From c842f02dee81e52f3b63a8b46021a8e18f143a7e Mon Sep 17 00:00:00 2001 From: cad97 Date: Sun, 15 Dec 2019 17:59:09 -0500 Subject: [PATCH 001/169] Use pointer offset instead of deref for A/Rc::into_raw --- src/liballoc/rc.rs | 9 +++++++-- src/liballoc/sync.rs | 9 +++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 1ff1c3c834f4e..0205c40829930 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -571,9 +571,14 @@ impl Rc { /// ``` #[stable(feature = "rc_raw", since = "1.17.0")] pub fn into_raw(this: Self) -> *const T { - let ptr: *const T = &*this; + let ptr: *mut RcBox = NonNull::as_ptr(this.ptr); + let fake_ptr = ptr as *mut T; mem::forget(this); - ptr + + unsafe { + let offset = data_offset(&(*ptr).value); + set_data_ptr(fake_ptr, (ptr as *mut u8).offset(offset)) + } } /// Constructs an `Rc` from a raw pointer. diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index 19b0086fa333c..de56cb300d38c 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -551,9 +551,14 @@ impl Arc { /// ``` #[stable(feature = "rc_raw", since = "1.17.0")] pub fn into_raw(this: Self) -> *const T { - let ptr: *const T = &*this; + let ptr: *mut ArcInner = NonNull::as_ptr(this.ptr); + let fake_ptr = ptr as *mut T; mem::forget(this); - ptr + + unsafe { + let offset = data_offset(&(*ptr).data); + set_data_ptr(fake_ptr, (ptr as *mut u8).offset(offset)) + } } /// Constructs an `Arc` from a raw pointer. From eb77f7ec6e9460c1ca70fbb7bb655f1a0a1bacfc Mon Sep 17 00:00:00 2001 From: CAD97 Date: Tue, 17 Dec 2019 15:52:13 -0500 Subject: [PATCH 002/169] Add internal safety docs to (A)Rc::into_raw --- src/liballoc/rc.rs | 5 +++++ src/liballoc/sync.rs | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 0205c40829930..8c70b0a913a98 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -575,6 +575,11 @@ impl Rc { let fake_ptr = ptr as *mut T; mem::forget(this); + // SAFETY: This cannot go through Deref::deref. + // Instead, we manually offset the pointer rather than manifesting a reference. + // This is so that the returned pointer retains the same provenance as our pointer. + // This is required so that e.g. `get_mut` can write through the pointer + // after the Rc is recovered through `from_raw`. unsafe { let offset = data_offset(&(*ptr).value); set_data_ptr(fake_ptr, (ptr as *mut u8).offset(offset)) diff --git a/src/liballoc/sync.rs b/src/liballoc/sync.rs index de56cb300d38c..5c1fa17a626d1 100644 --- a/src/liballoc/sync.rs +++ b/src/liballoc/sync.rs @@ -555,6 +555,11 @@ impl Arc { let fake_ptr = ptr as *mut T; mem::forget(this); + // SAFETY: This cannot go through Deref::deref. + // Instead, we manually offset the pointer rather than manifesting a reference. + // This is so that the returned pointer retains the same provenance as our pointer. + // This is required so that e.g. `get_mut` can write through the pointer + // after the Arc is recovered through `from_raw`. unsafe { let offset = data_offset(&(*ptr).data); set_data_ptr(fake_ptr, (ptr as *mut u8).offset(offset)) From 4843f227885bf23a34cc8485173c11601b00d977 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Mon, 30 Dec 2019 13:30:34 +0000 Subject: [PATCH 003/169] Handle recursive instantiation of drop shims --- src/librustc_mir/monomorphize/collector.rs | 4 ++-- src/test/ui/issues/issue-38591.rs | 10 ---------- .../issue-26548-recursion-via-normalize.rs} | 0 .../issue-26548-recursion-via-normalize.stderr} | 2 +- .../issue-38591-non-regular-dropck-recursion.rs | 17 +++++++++++++++++ ...ue-38591-non-regular-dropck-recursion.stderr | 4 ++++ 6 files changed, 24 insertions(+), 13 deletions(-) delete mode 100644 src/test/ui/issues/issue-38591.rs rename src/test/ui/{issues/issue-26548.rs => recursion/issue-26548-recursion-via-normalize.rs} (100%) rename src/test/ui/{issues/issue-26548.stderr => recursion/issue-26548-recursion-via-normalize.stderr} (88%) create mode 100644 src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.rs create mode 100644 src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 0a783337ad150..dfc3c4cd76947 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -423,7 +423,7 @@ fn check_recursion_limit<'tcx>( let recursion_depth = recursion_depths.get(&def_id).cloned().unwrap_or(0); debug!(" => recursion depth={}", recursion_depth); - let recursion_depth = if Some(def_id) == tcx.lang_items().drop_in_place_fn() { + let adjusted_recursion_depth = if Some(def_id) == tcx.lang_items().drop_in_place_fn() { // HACK: drop_in_place creates tight monomorphization loops. Give // it more margin. recursion_depth / 4 @@ -434,7 +434,7 @@ fn check_recursion_limit<'tcx>( // Code that needs to instantiate the same function recursively // more than the recursion limit is assumed to be causing an // infinite expansion. - if recursion_depth > *tcx.sess.recursion_limit.get() { + if adjusted_recursion_depth > *tcx.sess.recursion_limit.get() { let error = format!("reached the recursion limit while instantiating `{}`", instance); if let Some(hir_id) = tcx.hir().as_local_hir_id(def_id) { tcx.sess.span_fatal(tcx.hir().span(hir_id), &error); diff --git a/src/test/ui/issues/issue-38591.rs b/src/test/ui/issues/issue-38591.rs deleted file mode 100644 index 2f594b48e697f..0000000000000 --- a/src/test/ui/issues/issue-38591.rs +++ /dev/null @@ -1,10 +0,0 @@ -// check-pass - -struct S { - t : T, - s : Box> -} - -fn f(x : S) {} - -fn main () {} diff --git a/src/test/ui/issues/issue-26548.rs b/src/test/ui/recursion/issue-26548-recursion-via-normalize.rs similarity index 100% rename from src/test/ui/issues/issue-26548.rs rename to src/test/ui/recursion/issue-26548-recursion-via-normalize.rs diff --git a/src/test/ui/issues/issue-26548.stderr b/src/test/ui/recursion/issue-26548-recursion-via-normalize.stderr similarity index 88% rename from src/test/ui/issues/issue-26548.stderr rename to src/test/ui/recursion/issue-26548-recursion-via-normalize.stderr index 3c213674e4b70..6a83f91ce5b32 100644 --- a/src/test/ui/issues/issue-26548.stderr +++ b/src/test/ui/recursion/issue-26548-recursion-via-normalize.stderr @@ -3,7 +3,7 @@ error[E0391]: cycle detected when computing layout of `std::option::Option` = note: ...which requires computing layout of `S`... = note: ...which again requires computing layout of `std::option::Option`, completing the cycle note: cycle used when processing `main` - --> $DIR/issue-26548.rs:11:1 + --> $DIR/issue-26548-recursion-via-normalize.rs:11:1 | LL | fn main() { | ^^^^^^^^^ diff --git a/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.rs b/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.rs new file mode 100644 index 0000000000000..0fcf77d8722d6 --- /dev/null +++ b/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.rs @@ -0,0 +1,17 @@ +// Dropck shouldn't hit a recursion limit from checking `S` since it has +// no free regions or type parameters. +// Codegen however, has to error for the infinitely many `real_drop_in_place` +// functions it has been asked to create. +// build-fail + +struct S { + t: T, + s: Box>, +} + +fn f(x: S) {} + +fn main() { + // Force instantiation. + f as fn(_); +} diff --git a/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr b/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr new file mode 100644 index 0000000000000..77309a82a0fa7 --- /dev/null +++ b/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr @@ -0,0 +1,4 @@ +error: reached the recursion limit while instantiating `std::ptr::real_drop_in_place::> - shim(Some(S))` + +error: aborting due to previous error + From 8314b7fd27350681ecbe5d55f840ddc5873d222f Mon Sep 17 00:00:00 2001 From: Stein Somers Date: Tue, 31 Dec 2019 14:09:06 +0100 Subject: [PATCH 004/169] More thorough testing of BTreeMap::range --- src/liballoc/tests/btree/map.rs | 181 ++++++++++++++++++++++++++------ 1 file changed, 150 insertions(+), 31 deletions(-) diff --git a/src/liballoc/tests/btree/map.rs b/src/liballoc/tests/btree/map.rs index 35ce1354f52e0..f5be72c39b20c 100644 --- a/src/liballoc/tests/btree/map.rs +++ b/src/liballoc/tests/btree/map.rs @@ -4,6 +4,7 @@ use std::convert::TryFrom; use std::fmt::Debug; use std::iter::FromIterator; use std::ops::Bound::{self, Excluded, Included, Unbounded}; +use std::ops::RangeBounds; use std::rc::Rc; use super::DeterministicRng; @@ -68,6 +69,11 @@ fn test_basic_small() { assert_eq!(map.last_key_value(), None); assert_eq!(map.keys().count(), 0); assert_eq!(map.values().count(), 0); + assert_eq!(map.range(..).next(), None); + assert_eq!(map.range(..1).next(), None); + assert_eq!(map.range(1..).next(), None); + assert_eq!(map.range(1..=1).next(), None); + assert_eq!(map.range(1..2).next(), None); assert_eq!(map.insert(1, 1), None); // 1 key-value pair: @@ -118,6 +124,11 @@ fn test_basic_small() { assert_eq!(map.last_key_value(), None); assert_eq!(map.keys().count(), 0); assert_eq!(map.values().count(), 0); + assert_eq!(map.range(..).next(), None); + assert_eq!(map.range(..1).next(), None); + assert_eq!(map.range(1..).next(), None); + assert_eq!(map.range(1..=1).next(), None); + assert_eq!(map.range(1..2).next(), None); assert_eq!(map.remove(&1), None); } @@ -128,7 +139,6 @@ fn test_iter() { #[cfg(miri)] let size = 200; - // Forwards let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect(); fn test(size: usize, mut iter: T) @@ -154,7 +164,6 @@ fn test_iter_rev() { #[cfg(miri)] let size = 200; - // Forwards let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect(); fn test(size: usize, mut iter: T) @@ -275,7 +284,6 @@ fn test_iter_mixed() { #[cfg(miri)] let size = 200; - // Forwards let mut map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect(); fn test(size: usize, mut iter: T) @@ -299,27 +307,147 @@ fn test_iter_mixed() { test(size, map.into_iter()); } -#[test] -fn test_range_small() { - let size = 5; - - // Forwards - let map: BTreeMap<_, _> = (0..size).map(|i| (i, i)).collect(); - - let mut j = 0; - for ((&k, &v), i) in map.range(2..).zip(2..size) { - assert_eq!(k, i); - assert_eq!(v, i); - j += 1; - } - assert_eq!(j, size - 2); +fn range_keys(map: &BTreeMap, range: impl RangeBounds) -> Vec { + map.range(range) + .map(|(&k, &v)| { + assert_eq!(k, v); + k + }) + .collect() } #[test] -fn test_range_inclusive() { - let size = 500; +fn test_range_small() { + let size = 4; + + let map: BTreeMap<_, _> = (1..=size).map(|i| (i, i)).collect(); + let all: Vec<_> = (1..=size).collect(); + let (first, last) = (vec![all[0]], vec![all[size as usize - 1]]); + + assert_eq!(range_keys(&map, (Excluded(0), Excluded(size + 1))), all); + assert_eq!(range_keys(&map, (Excluded(0), Included(size + 1))), all); + assert_eq!(range_keys(&map, (Excluded(0), Included(size))), all); + assert_eq!(range_keys(&map, (Excluded(0), Unbounded)), all); + assert_eq!(range_keys(&map, (Included(0), Excluded(size + 1))), all); + assert_eq!(range_keys(&map, (Included(0), Included(size + 1))), all); + assert_eq!(range_keys(&map, (Included(0), Included(size))), all); + assert_eq!(range_keys(&map, (Included(0), Unbounded)), all); + assert_eq!(range_keys(&map, (Included(1), Excluded(size + 1))), all); + assert_eq!(range_keys(&map, (Included(1), Included(size + 1))), all); + assert_eq!(range_keys(&map, (Included(1), Included(size))), all); + assert_eq!(range_keys(&map, (Included(1), Unbounded)), all); + assert_eq!(range_keys(&map, (Unbounded, Excluded(size + 1))), all); + assert_eq!(range_keys(&map, (Unbounded, Included(size + 1))), all); + assert_eq!(range_keys(&map, (Unbounded, Included(size))), all); + assert_eq!(range_keys(&map, ..), all); + + assert_eq!(range_keys(&map, (Excluded(0), Excluded(1))), vec![]); + assert_eq!(range_keys(&map, (Excluded(0), Included(0))), vec![]); + assert_eq!(range_keys(&map, (Included(0), Included(0))), vec![]); + assert_eq!(range_keys(&map, (Included(0), Excluded(1))), vec![]); + assert_eq!(range_keys(&map, (Unbounded, Excluded(1))), vec![]); + assert_eq!(range_keys(&map, (Unbounded, Included(0))), vec![]); + assert_eq!(range_keys(&map, (Excluded(0), Excluded(2))), first); + assert_eq!(range_keys(&map, (Excluded(0), Included(1))), first); + assert_eq!(range_keys(&map, (Included(0), Excluded(2))), first); + assert_eq!(range_keys(&map, (Included(0), Included(1))), first); + assert_eq!(range_keys(&map, (Included(1), Excluded(2))), first); + assert_eq!(range_keys(&map, (Included(1), Included(1))), first); + assert_eq!(range_keys(&map, (Unbounded, Excluded(2))), first); + assert_eq!(range_keys(&map, (Unbounded, Included(1))), first); + assert_eq!(range_keys(&map, (Excluded(size - 1), Excluded(size + 1))), last); + assert_eq!(range_keys(&map, (Excluded(size - 1), Included(size + 1))), last); + assert_eq!(range_keys(&map, (Excluded(size - 1), Included(size))), last); + assert_eq!(range_keys(&map, (Excluded(size - 1), Unbounded)), last); + assert_eq!(range_keys(&map, (Included(size), Excluded(size + 1))), last); + assert_eq!(range_keys(&map, (Included(size), Included(size + 1))), last); + assert_eq!(range_keys(&map, (Included(size), Included(size))), last); + assert_eq!(range_keys(&map, (Included(size), Unbounded)), last); + assert_eq!(range_keys(&map, (Excluded(size), Excluded(size + 1))), vec![]); + assert_eq!(range_keys(&map, (Excluded(size), Included(size))), vec![]); + assert_eq!(range_keys(&map, (Excluded(size), Unbounded)), vec![]); + assert_eq!(range_keys(&map, (Included(size + 1), Excluded(size + 1))), vec![]); + assert_eq!(range_keys(&map, (Included(size + 1), Included(size + 1))), vec![]); + assert_eq!(range_keys(&map, (Included(size + 1), Unbounded)), vec![]); + + assert_eq!(range_keys(&map, ..3), vec![1, 2]); + assert_eq!(range_keys(&map, 3..), vec![3, 4]); + assert_eq!(range_keys(&map, 2..=3), vec![2, 3]); +} + +#[test] +fn test_range_depth_2() { + // Assuming that node.CAPACITY is 11, having 12 pairs implies a depth 2 tree + // with 2 leaves. Depending on details we don't want or need to rely upon, + // the single key at the root will be 6 or 7. + + let map: BTreeMap<_, _> = (1..=12).map(|i| (i, i)).collect(); + for &root in &[6, 7] { + assert_eq!(range_keys(&map, (Excluded(root), Excluded(root + 1))), vec![]); + assert_eq!(range_keys(&map, (Excluded(root), Included(root + 1))), vec![root + 1]); + assert_eq!(range_keys(&map, (Included(root), Excluded(root + 1))), vec![root]); + assert_eq!(range_keys(&map, (Included(root), Included(root + 1))), vec![root, root + 1]); + + assert_eq!(range_keys(&map, (Excluded(root - 1), Excluded(root))), vec![]); + assert_eq!(range_keys(&map, (Included(root - 1), Excluded(root))), vec![root - 1]); + assert_eq!(range_keys(&map, (Excluded(root - 1), Included(root))), vec![root]); + assert_eq!(range_keys(&map, (Included(root - 1), Included(root))), vec![root - 1, root]); + } +} + +#[test] +fn test_range_large() { + let size = 200; - let map: BTreeMap<_, _> = (0..=size).map(|i| (i, i)).collect(); + let map: BTreeMap<_, _> = (1..=size).map(|i| (i, i)).collect(); + let all: Vec<_> = (1..=size).collect(); + let (first, last) = (vec![all[0]], vec![all[size as usize - 1]]); + + assert_eq!(range_keys(&map, (Excluded(0), Excluded(size + 1))), all); + assert_eq!(range_keys(&map, (Excluded(0), Included(size + 1))), all); + assert_eq!(range_keys(&map, (Excluded(0), Included(size))), all); + assert_eq!(range_keys(&map, (Excluded(0), Unbounded)), all); + assert_eq!(range_keys(&map, (Included(0), Excluded(size + 1))), all); + assert_eq!(range_keys(&map, (Included(0), Included(size + 1))), all); + assert_eq!(range_keys(&map, (Included(0), Included(size))), all); + assert_eq!(range_keys(&map, (Included(0), Unbounded)), all); + assert_eq!(range_keys(&map, (Included(1), Excluded(size + 1))), all); + assert_eq!(range_keys(&map, (Included(1), Included(size + 1))), all); + assert_eq!(range_keys(&map, (Included(1), Included(size))), all); + assert_eq!(range_keys(&map, (Included(1), Unbounded)), all); + assert_eq!(range_keys(&map, (Unbounded, Excluded(size + 1))), all); + assert_eq!(range_keys(&map, (Unbounded, Included(size + 1))), all); + assert_eq!(range_keys(&map, (Unbounded, Included(size))), all); + assert_eq!(range_keys(&map, ..), all); + + assert_eq!(range_keys(&map, (Excluded(0), Excluded(1))), vec![]); + assert_eq!(range_keys(&map, (Excluded(0), Included(0))), vec![]); + assert_eq!(range_keys(&map, (Included(0), Included(0))), vec![]); + assert_eq!(range_keys(&map, (Included(0), Excluded(1))), vec![]); + assert_eq!(range_keys(&map, (Unbounded, Excluded(1))), vec![]); + assert_eq!(range_keys(&map, (Unbounded, Included(0))), vec![]); + assert_eq!(range_keys(&map, (Excluded(0), Excluded(2))), first); + assert_eq!(range_keys(&map, (Excluded(0), Included(1))), first); + assert_eq!(range_keys(&map, (Included(0), Excluded(2))), first); + assert_eq!(range_keys(&map, (Included(0), Included(1))), first); + assert_eq!(range_keys(&map, (Included(1), Excluded(2))), first); + assert_eq!(range_keys(&map, (Included(1), Included(1))), first); + assert_eq!(range_keys(&map, (Unbounded, Excluded(2))), first); + assert_eq!(range_keys(&map, (Unbounded, Included(1))), first); + assert_eq!(range_keys(&map, (Excluded(size - 1), Excluded(size + 1))), last); + assert_eq!(range_keys(&map, (Excluded(size - 1), Included(size + 1))), last); + assert_eq!(range_keys(&map, (Excluded(size - 1), Included(size))), last); + assert_eq!(range_keys(&map, (Excluded(size - 1), Unbounded)), last); + assert_eq!(range_keys(&map, (Included(size), Excluded(size + 1))), last); + assert_eq!(range_keys(&map, (Included(size), Included(size + 1))), last); + assert_eq!(range_keys(&map, (Included(size), Included(size))), last); + assert_eq!(range_keys(&map, (Included(size), Unbounded)), last); + assert_eq!(range_keys(&map, (Excluded(size), Excluded(size + 1))), vec![]); + assert_eq!(range_keys(&map, (Excluded(size), Included(size))), vec![]); + assert_eq!(range_keys(&map, (Excluded(size), Unbounded)), vec![]); + assert_eq!(range_keys(&map, (Included(size + 1), Excluded(size + 1))), vec![]); + assert_eq!(range_keys(&map, (Included(size + 1), Included(size + 1))), vec![]); + assert_eq!(range_keys(&map, (Included(size + 1), Unbounded)), vec![]); fn check<'a, L, R>(lhs: L, rhs: R) where @@ -331,18 +459,9 @@ fn test_range_inclusive() { assert_eq!(lhs, rhs); } - check(map.range(size + 1..=size + 1), vec![]); - check(map.range(size..=size), vec![(&size, &size)]); - check(map.range(size..=size + 1), vec![(&size, &size)]); - check(map.range(0..=0), vec![(&0, &0)]); - check(map.range(0..=size - 1), map.range(..size)); - check(map.range(-1..=-1), vec![]); - check(map.range(-1..=size), map.range(..)); - check(map.range(..=size), map.range(..)); - check(map.range(..=200), map.range(..201)); + check(map.range(..=100), map.range(..101)); check(map.range(5..=8), vec![(&5, &5), (&6, &6), (&7, &7), (&8, &8)]); - check(map.range(-1..=0), vec![(&0, &0)]); - check(map.range(-1..=2), vec![(&0, &0), (&1, &1), (&2, &2)]); + check(map.range(-1..=2), vec![(&1, &1), (&2, &2)]); } #[test] From 73996df6291001f0742b6409249329301aa77a23 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Wed, 1 Jan 2020 14:43:24 -0500 Subject: [PATCH 005/169] Reset Formatter flags on exit from pad_integral This fixes a bug where after calling pad_integral with appropriate flags, the fill and alignment flags would be set to '0' and 'Right' and left as such even after exiting pad_integral, which meant that future calls on the same Formatter would get incorrect flags reported. This is quite difficult to observe in practice, as almost all formatting implementations in practice don't call `Display::fmt` directly, but rather use `write!` or a similar macro, which means that they cannot observe the effects of the wrong flags (as `write!` creates a fresh Formatter instance). However, we include a test case. --- src/libcore/fmt/mod.rs | 9 ++++++--- src/libcore/tests/fmt/mod.rs | 15 +++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index 6c8d1626b09b6..e68f3c58a3e07 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -1244,12 +1244,15 @@ impl<'a> Formatter<'a> { // The sign and prefix goes before the padding if the fill character // is zero Some(min) if self.sign_aware_zero_pad() => { - self.fill = '0'; - self.align = rt::v1::Alignment::Right; + let old_fill = crate::mem::replace(&mut self.fill, '0'); + let old_align = crate::mem::replace(&mut self.align, rt::v1::Alignment::Right); write_prefix(self, sign, prefix)?; let post_padding = self.padding(min - width, rt::v1::Alignment::Right)?; self.buf.write_str(buf)?; - post_padding.write(self.buf) + post_padding.write(self.buf)?; + self.fill = old_fill; + self.align = old_align; + Ok(()) } // Otherwise, the sign and prefix goes after the padding Some(min) => { diff --git a/src/libcore/tests/fmt/mod.rs b/src/libcore/tests/fmt/mod.rs index d86e21cf40b6e..7b281ce48e6aa 100644 --- a/src/libcore/tests/fmt/mod.rs +++ b/src/libcore/tests/fmt/mod.rs @@ -28,3 +28,18 @@ fn test_estimated_capacity() { assert_eq!(format_args!("{}, hello!", "World").estimated_capacity(), 0); assert_eq!(format_args!("{}. 16-bytes piece", "World").estimated_capacity(), 32); } + +#[test] +fn pad_integral_resets() { + struct Bar; + + impl core::fmt::Display for Bar { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + "1".fmt(f)?; + f.pad_integral(true, "", "5")?; + "1".fmt(f) + } + } + + assert_eq!(format!("{:<03}", Bar), "1 0051 "); +} From 3ab95ceb12b60c1564d037e8d8d6e2406fad44b3 Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 7 Jan 2020 00:00:16 +0000 Subject: [PATCH 006/169] Detail transitive containment in E0588 diagnostic --- src/librustc_typeck/check/mod.rs | 87 ++++++++++---- .../ui/repr/repr-packed-contains-align.rs | 16 +-- .../ui/repr/repr-packed-contains-align.stderr | 112 ++++++++++++++++-- 3 files changed, 174 insertions(+), 41 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index eacd94f7da7f7..6b9b28a0fa622 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -118,7 +118,7 @@ use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LOCAL_CRATE}; use rustc_hir::itemlikevisit::ItemLikeVisitor; -use rustc_hir::{ExprKind, GenericArg, HirIdMap, ItemKind, Node, PatKind, QPath}; +use rustc_hir::{ExprKind, GenericArg, HirIdMap, Item, ItemKind, Node, PatKind, QPath}; use rustc_index::vec::Idx; use rustc_span::hygiene::DesugaringKind; use rustc_span::source_map::{original_sp, DUMMY_SP}; @@ -2295,44 +2295,81 @@ fn check_packed(tcx: TyCtxt<'_>, sp: Span, def_id: DefId) { "type has conflicting packed and align representation hints" ) .emit(); - } else if check_packed_inner(tcx, def_id, &mut Vec::new()) { - struct_span_err!( - tcx.sess, - sp, - E0588, - "packed type cannot transitively contain a `[repr(align)]` type" - ) - .emit(); + } else { + if let Some(def_spans) = check_packed_inner(tcx, def_id, &mut vec![]) { + let mut err = struct_span_err!( + tcx.sess, + sp, + E0588, + "packed type cannot transitively contain a `#[repr(align)]` type" + ); + + let hir = tcx.hir(); + if let Some(hir_id) = hir.as_local_hir_id(def_spans[0].0) { + if let Node::Item(Item { ident, .. }) = hir.get(hir_id) { + err.span_note( + tcx.def_span(def_spans[0].0), + &format!("`{}` has a `#[repr(align)]` attribute", ident), + ); + } + } + + if def_spans.len() > 2 { + let mut first = true; + for (adt_def, span) in def_spans.iter().skip(1).rev() { + if let Some(hir_id) = hir.as_local_hir_id(*adt_def) { + if let Node::Item(Item { ident, .. }) = hir.get(hir_id) { + err.span_note( + *span, + &if first { + format!( + "`{}` contains a field of type `{}`", + tcx.type_of(def_id), + ident + ) + } else { + format!("...which contains a field of type `{}`", ident) + }, + ); + first = false; + } + } + } + } + + err.emit(); + } } } } -fn check_packed_inner(tcx: TyCtxt<'_>, def_id: DefId, stack: &mut Vec) -> bool { - let t = tcx.type_of(def_id); - if stack.contains(&def_id) { - debug!("check_packed_inner: {:?} is recursive", t); - return false; - } - if let ty::Adt(def, substs) = t.kind { +fn check_packed_inner( + tcx: TyCtxt<'_>, + def_id: DefId, + stack: &mut Vec, +) -> Option> { + if let ty::Adt(def, substs) = tcx.type_of(def_id).kind { if def.is_struct() || def.is_union() { - if tcx.adt_def(def.did).repr.align.is_some() { - return true; + if def.repr.align.is_some() { + return Some(vec![(def.did, DUMMY_SP)]); } - // push struct def_id before checking fields + stack.push(def_id); for field in &def.non_enum_variant().fields { - let f = field.ty(tcx, substs); - if let ty::Adt(def, _) = f.kind { - if check_packed_inner(tcx, def.did, stack) { - return true; + if let ty::Adt(def, _) = field.ty(tcx, substs).kind { + if !stack.contains(&def.did) { + if let Some(mut defs) = check_packed_inner(tcx, def.did, stack) { + defs.push((def.did, field.ident.span)); + return Some(defs); + } } } } - // only need to pop if not early out stack.pop(); } } - false + + None } /// Emit an error when encountering more or less than one variant in a transparent enum. diff --git a/src/test/ui/repr/repr-packed-contains-align.rs b/src/test/ui/repr/repr-packed-contains-align.rs index a3610345173a7..67d87eb5cd520 100644 --- a/src/test/ui/repr/repr-packed-contains-align.rs +++ b/src/test/ui/repr/repr-packed-contains-align.rs @@ -16,34 +16,34 @@ union UB { } #[repr(packed)] -struct SC(SA); //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type +struct SC(SA); //~ ERROR: packed type cannot transitively contain a `#[repr(align)]` type #[repr(packed)] -struct SD(SB); //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type +struct SD(SB); //~ ERROR: packed type cannot transitively contain a `#[repr(align)]` type #[repr(packed)] -struct SE(UA); //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type +struct SE(UA); //~ ERROR: packed type cannot transitively contain a `#[repr(align)]` type #[repr(packed)] -struct SF(UB); //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type +struct SF(UB); //~ ERROR: packed type cannot transitively contain a `#[repr(align)]` type #[repr(packed)] -union UC { //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type +union UC { //~ ERROR: packed type cannot transitively contain a `#[repr(align)]` type a: UA } #[repr(packed)] -union UD { //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type +union UD { //~ ERROR: packed type cannot transitively contain a `#[repr(align)]` type n: UB } #[repr(packed)] -union UE { //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type +union UE { //~ ERROR: packed type cannot transitively contain a `#[repr(align)]` type a: SA } #[repr(packed)] -union UF { //~ ERROR: packed type cannot transitively contain a `[repr(align)]` type +union UF { //~ ERROR: packed type cannot transitively contain a `#[repr(align)]` type n: SB } diff --git a/src/test/ui/repr/repr-packed-contains-align.stderr b/src/test/ui/repr/repr-packed-contains-align.stderr index df001d6b5f2a4..32f9bb8bf33d9 100644 --- a/src/test/ui/repr/repr-packed-contains-align.stderr +++ b/src/test/ui/repr/repr-packed-contains-align.stderr @@ -1,58 +1,154 @@ -error[E0588]: packed type cannot transitively contain a `[repr(align)]` type +error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type --> $DIR/repr-packed-contains-align.rs:19:1 | LL | struct SC(SA); | ^^^^^^^^^^^^^^ + | +note: `SA` has a `#[repr(align)]` attribute + --> $DIR/repr-packed-contains-align.rs:5:1 + | +LL | struct SA(i32); + | ^^^^^^^^^^^^^^^ -error[E0588]: packed type cannot transitively contain a `[repr(align)]` type +error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type --> $DIR/repr-packed-contains-align.rs:22:1 | LL | struct SD(SB); | ^^^^^^^^^^^^^^ + | +note: `SA` has a `#[repr(align)]` attribute + --> $DIR/repr-packed-contains-align.rs:5:1 + | +LL | struct SA(i32); + | ^^^^^^^^^^^^^^^ +note: `SD` contains a field of type `SB` + --> $DIR/repr-packed-contains-align.rs:22:11 + | +LL | struct SD(SB); + | ^^ +note: ...which contains a field of type `SA` + --> $DIR/repr-packed-contains-align.rs:7:11 + | +LL | struct SB(SA); + | ^^ -error[E0588]: packed type cannot transitively contain a `[repr(align)]` type +error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type --> $DIR/repr-packed-contains-align.rs:25:1 | LL | struct SE(UA); | ^^^^^^^^^^^^^^ + | +note: `UA` has a `#[repr(align)]` attribute + --> $DIR/repr-packed-contains-align.rs:10:1 + | +LL | / union UA { +LL | | i: i32 +LL | | } + | |_^ -error[E0588]: packed type cannot transitively contain a `[repr(align)]` type +error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type --> $DIR/repr-packed-contains-align.rs:28:1 | LL | struct SF(UB); | ^^^^^^^^^^^^^^ + | +note: `UA` has a `#[repr(align)]` attribute + --> $DIR/repr-packed-contains-align.rs:10:1 + | +LL | / union UA { +LL | | i: i32 +LL | | } + | |_^ +note: `SF` contains a field of type `UB` + --> $DIR/repr-packed-contains-align.rs:28:11 + | +LL | struct SF(UB); + | ^^ +note: ...which contains a field of type `UA` + --> $DIR/repr-packed-contains-align.rs:15:5 + | +LL | a: UA + | ^ -error[E0588]: packed type cannot transitively contain a `[repr(align)]` type +error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type --> $DIR/repr-packed-contains-align.rs:31:1 | LL | / union UC { LL | | a: UA +LL | | } + | |_^ + | +note: `UA` has a `#[repr(align)]` attribute + --> $DIR/repr-packed-contains-align.rs:10:1 + | +LL | / union UA { +LL | | i: i32 LL | | } | |_^ -error[E0588]: packed type cannot transitively contain a `[repr(align)]` type +error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type --> $DIR/repr-packed-contains-align.rs:36:1 | LL | / union UD { LL | | n: UB LL | | } | |_^ + | +note: `UA` has a `#[repr(align)]` attribute + --> $DIR/repr-packed-contains-align.rs:10:1 + | +LL | / union UA { +LL | | i: i32 +LL | | } + | |_^ +note: `UD` contains a field of type `UB` + --> $DIR/repr-packed-contains-align.rs:37:5 + | +LL | n: UB + | ^ +note: ...which contains a field of type `UA` + --> $DIR/repr-packed-contains-align.rs:15:5 + | +LL | a: UA + | ^ -error[E0588]: packed type cannot transitively contain a `[repr(align)]` type +error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type --> $DIR/repr-packed-contains-align.rs:41:1 | LL | / union UE { LL | | a: SA LL | | } | |_^ + | +note: `SA` has a `#[repr(align)]` attribute + --> $DIR/repr-packed-contains-align.rs:5:1 + | +LL | struct SA(i32); + | ^^^^^^^^^^^^^^^ -error[E0588]: packed type cannot transitively contain a `[repr(align)]` type +error[E0588]: packed type cannot transitively contain a `#[repr(align)]` type --> $DIR/repr-packed-contains-align.rs:46:1 | LL | / union UF { LL | | n: SB LL | | } | |_^ + | +note: `SA` has a `#[repr(align)]` attribute + --> $DIR/repr-packed-contains-align.rs:5:1 + | +LL | struct SA(i32); + | ^^^^^^^^^^^^^^^ +note: `UF` contains a field of type `SB` + --> $DIR/repr-packed-contains-align.rs:47:5 + | +LL | n: SB + | ^ +note: ...which contains a field of type `SA` + --> $DIR/repr-packed-contains-align.rs:7:11 + | +LL | struct SB(SA); + | ^^ error: aborting due to 8 previous errors From 0d2f9825b5687470accfc2e25a73a0cd02c37e01 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 8 Jan 2020 13:57:01 -0800 Subject: [PATCH 007/169] Rebase LLVM onto 9.0.1 --- .gitmodules | 2 +- src/llvm-project | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index 31db0772cfb6b..62cbbdd9a3a06 100644 --- a/.gitmodules +++ b/.gitmodules @@ -40,7 +40,7 @@ [submodule "src/llvm-project"] path = src/llvm-project url = https://github.com/rust-lang/llvm-project.git - branch = rustc/9.0-2019-09-19 + branch = rustc/9.0-2019-12-19 [submodule "src/doc/embedded-book"] path = src/doc/embedded-book url = https://github.com/rust-embedded/book.git diff --git a/src/llvm-project b/src/llvm-project index 9330ec5a4c1df..cd87134ab77e6 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit 9330ec5a4c1df5fc1fa62f993ed6a04da68cb040 +Subproject commit cd87134ab77e6bacb2128137065b328b9c35e0e5 From 084217af65b212c3c68f66d798faa19bcef5007a Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Wed, 8 Jan 2020 22:56:33 +0000 Subject: [PATCH 008/169] Don't use f64 shims for f32 cmath functions on none 32-bit x86 MSVC These shims are only needed on 32-bit x86. Additionally since https://reviews.llvm.org/rL268875 LLVM handles adding the shims itself for the intrinsics. --- src/libstd/f32.rs | 60 +++++---------------------------- src/libstd/sys/windows/cmath.rs | 10 +++--- 2 files changed, 13 insertions(+), 57 deletions(-) diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs index 267d7013b1e42..acca4af85be01 100644 --- a/src/libstd/f32.rs +++ b/src/libstd/f32.rs @@ -44,23 +44,7 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn floor(self) -> f32 { - // On MSVC LLVM will lower many math intrinsics to a call to the - // corresponding function. On MSVC, however, many of these functions - // aren't actually available as symbols to call, but rather they are all - // `static inline` functions in header files. This means that from a C - // perspective it's "compatible", but not so much from an ABI - // perspective (which we're worried about). - // - // The inline header functions always just cast to a f64 and do their - // operation, so we do that here as well, but only for MSVC targets. - // - // Note that there are many MSVC-specific float operations which - // redirect to this comment, so `floorf` is just one case of a missing - // function on MSVC, but there are many others elsewhere. - #[cfg(target_env = "msvc")] - return (self as f64).floor() as f32; - #[cfg(not(target_env = "msvc"))] - return unsafe { intrinsics::floorf32(self) }; + unsafe { intrinsics::floorf32(self) } } /// Returns the smallest integer greater than or equal to a number. @@ -78,11 +62,7 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn ceil(self) -> f32 { - // see notes above in `floor` - #[cfg(target_env = "msvc")] - return (self as f64).ceil() as f32; - #[cfg(not(target_env = "msvc"))] - return unsafe { intrinsics::ceilf32(self) }; + unsafe { intrinsics::ceilf32(self) } } /// Returns the nearest integer to a number. Round half-way cases away from @@ -348,11 +328,7 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn powf(self, n: f32) -> f32 { - // see notes above in `floor` - #[cfg(target_env = "msvc")] - return (self as f64).powf(n as f64) as f32; - #[cfg(not(target_env = "msvc"))] - return unsafe { intrinsics::powf32(self, n) }; + unsafe { intrinsics::powf32(self, n) } } /// Takes the square root of a number. @@ -399,11 +375,7 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn exp(self) -> f32 { - // see notes above in `floor` - #[cfg(target_env = "msvc")] - return (self as f64).exp() as f32; - #[cfg(not(target_env = "msvc"))] - return unsafe { intrinsics::expf32(self) }; + unsafe { intrinsics::expf32(self) } } /// Returns `2^(self)`. @@ -447,11 +419,7 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn ln(self) -> f32 { - // see notes above in `floor` - #[cfg(target_env = "msvc")] - return (self as f64).ln() as f32; - #[cfg(not(target_env = "msvc"))] - return unsafe { intrinsics::logf32(self) }; + unsafe { intrinsics::logf32(self) } } /// Returns the logarithm of the number with respect to an arbitrary base. @@ -521,11 +489,7 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn log10(self) -> f32 { - // see notes above in `floor` - #[cfg(target_env = "msvc")] - return (self as f64).log10() as f32; - #[cfg(not(target_env = "msvc"))] - return unsafe { intrinsics::log10f32(self) }; + unsafe { intrinsics::log10f32(self) } } /// The positive difference of two numbers. @@ -625,11 +589,7 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn sin(self) -> f32 { - // see notes in `core::f32::Float::floor` - #[cfg(target_env = "msvc")] - return (self as f64).sin() as f32; - #[cfg(not(target_env = "msvc"))] - return unsafe { intrinsics::sinf32(self) }; + unsafe { intrinsics::sinf32(self) } } /// Computes the cosine of a number (in radians). @@ -649,11 +609,7 @@ impl f32 { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn cos(self) -> f32 { - // see notes in `core::f32::Float::floor` - #[cfg(target_env = "msvc")] - return (self as f64).cos() as f32; - #[cfg(not(target_env = "msvc"))] - return unsafe { intrinsics::cosf32(self) }; + unsafe { intrinsics::cosf32(self) } } /// Computes the tangent of a number (in radians). diff --git a/src/libstd/sys/windows/cmath.rs b/src/libstd/sys/windows/cmath.rs index 6f5d40b494fbe..1a5421facd0c1 100644 --- a/src/libstd/sys/windows/cmath.rs +++ b/src/libstd/sys/windows/cmath.rs @@ -27,7 +27,7 @@ extern "C" { pub use self::shims::*; -#[cfg(not(target_env = "msvc"))] +#[cfg(not(all(target_env = "msvc", target_arch = "x86")))] mod shims { use libc::c_float; @@ -43,10 +43,10 @@ mod shims { } } -// On MSVC these functions aren't defined, so we just define shims which promote -// everything fo f64, perform the calculation, and then demote back to f32. -// While not precisely correct should be "correct enough" for now. -#[cfg(target_env = "msvc")] +// On 32-bit x86 MSVC these functions aren't defined, so we just define shims +// which promote everything fo f64, perform the calculation, and then demote +// back to f32. While not precisely correct should be "correct enough" for now. +#[cfg(all(target_env = "msvc", target_arch = "x86"))] mod shims { use libc::c_float; From 4840cd8117010e057109e0233f403e526d309d9f Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Thu, 9 Jan 2020 10:01:20 -0500 Subject: [PATCH 009/169] Don't discard marker trait impls when inference variables are present Fixes #61651 Previously, we would unconditionally discard impl candidates for marker traits during trait selection. However, if the predicate had inference variables, this could have the effect of constrainting inference variables (due to a successful trait selection) when we would have otherwise failed due to mutliple applicable impls, This commit prevents marker trait impls from being discarded while the obligation predicate has any inference variables, ensuring that discarding impls will never cause us to incorrectly constraint inference variables. --- src/librustc/traits/select.rs | 62 +++++++++++++++++-- .../traits/specialize/specialization_graph.rs | 2 +- src/librustc/ty/mod.rs | 13 ++-- .../issue-61651-type-mismatch.rs | 17 +++++ 4 files changed, 84 insertions(+), 10 deletions(-) create mode 100644 src/test/ui/marker_trait_attr/issue-61651-type-mismatch.rs diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 1b1cb1b36e09a..491496e2c62b3 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -1412,6 +1412,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { debug!("winnowed to {} candidates for {:?}: {:?}", candidates.len(), stack, candidates); + let needs_infer = stack.obligation.predicate.needs_infer(); + // If there are STILL multiple candidates, we can further // reduce the list by dropping duplicates -- including // resolving specializations. @@ -1419,7 +1421,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let mut i = 0; while i < candidates.len() { let is_dup = (0..candidates.len()).filter(|&j| i != j).any(|j| { - self.candidate_should_be_dropped_in_favor_of(&candidates[i], &candidates[j]) + self.candidate_should_be_dropped_in_favor_of( + &candidates[i], + &candidates[j], + needs_infer, + ) }); if is_dup { debug!("Dropping candidate #{}/{}: {:?}", i, candidates.len(), candidates[i]); @@ -2253,6 +2259,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &mut self, victim: &EvaluatedCandidate<'tcx>, other: &EvaluatedCandidate<'tcx>, + needs_infer: bool, ) -> bool { if victim.candidate == other.candidate { return true; @@ -2334,10 +2341,55 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { match victim.candidate { ImplCandidate(victim_def) => { let tcx = self.tcx(); - return tcx.specializes((other_def, victim_def)) - || tcx - .impls_are_allowed_to_overlap(other_def, victim_def) - .is_some(); + if tcx.specializes((other_def, victim_def)) { + return true; + } + return match tcx.impls_are_allowed_to_overlap(other_def, victim_def) { + Some(ty::ImplOverlapKind::Permitted { marker: true }) => { + // Subtle: If the predicate we are evaluating has inference + // variables, do *not* allow discarding candidates due to + // marker trait impls. + // + // Without this restriction, we could end up accidentally + // constrainting inference variables based on an arbitrarily + // chosen trait impl. + // + // Imagine we have the following code: + // + // ```rust + // #[marker] trait MyTrait {} + // impl MyTrait for u8 {} + // impl MyTrait for bool {} + // ``` + // + // And we are evaluating the predicate `<_#0t as MyTrait>`. + // + // During selection, we will end up with one candidate for each + // impl of `MyTrait`. If we were to discard one impl in favor + // of the other, we would be left with one candidate, causing + // us to "successfully" select the predicate, unifying + // _#0t with (for example) `u8`. + // + // However, we have no reason to believe that this unification + // is correct - we've essentially just picked an arbitrary + // *possibility* for _#0t, and required that this be the *only* + // possibility. + // + // Eventually, we will either: + // 1) Unify all inference variables in the predicate through + // some other means (e.g. type-checking of a function). We will + // then be in a position to drop marker trait candidates + // without constraining inference variables (since there are + // none left to constrin) + // 2) Be left with some unconstrained inference variables. We + // will then correctly report an inference error, since the + // existence of multiple marker trait impls tells us nothing + // about which one should actually apply. + !needs_infer + } + Some(_) => true, + None => false, + }; } ParamCandidate(ref cand) => { // Prefer the impl to a global where clause candidate. diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs index c176f139bf868..9509b6220eb0e 100644 --- a/src/librustc/traits/specialize/specialization_graph.rs +++ b/src/librustc/traits/specialize/specialization_graph.rs @@ -163,7 +163,7 @@ impl<'tcx> Children { tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling) { match overlap_kind { - ty::ImplOverlapKind::Permitted => {} + ty::ImplOverlapKind::Permitted { marker: _ } => {} ty::ImplOverlapKind::Issue33140 => { last_lint = Some(FutureCompatOverlapError { error: overlap_error(overlap), diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 747e6e8da99af..d27a29d31c0c3 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2662,7 +2662,12 @@ impl<'tcx> ::std::ops::Deref for Attributes<'tcx> { #[derive(Debug, PartialEq, Eq)] pub enum ImplOverlapKind { /// These impls are always allowed to overlap. - Permitted, + Permitted { + /// Whether or not the impl is permitted due to the trait being + /// a marker trait (a trait with #[marker], or a trait with + /// no associated items and #![feature(overlapping_marker_traits)] enabled) + marker: bool, + }, /// These impls are allowed to overlap, but that raises /// an issue #33140 future-compatibility warning. /// @@ -2833,7 +2838,7 @@ impl<'tcx> TyCtxt<'tcx> { if self.impl_trait_ref(def_id1).map_or(false, |tr| tr.references_error()) || self.impl_trait_ref(def_id2).map_or(false, |tr| tr.references_error()) { - return Some(ImplOverlapKind::Permitted); + return Some(ImplOverlapKind::Permitted { marker: false }); } match (self.impl_polarity(def_id1), self.impl_polarity(def_id2)) { @@ -2843,7 +2848,7 @@ impl<'tcx> TyCtxt<'tcx> { "impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted) (reservations)", def_id1, def_id2 ); - return Some(ImplOverlapKind::Permitted); + return Some(ImplOverlapKind::Permitted { marker: false }); } (ImplPolarity::Positive, ImplPolarity::Negative) | (ImplPolarity::Negative, ImplPolarity::Positive) => { @@ -2879,7 +2884,7 @@ impl<'tcx> TyCtxt<'tcx> { "impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted) (marker overlap)", def_id1, def_id2 ); - Some(ImplOverlapKind::Permitted) + Some(ImplOverlapKind::Permitted { marker: true }) } else { if let Some(self_ty1) = self.issue33140_self_ty(def_id1) { if let Some(self_ty2) = self.issue33140_self_ty(def_id2) { diff --git a/src/test/ui/marker_trait_attr/issue-61651-type-mismatch.rs b/src/test/ui/marker_trait_attr/issue-61651-type-mismatch.rs new file mode 100644 index 0000000000000..0af706615e31f --- /dev/null +++ b/src/test/ui/marker_trait_attr/issue-61651-type-mismatch.rs @@ -0,0 +1,17 @@ +// check-pass +// Regression test for issue #61651 +// Verifies that we don't try to constrain inference +// variables due to the presence of multiple applicable +// marker trait impls + +#![feature(marker_trait_attr)] + +#[marker] // Remove this line and it works?!? +trait Foo {} +impl Foo for u8 {} +impl Foo<[u8; 1]> for u8 {} +fn foo, U>(_: T) -> U { unimplemented!() } + +fn main() { + let _: u16 = foo(0_u8); +} From 451c97ba53412f6b1b740a5e6783da954e7c7be9 Mon Sep 17 00:00:00 2001 From: msizanoen1 Date: Fri, 10 Jan 2020 12:23:42 +0700 Subject: [PATCH 010/169] Distribution CI for RISC-V GNU/Linux --- src/ci/docker/dist-various-1/Dockerfile | 29 + .../dist-various-1/build-riscv-toolchain.sh | 27 + src/ci/docker/dist-various-1/crosstool-ng.sh | 13 + .../riscv64-unknown-linux-gnu.config | 908 ++++++++++++++++++ 4 files changed, 977 insertions(+) create mode 100755 src/ci/docker/dist-various-1/build-riscv-toolchain.sh create mode 100755 src/ci/docker/dist-various-1/crosstool-ng.sh create mode 100644 src/ci/docker/dist-various-1/riscv64-unknown-linux-gnu.config diff --git a/src/ci/docker/dist-various-1/Dockerfile b/src/ci/docker/dist-various-1/Dockerfile index 6bbf092878311..546e73e33d7f3 100644 --- a/src/ci/docker/dist-various-1/Dockerfile +++ b/src/ci/docker/dist-various-1/Dockerfile @@ -2,11 +2,24 @@ FROM ubuntu:16.04 RUN apt-get update && apt-get install -y --no-install-recommends \ g++ \ + automake \ + bison \ + bzip2 \ + flex \ + help2man \ + libtool-bin \ + texinfo \ + unzip \ + wget \ + xz-utils \ + libncurses-dev \ + gawk \ make \ file \ curl \ ca-certificates \ python2.7 \ + python3 \ git \ cmake \ sudo \ @@ -35,6 +48,18 @@ RUN add-apt-repository ppa:team-gcc-arm-embedded/ppa && \ apt-get update && \ apt-get install -y --no-install-recommends gcc-arm-embedded +COPY scripts/rustbuild-setup.sh dist-various-1/build-riscv-toolchain.sh dist-various-1/riscv64-unknown-linux-gnu.config dist-various-1/crosstool-ng.sh /build/ +RUN ./crosstool-ng.sh + +# Crosstool-ng will refuse to build as root +RUN sh ./rustbuild-setup.sh +USER rustbuild + +RUN ./build-riscv-toolchain.sh + +USER root +ENV PATH=/x-tools/riscv64-unknown-linux-gnu/bin:$PATH + COPY dist-various-1/build-rumprun.sh /build RUN ./build-rumprun.sh @@ -129,6 +154,7 @@ ENV TARGETS=$TARGETS,riscv32imc-unknown-none-elf ENV TARGETS=$TARGETS,riscv32imac-unknown-none-elf ENV TARGETS=$TARGETS,riscv64imac-unknown-none-elf ENV TARGETS=$TARGETS,riscv64gc-unknown-none-elf +ENV TARGETS=$TARGETS,riscv64gc-unknown-linux-gnu ENV TARGETS=$TARGETS,armebv7r-none-eabi ENV TARGETS=$TARGETS,armebv7r-none-eabihf ENV TARGETS=$TARGETS,armv7r-none-eabi @@ -147,6 +173,9 @@ ENV CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc \ CC_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-gcc \ AR_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-ar \ CXX_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-g++ \ + CC_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-gcc \ + AR_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-ar \ + CXX_riscv64gc_unknown_linux_gnu=riscv64-unknown-linux-gnu-g++ \ CC_riscv32i_unknown_none_elf=false \ CC_riscv32imc_unknown_none_elf=false \ CC_riscv32imac_unknown_none_elf=false \ diff --git a/src/ci/docker/dist-various-1/build-riscv-toolchain.sh b/src/ci/docker/dist-various-1/build-riscv-toolchain.sh new file mode 100755 index 0000000000000..9cb5700b3b6fb --- /dev/null +++ b/src/ci/docker/dist-various-1/build-riscv-toolchain.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +set -ex + +hide_output() { + set +x + on_err=" +echo ERROR: An error was encountered with the build. +cat /tmp/build.log +exit 1 +" + trap "$on_err" ERR + bash -c "while true; do sleep 30; echo \$(date) - building ...; done" & + PING_LOOP_PID=$! + $@ &> /tmp/build.log + rm /tmp/build.log + trap - ERR + kill $PING_LOOP_PID + set -x +} + +mkdir -p /tmp/build-riscv +cp riscv64-unknown-linux-gnu.config /tmp/build-riscv/.config +cd /tmp/build-riscv +hide_output ct-ng build +cd .. +rm -rf build-riscv diff --git a/src/ci/docker/dist-various-1/crosstool-ng.sh b/src/ci/docker/dist-various-1/crosstool-ng.sh new file mode 100755 index 0000000000000..b01fdd0bf65e7 --- /dev/null +++ b/src/ci/docker/dist-various-1/crosstool-ng.sh @@ -0,0 +1,13 @@ +#!/bin/bash +set -ex + +# Mirrored from https://github.com/crosstool-ng/crosstool-ng/archive/crosstool-ng-1.24.0.tar.gz +url="https://ci-mirrors.rust-lang.org/rustc/crosstool-ng-1.24.0.tar.gz" +curl -Lf $url | tar xzf - +cd crosstool-ng-crosstool-ng-1.24.0 +./bootstrap +./configure --prefix=/usr/local +make -j$(nproc) +make install +cd .. +rm -rf crosstool-ng-crosstool-ng-1.24.0 diff --git a/src/ci/docker/dist-various-1/riscv64-unknown-linux-gnu.config b/src/ci/docker/dist-various-1/riscv64-unknown-linux-gnu.config new file mode 100644 index 0000000000000..dd06065b19740 --- /dev/null +++ b/src/ci/docker/dist-various-1/riscv64-unknown-linux-gnu.config @@ -0,0 +1,908 @@ +# +# Automatically generated file; DO NOT EDIT. +# crosstool-NG Configuration +# +CT_CONFIGURE_has_static_link=y +CT_CONFIGURE_has_cxx11=y +CT_CONFIGURE_has_wget=y +CT_CONFIGURE_has_curl=y +CT_CONFIGURE_has_make_3_81_or_newer=y +CT_CONFIGURE_has_make_4_0_or_newer=y +CT_CONFIGURE_has_libtool_2_4_or_newer=y +CT_CONFIGURE_has_libtoolize_2_4_or_newer=y +CT_CONFIGURE_has_autoconf_2_65_or_newer=y +CT_CONFIGURE_has_autoreconf_2_65_or_newer=y +CT_CONFIGURE_has_automake_1_15_or_newer=y +CT_CONFIGURE_has_gnu_m4_1_4_12_or_newer=y +CT_CONFIGURE_has_python_3_4_or_newer=y +CT_CONFIGURE_has_bison_2_7_or_newer=y +CT_CONFIGURE_has_python=y +CT_CONFIGURE_has_dtc=y +CT_CONFIGURE_has_svn=y +CT_CONFIGURE_has_git=y +CT_CONFIGURE_has_md5sum=y +CT_CONFIGURE_has_sha1sum=y +CT_CONFIGURE_has_sha256sum=y +CT_CONFIGURE_has_sha512sum=y +CT_CONFIGURE_has_install_with_strip_program=y +CT_CONFIG_VERSION_CURRENT="3" +CT_CONFIG_VERSION="3" +CT_MODULES=y + +# +# Paths and misc options +# + +# +# crosstool-NG behavior +# +# CT_OBSOLETE is not set +CT_EXPERIMENTAL=y +# CT_ALLOW_BUILD_AS_ROOT is not set +# CT_DEBUG_CT is not set + +# +# Paths +# +CT_LOCAL_TARBALLS_DIR="${HOME}/src" +CT_SAVE_TARBALLS=y +# CT_TARBALLS_BUILDROOT_LAYOUT is not set +CT_WORK_DIR="${CT_TOP_DIR}/.build" +CT_BUILD_TOP_DIR="${CT_WORK_DIR:-${CT_TOP_DIR}/.build}/${CT_HOST:+HOST-${CT_HOST}/}${CT_TARGET}" +CT_PREFIX_DIR="/x-tools/${CT_TARGET}" +CT_RM_RF_PREFIX_DIR=y +CT_REMOVE_DOCS=y +CT_INSTALL_LICENSES=y +CT_PREFIX_DIR_RO=y +CT_STRIP_HOST_TOOLCHAIN_EXECUTABLES=y +# CT_STRIP_TARGET_TOOLCHAIN_EXECUTABLES is not set + +# +# Downloading +# +CT_DOWNLOAD_AGENT_WGET=y +# CT_DOWNLOAD_AGENT_CURL is not set +# CT_DOWNLOAD_AGENT_NONE is not set +# CT_FORBID_DOWNLOAD is not set +# CT_FORCE_DOWNLOAD is not set +CT_CONNECT_TIMEOUT=10 +CT_DOWNLOAD_WGET_OPTIONS="--passive-ftp --tries=3 -nc --progress=dot:binary" +# CT_ONLY_DOWNLOAD is not set +# CT_USE_MIRROR is not set +CT_VERIFY_DOWNLOAD_DIGEST=y +CT_VERIFY_DOWNLOAD_DIGEST_SHA512=y +# CT_VERIFY_DOWNLOAD_DIGEST_SHA256 is not set +# CT_VERIFY_DOWNLOAD_DIGEST_SHA1 is not set +# CT_VERIFY_DOWNLOAD_DIGEST_MD5 is not set +CT_VERIFY_DOWNLOAD_DIGEST_ALG="sha512" +# CT_VERIFY_DOWNLOAD_SIGNATURE is not set + +# +# Extracting +# +# CT_FORCE_EXTRACT is not set +CT_OVERRIDE_CONFIG_GUESS_SUB=y +# CT_ONLY_EXTRACT is not set +CT_PATCH_BUNDLED=y +# CT_PATCH_LOCAL is not set +# CT_PATCH_BUNDLED_LOCAL is not set +# CT_PATCH_LOCAL_BUNDLED is not set +# CT_PATCH_NONE is not set +CT_PATCH_ORDER="bundled" + +# +# Build behavior +# +CT_PARALLEL_JOBS=0 +CT_LOAD="" +CT_USE_PIPES=y +CT_EXTRA_CFLAGS_FOR_BUILD="" +CT_EXTRA_LDFLAGS_FOR_BUILD="" +CT_EXTRA_CFLAGS_FOR_HOST="" +CT_EXTRA_LDFLAGS_FOR_HOST="" +# CT_CONFIG_SHELL_SH is not set +# CT_CONFIG_SHELL_ASH is not set +CT_CONFIG_SHELL_BASH=y +# CT_CONFIG_SHELL_CUSTOM is not set +CT_CONFIG_SHELL="${bash}" + +# +# Logging +# +# CT_LOG_ERROR is not set +# CT_LOG_WARN is not set +# CT_LOG_INFO is not set +# CT_LOG_EXTRA is not set +CT_LOG_ALL=y +# CT_LOG_DEBUG is not set +CT_LOG_LEVEL_MAX="ALL" +# CT_LOG_SEE_TOOLS_WARN is not set +CT_LOG_TO_FILE=y +CT_LOG_FILE_COMPRESS=y + +# +# Target options +# +# CT_ARCH_ALPHA is not set +# CT_ARCH_ARC is not set +# CT_ARCH_ARM is not set +# CT_ARCH_AVR is not set +# CT_ARCH_M68K is not set +# CT_ARCH_MICROBLAZE is not set +# CT_ARCH_MIPS is not set +# CT_ARCH_MOXIE is not set +# CT_ARCH_MSP430 is not set +# CT_ARCH_NIOS2 is not set +# CT_ARCH_POWERPC is not set +CT_ARCH_RISCV=y +# CT_ARCH_S390 is not set +# CT_ARCH_SH is not set +# CT_ARCH_SPARC is not set +# CT_ARCH_X86 is not set +# CT_ARCH_XTENSA is not set +CT_ARCH="riscv" +CT_ARCH_CHOICE_KSYM="RISCV" +CT_ARCH_TUNE="" +CT_ARCH_RISCV_SHOW=y + +# +# Options for riscv +# +CT_ARCH_RISCV_PKG_KSYM="" +CT_ALL_ARCH_CHOICES="ALPHA ARC ARM AVR M68K MICROBLAZE MIPS MOXIE MSP430 NIOS2 POWERPC RISCV S390 SH SPARC X86 XTENSA" +CT_ARCH_SUFFIX="" +# CT_OMIT_TARGET_VENDOR is not set + +# +# Generic target options +# +# CT_MULTILIB is not set +# CT_DEMULTILIB is not set +CT_ARCH_SUPPORTS_BOTH_MMU=y +CT_ARCH_USE_MMU=y +CT_ARCH_SUPPORTS_32=y +CT_ARCH_SUPPORTS_64=y +CT_ARCH_DEFAULT_32=y +CT_ARCH_BITNESS=64 +# CT_ARCH_32 is not set +CT_ARCH_64=y + +# +# Target optimisations +# +CT_ARCH_SUPPORTS_WITH_ARCH=y +CT_ARCH_SUPPORTS_WITH_ABI=y +CT_ARCH_SUPPORTS_WITH_TUNE=y +CT_ARCH_ARCH="rv64gc" +CT_ARCH_ABI="" +CT_TARGET_CFLAGS="" +CT_TARGET_LDFLAGS="" + +# +# Toolchain options +# + +# +# General toolchain options +# +CT_FORCE_SYSROOT=y +CT_USE_SYSROOT=y +CT_SYSROOT_NAME="sysroot" +CT_SYSROOT_DIR_PREFIX="" +CT_WANTS_STATIC_LINK=y +CT_WANTS_STATIC_LINK_CXX=y +# CT_STATIC_TOOLCHAIN is not set +CT_SHOW_CT_VERSION=y +CT_TOOLCHAIN_PKGVERSION="" +CT_TOOLCHAIN_BUGURL="" + +# +# Tuple completion and aliasing +# +CT_TARGET_VENDOR="unknown" +CT_TARGET_ALIAS_SED_EXPR="" +CT_TARGET_ALIAS="" + +# +# Toolchain type +# +# CT_NATIVE is not set +CT_CROSS=y +# CT_CROSS_NATIVE is not set +# CT_CANADIAN is not set +CT_TOOLCHAIN_TYPE="cross" + +# +# Build system +# +CT_BUILD="" +CT_BUILD_PREFIX="" +CT_BUILD_SUFFIX="" + +# +# Misc options +# +# CT_TOOLCHAIN_ENABLE_NLS is not set + +# +# Operating System +# +CT_KERNEL_SUPPORTS_SHARED_LIBS=y +# CT_KERNEL_BARE_METAL is not set +CT_KERNEL_LINUX=y +CT_KERNEL="linux" +CT_KERNEL_CHOICE_KSYM="LINUX" +CT_KERNEL_LINUX_SHOW=y + +# +# Options for linux +# +CT_KERNEL_LINUX_PKG_KSYM="LINUX" +CT_LINUX_DIR_NAME="linux" +CT_LINUX_PKG_NAME="linux" +CT_LINUX_SRC_RELEASE=y +# CT_LINUX_SRC_DEVEL is not set +# CT_LINUX_SRC_CUSTOM is not set +CT_LINUX_PATCH_GLOBAL=y +# CT_LINUX_PATCH_BUNDLED is not set +# CT_LINUX_PATCH_LOCAL is not set +# CT_LINUX_PATCH_BUNDLED_LOCAL is not set +# CT_LINUX_PATCH_LOCAL_BUNDLED is not set +# CT_LINUX_PATCH_NONE is not set +CT_LINUX_PATCH_ORDER="global" +CT_LINUX_V_4_20=y +# CT_LINUX_V_4_19 is not set +# CT_LINUX_V_4_18 is not set +# CT_LINUX_V_4_17 is not set +# CT_LINUX_V_4_16 is not set +# CT_LINUX_V_4_15 is not set +# CT_LINUX_V_4_14 is not set +# CT_LINUX_V_4_13 is not set +# CT_LINUX_V_4_12 is not set +# CT_LINUX_V_4_11 is not set +# CT_LINUX_V_4_10 is not set +# CT_LINUX_V_4_9 is not set +# CT_LINUX_V_4_4 is not set +# CT_LINUX_V_4_1 is not set +# CT_LINUX_V_3_16 is not set +# CT_LINUX_V_3_13 is not set +# CT_LINUX_V_3_12 is not set +# CT_LINUX_V_3_10 is not set +# CT_LINUX_V_3_4 is not set +# CT_LINUX_V_3_2 is not set +# CT_LINUX_NO_VERSIONS is not set +CT_LINUX_VERSION="4.20.8" +CT_LINUX_MIRRORS="$(CT_Mirrors kernel.org linux ${CT_LINUX_VERSION})" +CT_LINUX_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_LINUX_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_LINUX_ARCHIVE_FORMATS=".tar.xz .tar.gz" +CT_LINUX_SIGNATURE_FORMAT="unpacked/.sign" +CT_LINUX_later_than_4_8=y +CT_LINUX_4_8_or_later=y +CT_LINUX_later_than_3_7=y +CT_LINUX_3_7_or_later=y +CT_LINUX_later_than_3_2=y +CT_LINUX_3_2_or_later=y +CT_LINUX_REQUIRE_3_2_or_later=y +CT_KERNEL_LINUX_VERBOSITY_0=y +# CT_KERNEL_LINUX_VERBOSITY_1 is not set +# CT_KERNEL_LINUX_VERBOSITY_2 is not set +CT_KERNEL_LINUX_VERBOSE_LEVEL=0 +CT_KERNEL_LINUX_INSTALL_CHECK=y +CT_ALL_KERNEL_CHOICES="BARE_METAL LINUX WINDOWS" + +# +# Common kernel options +# +CT_SHARED_LIBS=y + +# +# Binary utilities +# +CT_ARCH_BINFMT_ELF=y +CT_BINUTILS_BINUTILS=y +CT_BINUTILS="binutils" +CT_BINUTILS_CHOICE_KSYM="BINUTILS" +CT_BINUTILS_BINUTILS_SHOW=y + +# +# Options for binutils +# +CT_BINUTILS_BINUTILS_PKG_KSYM="BINUTILS" +CT_BINUTILS_DIR_NAME="binutils" +CT_BINUTILS_USE_GNU=y +CT_BINUTILS_USE="BINUTILS" +CT_BINUTILS_PKG_NAME="binutils" +CT_BINUTILS_SRC_RELEASE=y +# CT_BINUTILS_SRC_DEVEL is not set +# CT_BINUTILS_SRC_CUSTOM is not set +CT_BINUTILS_PATCH_GLOBAL=y +# CT_BINUTILS_PATCH_BUNDLED is not set +# CT_BINUTILS_PATCH_LOCAL is not set +# CT_BINUTILS_PATCH_BUNDLED_LOCAL is not set +# CT_BINUTILS_PATCH_LOCAL_BUNDLED is not set +# CT_BINUTILS_PATCH_NONE is not set +CT_BINUTILS_PATCH_ORDER="global" +CT_BINUTILS_V_2_32=y +# CT_BINUTILS_V_2_31 is not set +# CT_BINUTILS_V_2_30 is not set +# CT_BINUTILS_V_2_29 is not set +# CT_BINUTILS_V_2_28 is not set +# CT_BINUTILS_V_2_27 is not set +# CT_BINUTILS_V_2_26 is not set +# CT_BINUTILS_NO_VERSIONS is not set +CT_BINUTILS_VERSION="2.32" +CT_BINUTILS_MIRRORS="$(CT_Mirrors GNU binutils) $(CT_Mirrors sourceware binutils/releases)" +CT_BINUTILS_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_BINUTILS_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_BINUTILS_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" +CT_BINUTILS_SIGNATURE_FORMAT="packed/.sig" +CT_BINUTILS_later_than_2_30=y +CT_BINUTILS_2_30_or_later=y +CT_BINUTILS_later_than_2_27=y +CT_BINUTILS_2_27_or_later=y +CT_BINUTILS_later_than_2_25=y +CT_BINUTILS_2_25_or_later=y +CT_BINUTILS_REQUIRE_2_25_or_later=y +CT_BINUTILS_later_than_2_23=y +CT_BINUTILS_2_23_or_later=y + +# +# GNU binutils +# +CT_BINUTILS_HAS_HASH_STYLE=y +CT_BINUTILS_HAS_GOLD=y +CT_BINUTILS_HAS_PLUGINS=y +CT_BINUTILS_HAS_PKGVERSION_BUGURL=y +CT_BINUTILS_FORCE_LD_BFD_DEFAULT=y +CT_BINUTILS_LINKER_LD=y +CT_BINUTILS_LINKERS_LIST="ld" +CT_BINUTILS_LINKER_DEFAULT="bfd" +# CT_BINUTILS_PLUGINS is not set +CT_BINUTILS_RELRO=m +CT_BINUTILS_EXTRA_CONFIG_ARRAY="" +# CT_BINUTILS_FOR_TARGET is not set +CT_ALL_BINUTILS_CHOICES="BINUTILS" + +# +# C-library +# +CT_LIBC_GLIBC=y +# CT_LIBC_MUSL is not set +# CT_LIBC_UCLIBC is not set +CT_LIBC="glibc" +CT_LIBC_CHOICE_KSYM="GLIBC" +CT_THREADS="nptl" +CT_LIBC_GLIBC_SHOW=y + +# +# Options for glibc +# +CT_LIBC_GLIBC_PKG_KSYM="GLIBC" +CT_GLIBC_DIR_NAME="glibc" +CT_GLIBC_USE_GNU=y +CT_GLIBC_USE="GLIBC" +CT_GLIBC_PKG_NAME="glibc" +CT_GLIBC_SRC_RELEASE=y +# CT_GLIBC_SRC_DEVEL is not set +# CT_GLIBC_SRC_CUSTOM is not set +CT_GLIBC_PATCH_GLOBAL=y +# CT_GLIBC_PATCH_BUNDLED is not set +# CT_GLIBC_PATCH_LOCAL is not set +# CT_GLIBC_PATCH_BUNDLED_LOCAL is not set +# CT_GLIBC_PATCH_LOCAL_BUNDLED is not set +# CT_GLIBC_PATCH_NONE is not set +CT_GLIBC_PATCH_ORDER="global" +CT_GLIBC_V_2_29=y +# CT_GLIBC_NO_VERSIONS is not set +CT_GLIBC_VERSION="2.29" +CT_GLIBC_MIRRORS="$(CT_Mirrors GNU glibc)" +CT_GLIBC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_GLIBC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_GLIBC_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" +CT_GLIBC_SIGNATURE_FORMAT="packed/.sig" +CT_GLIBC_2_29_or_later=y +CT_GLIBC_2_29_or_older=y +CT_GLIBC_REQUIRE_2_29_or_later=y +CT_GLIBC_later_than_2_27=y +CT_GLIBC_2_27_or_later=y +CT_GLIBC_later_than_2_26=y +CT_GLIBC_2_26_or_later=y +CT_GLIBC_later_than_2_25=y +CT_GLIBC_2_25_or_later=y +CT_GLIBC_later_than_2_24=y +CT_GLIBC_2_24_or_later=y +CT_GLIBC_later_than_2_23=y +CT_GLIBC_2_23_or_later=y +CT_GLIBC_later_than_2_20=y +CT_GLIBC_2_20_or_later=y +CT_GLIBC_later_than_2_17=y +CT_GLIBC_2_17_or_later=y +CT_GLIBC_later_than_2_14=y +CT_GLIBC_2_14_or_later=y +CT_GLIBC_DEP_KERNEL_HEADERS_VERSION=y +CT_GLIBC_DEP_BINUTILS=y +CT_GLIBC_DEP_GCC=y +CT_GLIBC_DEP_PYTHON=y +CT_GLIBC_BUILD_SSP=y +CT_GLIBC_HAS_LIBIDN_ADDON=y +# CT_GLIBC_USE_LIBIDN_ADDON is not set +CT_GLIBC_NO_SPARC_V8=y +CT_GLIBC_HAS_OBSOLETE_RPC=y +CT_GLIBC_EXTRA_CONFIG_ARRAY="" +CT_GLIBC_CONFIGPARMS="" +CT_GLIBC_EXTRA_CFLAGS="" +CT_GLIBC_ENABLE_OBSOLETE_RPC=y +# CT_GLIBC_ENABLE_FORTIFIED_BUILD is not set +# CT_GLIBC_DISABLE_VERSIONING is not set +CT_GLIBC_OLDEST_ABI="" +CT_GLIBC_FORCE_UNWIND=y +# CT_GLIBC_LOCALES is not set +CT_GLIBC_KERNEL_VERSION_NONE=y +# CT_GLIBC_KERNEL_VERSION_AS_HEADERS is not set +# CT_GLIBC_KERNEL_VERSION_CHOSEN is not set +CT_GLIBC_MIN_KERNEL="" +CT_GLIBC_SSP_DEFAULT=y +# CT_GLIBC_SSP_NO is not set +# CT_GLIBC_SSP_YES is not set +# CT_GLIBC_SSP_ALL is not set +# CT_GLIBC_SSP_STRONG is not set +# CT_GLIBC_ENABLE_WERROR is not set +CT_ALL_LIBC_CHOICES="AVR_LIBC BIONIC GLIBC MINGW_W64 MOXIEBOX MUSL NEWLIB NONE UCLIBC" +CT_LIBC_SUPPORT_THREADS_ANY=y +CT_LIBC_SUPPORT_THREADS_NATIVE=y + +# +# Common C library options +# +CT_THREADS_NATIVE=y +# CT_CREATE_LDSO_CONF is not set +CT_LIBC_XLDD=y + +# +# C compiler +# +CT_CC_CORE_PASSES_NEEDED=y +CT_CC_CORE_PASS_1_NEEDED=y +CT_CC_CORE_PASS_2_NEEDED=y +CT_CC_SUPPORT_CXX=y +CT_CC_SUPPORT_FORTRAN=y +CT_CC_SUPPORT_ADA=y +CT_CC_SUPPORT_OBJC=y +CT_CC_SUPPORT_OBJCXX=y +CT_CC_SUPPORT_GOLANG=y +CT_CC_GCC=y +CT_CC="gcc" +CT_CC_CHOICE_KSYM="GCC" +CT_CC_GCC_SHOW=y + +# +# Options for gcc +# +CT_CC_GCC_PKG_KSYM="GCC" +CT_GCC_DIR_NAME="gcc" +CT_GCC_USE_GNU=y +# CT_GCC_USE_LINARO is not set +CT_GCC_USE="GCC" +CT_GCC_PKG_NAME="gcc" +CT_GCC_SRC_RELEASE=y +# CT_GCC_SRC_DEVEL is not set +# CT_GCC_SRC_CUSTOM is not set +CT_GCC_PATCH_GLOBAL=y +# CT_GCC_PATCH_BUNDLED is not set +# CT_GCC_PATCH_LOCAL is not set +# CT_GCC_PATCH_BUNDLED_LOCAL is not set +# CT_GCC_PATCH_LOCAL_BUNDLED is not set +# CT_GCC_PATCH_NONE is not set +CT_GCC_PATCH_ORDER="global" +CT_GCC_V_8=y +# CT_GCC_V_7 is not set +# CT_GCC_NO_VERSIONS is not set +CT_GCC_VERSION="8.3.0" +CT_GCC_MIRRORS="$(CT_Mirrors GNU gcc/gcc-${CT_GCC_VERSION}) $(CT_Mirrors sourceware gcc/releases/gcc-${CT_GCC_VERSION})" +CT_GCC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_GCC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_GCC_ARCHIVE_FORMATS=".tar.xz .tar.gz" +CT_GCC_SIGNATURE_FORMAT="" +CT_GCC_later_than_7=y +CT_GCC_7_or_later=y +CT_GCC_REQUIRE_7_or_later=y +CT_GCC_later_than_6=y +CT_GCC_6_or_later=y +CT_GCC_later_than_5=y +CT_GCC_5_or_later=y +CT_GCC_REQUIRE_5_or_later=y +CT_GCC_later_than_4_9=y +CT_GCC_4_9_or_later=y +CT_GCC_REQUIRE_4_9_or_later=y +CT_GCC_later_than_4_8=y +CT_GCC_4_8_or_later=y +CT_CC_GCC_HAS_LIBMPX=y +CT_CC_GCC_ENABLE_CXX_FLAGS="" +CT_CC_GCC_CORE_EXTRA_CONFIG_ARRAY="" +CT_CC_GCC_EXTRA_CONFIG_ARRAY="" +CT_CC_GCC_STATIC_LIBSTDCXX=y +# CT_CC_GCC_SYSTEM_ZLIB is not set +CT_CC_GCC_CONFIG_TLS=m + +# +# Optimisation features +# +CT_CC_GCC_USE_GRAPHITE=y +CT_CC_GCC_USE_LTO=y + +# +# Settings for libraries running on target +# +CT_CC_GCC_ENABLE_TARGET_OPTSPACE=y +# CT_CC_GCC_LIBMUDFLAP is not set +# CT_CC_GCC_LIBGOMP is not set +# CT_CC_GCC_LIBSSP is not set +# CT_CC_GCC_LIBQUADMATH is not set +# CT_CC_GCC_LIBSANITIZER is not set + +# +# Misc. obscure options. +# +CT_CC_CXA_ATEXIT=y +# CT_CC_GCC_DISABLE_PCH is not set +CT_CC_GCC_SJLJ_EXCEPTIONS=m +CT_CC_GCC_LDBL_128=m +# CT_CC_GCC_BUILD_ID is not set +CT_CC_GCC_LNK_HASH_STYLE_DEFAULT=y +# CT_CC_GCC_LNK_HASH_STYLE_SYSV is not set +# CT_CC_GCC_LNK_HASH_STYLE_GNU is not set +# CT_CC_GCC_LNK_HASH_STYLE_BOTH is not set +CT_CC_GCC_LNK_HASH_STYLE="" +CT_CC_GCC_DEC_FLOAT_AUTO=y +# CT_CC_GCC_DEC_FLOAT_BID is not set +# CT_CC_GCC_DEC_FLOAT_DPD is not set +# CT_CC_GCC_DEC_FLOATS_NO is not set +CT_ALL_CC_CHOICES="GCC" + +# +# Additional supported languages: +# +CT_CC_LANG_CXX=y +# CT_CC_LANG_FORTRAN is not set +# CT_CC_LANG_ADA is not set +# CT_CC_LANG_OBJC is not set +# CT_CC_LANG_OBJCXX is not set +# CT_CC_LANG_GOLANG is not set +CT_CC_LANG_OTHERS="" + +# +# Debug facilities +# +# CT_DEBUG_DUMA is not set +CT_DEBUG_GDB=y +CT_DEBUG_GDB_PKG_KSYM="GDB" +CT_GDB_DIR_NAME="gdb" +CT_GDB_USE_GNU=y +CT_GDB_USE="GDB" +CT_GDB_PKG_NAME="gdb" +CT_GDB_SRC_RELEASE=y +# CT_GDB_SRC_DEVEL is not set +# CT_GDB_SRC_CUSTOM is not set +CT_GDB_PATCH_GLOBAL=y +# CT_GDB_PATCH_BUNDLED is not set +# CT_GDB_PATCH_LOCAL is not set +# CT_GDB_PATCH_BUNDLED_LOCAL is not set +# CT_GDB_PATCH_LOCAL_BUNDLED is not set +# CT_GDB_PATCH_NONE is not set +CT_GDB_PATCH_ORDER="global" +CT_GDB_V_8_2=y +# CT_GDB_V_8_1 is not set +# CT_GDB_V_8_0 is not set +# CT_GDB_NO_VERSIONS is not set +CT_GDB_VERSION="8.2.1" +CT_GDB_MIRRORS="$(CT_Mirrors GNU gdb) $(CT_Mirrors sourceware gdb/releases)" +CT_GDB_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_GDB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_GDB_ARCHIVE_FORMATS=".tar.xz .tar.gz" +CT_GDB_SIGNATURE_FORMAT="" +CT_GDB_later_than_8_0=y +CT_GDB_8_0_or_later=y +CT_GDB_REQUIRE_8_0_or_later=y +CT_GDB_later_than_7_12=y +CT_GDB_7_12_or_later=y +CT_GDB_later_than_7_2=y +CT_GDB_7_2_or_later=y +CT_GDB_later_than_7_0=y +CT_GDB_7_0_or_later=y +CT_GDB_CROSS=y +# CT_GDB_CROSS_STATIC is not set +# CT_GDB_CROSS_SIM is not set +# CT_GDB_CROSS_PYTHON is not set +CT_GDB_CROSS_EXTRA_CONFIG_ARRAY="" +# CT_GDB_NATIVE is not set +# CT_GDB_GDBSERVER is not set +CT_GDB_HAS_PKGVERSION_BUGURL=y +CT_GDB_HAS_PYTHON=y +CT_GDB_INSTALL_GDBINIT=y +CT_GDB_HAS_IPA_LIB=y +# CT_DEBUG_LTRACE is not set +# CT_DEBUG_STRACE is not set +CT_ALL_DEBUG_CHOICES="DUMA GDB LTRACE STRACE" + +# +# Companion libraries +# +# CT_COMPLIBS_CHECK is not set +# CT_COMP_LIBS_CLOOG is not set +CT_COMP_LIBS_EXPAT=y +CT_COMP_LIBS_EXPAT_PKG_KSYM="EXPAT" +CT_EXPAT_DIR_NAME="expat" +CT_EXPAT_PKG_NAME="expat" +CT_EXPAT_SRC_RELEASE=y +# CT_EXPAT_SRC_DEVEL is not set +# CT_EXPAT_SRC_CUSTOM is not set +CT_EXPAT_PATCH_GLOBAL=y +# CT_EXPAT_PATCH_BUNDLED is not set +# CT_EXPAT_PATCH_LOCAL is not set +# CT_EXPAT_PATCH_BUNDLED_LOCAL is not set +# CT_EXPAT_PATCH_LOCAL_BUNDLED is not set +# CT_EXPAT_PATCH_NONE is not set +CT_EXPAT_PATCH_ORDER="global" +CT_EXPAT_V_2_2=y +# CT_EXPAT_NO_VERSIONS is not set +CT_EXPAT_VERSION="2.2.6" +CT_EXPAT_MIRRORS="http://downloads.sourceforge.net/project/expat/expat/${CT_EXPAT_VERSION}" +CT_EXPAT_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_EXPAT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_EXPAT_ARCHIVE_FORMATS=".tar.bz2" +CT_EXPAT_SIGNATURE_FORMAT="" +CT_COMP_LIBS_GETTEXT=y +CT_COMP_LIBS_GETTEXT_PKG_KSYM="GETTEXT" +CT_GETTEXT_DIR_NAME="gettext" +CT_GETTEXT_PKG_NAME="gettext" +CT_GETTEXT_SRC_RELEASE=y +# CT_GETTEXT_SRC_DEVEL is not set +# CT_GETTEXT_SRC_CUSTOM is not set +CT_GETTEXT_PATCH_GLOBAL=y +# CT_GETTEXT_PATCH_BUNDLED is not set +# CT_GETTEXT_PATCH_LOCAL is not set +# CT_GETTEXT_PATCH_BUNDLED_LOCAL is not set +# CT_GETTEXT_PATCH_LOCAL_BUNDLED is not set +# CT_GETTEXT_PATCH_NONE is not set +CT_GETTEXT_PATCH_ORDER="global" +CT_GETTEXT_V_0_19_8_1=y +# CT_GETTEXT_NO_VERSIONS is not set +CT_GETTEXT_VERSION="0.19.8.1" +CT_GETTEXT_MIRRORS="$(CT_Mirrors GNU gettext)" +CT_GETTEXT_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_GETTEXT_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_GETTEXT_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.gz" +CT_GETTEXT_SIGNATURE_FORMAT="packed/.sig" +CT_COMP_LIBS_GMP=y +CT_COMP_LIBS_GMP_PKG_KSYM="GMP" +CT_GMP_DIR_NAME="gmp" +CT_GMP_PKG_NAME="gmp" +CT_GMP_SRC_RELEASE=y +# CT_GMP_SRC_DEVEL is not set +# CT_GMP_SRC_CUSTOM is not set +CT_GMP_PATCH_GLOBAL=y +# CT_GMP_PATCH_BUNDLED is not set +# CT_GMP_PATCH_LOCAL is not set +# CT_GMP_PATCH_BUNDLED_LOCAL is not set +# CT_GMP_PATCH_LOCAL_BUNDLED is not set +# CT_GMP_PATCH_NONE is not set +CT_GMP_PATCH_ORDER="global" +CT_GMP_V_6_1=y +# CT_GMP_NO_VERSIONS is not set +CT_GMP_VERSION="6.1.2" +CT_GMP_MIRRORS="https://gmplib.org/download/gmp https://gmplib.org/download/gmp/archive $(CT_Mirrors GNU gmp)" +CT_GMP_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_GMP_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_GMP_ARCHIVE_FORMATS=".tar.xz .tar.lz .tar.bz2" +CT_GMP_SIGNATURE_FORMAT="packed/.sig" +CT_GMP_later_than_5_1_0=y +CT_GMP_5_1_0_or_later=y +CT_GMP_later_than_5_0_0=y +CT_GMP_5_0_0_or_later=y +CT_GMP_REQUIRE_5_0_0_or_later=y +CT_COMP_LIBS_ISL=y +CT_COMP_LIBS_ISL_PKG_KSYM="ISL" +CT_ISL_DIR_NAME="isl" +CT_ISL_PKG_NAME="isl" +CT_ISL_SRC_RELEASE=y +# CT_ISL_SRC_DEVEL is not set +# CT_ISL_SRC_CUSTOM is not set +CT_ISL_PATCH_GLOBAL=y +# CT_ISL_PATCH_BUNDLED is not set +# CT_ISL_PATCH_LOCAL is not set +# CT_ISL_PATCH_BUNDLED_LOCAL is not set +# CT_ISL_PATCH_LOCAL_BUNDLED is not set +# CT_ISL_PATCH_NONE is not set +CT_ISL_PATCH_ORDER="global" +CT_ISL_V_0_20=y +# CT_ISL_V_0_19 is not set +# CT_ISL_V_0_18 is not set +# CT_ISL_V_0_17 is not set +# CT_ISL_V_0_16 is not set +# CT_ISL_V_0_15 is not set +# CT_ISL_NO_VERSIONS is not set +CT_ISL_VERSION="0.20" +CT_ISL_MIRRORS="http://isl.gforge.inria.fr" +CT_ISL_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_ISL_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_ISL_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz" +CT_ISL_SIGNATURE_FORMAT="" +CT_ISL_later_than_0_18=y +CT_ISL_0_18_or_later=y +CT_ISL_later_than_0_15=y +CT_ISL_0_15_or_later=y +CT_ISL_REQUIRE_0_15_or_later=y +CT_ISL_later_than_0_14=y +CT_ISL_0_14_or_later=y +CT_ISL_REQUIRE_0_14_or_later=y +CT_ISL_later_than_0_13=y +CT_ISL_0_13_or_later=y +CT_ISL_later_than_0_12=y +CT_ISL_0_12_or_later=y +CT_ISL_REQUIRE_0_12_or_later=y +# CT_COMP_LIBS_LIBELF is not set +CT_COMP_LIBS_LIBICONV=y +CT_COMP_LIBS_LIBICONV_PKG_KSYM="LIBICONV" +CT_LIBICONV_DIR_NAME="libiconv" +CT_LIBICONV_PKG_NAME="libiconv" +CT_LIBICONV_SRC_RELEASE=y +# CT_LIBICONV_SRC_DEVEL is not set +# CT_LIBICONV_SRC_CUSTOM is not set +CT_LIBICONV_PATCH_GLOBAL=y +# CT_LIBICONV_PATCH_BUNDLED is not set +# CT_LIBICONV_PATCH_LOCAL is not set +# CT_LIBICONV_PATCH_BUNDLED_LOCAL is not set +# CT_LIBICONV_PATCH_LOCAL_BUNDLED is not set +# CT_LIBICONV_PATCH_NONE is not set +CT_LIBICONV_PATCH_ORDER="global" +CT_LIBICONV_V_1_15=y +# CT_LIBICONV_NO_VERSIONS is not set +CT_LIBICONV_VERSION="1.15" +CT_LIBICONV_MIRRORS="$(CT_Mirrors GNU libiconv)" +CT_LIBICONV_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_LIBICONV_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_LIBICONV_ARCHIVE_FORMATS=".tar.gz" +CT_LIBICONV_SIGNATURE_FORMAT="packed/.sig" +CT_COMP_LIBS_MPC=y +CT_COMP_LIBS_MPC_PKG_KSYM="MPC" +CT_MPC_DIR_NAME="mpc" +CT_MPC_PKG_NAME="mpc" +CT_MPC_SRC_RELEASE=y +# CT_MPC_SRC_DEVEL is not set +# CT_MPC_SRC_CUSTOM is not set +CT_MPC_PATCH_GLOBAL=y +# CT_MPC_PATCH_BUNDLED is not set +# CT_MPC_PATCH_LOCAL is not set +# CT_MPC_PATCH_BUNDLED_LOCAL is not set +# CT_MPC_PATCH_LOCAL_BUNDLED is not set +# CT_MPC_PATCH_NONE is not set +CT_MPC_PATCH_ORDER="global" +CT_MPC_V_1_1=y +# CT_MPC_V_1_0 is not set +# CT_MPC_NO_VERSIONS is not set +CT_MPC_VERSION="1.1.0" +CT_MPC_MIRRORS="http://www.multiprecision.org/downloads $(CT_Mirrors GNU mpc)" +CT_MPC_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_MPC_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_MPC_ARCHIVE_FORMATS=".tar.gz" +CT_MPC_SIGNATURE_FORMAT="packed/.sig" +CT_MPC_1_1_0_or_later=y +CT_MPC_1_1_0_or_older=y +CT_COMP_LIBS_MPFR=y +CT_COMP_LIBS_MPFR_PKG_KSYM="MPFR" +CT_MPFR_DIR_NAME="mpfr" +CT_MPFR_PKG_NAME="mpfr" +CT_MPFR_SRC_RELEASE=y +# CT_MPFR_SRC_DEVEL is not set +# CT_MPFR_SRC_CUSTOM is not set +CT_MPFR_PATCH_GLOBAL=y +# CT_MPFR_PATCH_BUNDLED is not set +# CT_MPFR_PATCH_LOCAL is not set +# CT_MPFR_PATCH_BUNDLED_LOCAL is not set +# CT_MPFR_PATCH_LOCAL_BUNDLED is not set +# CT_MPFR_PATCH_NONE is not set +CT_MPFR_PATCH_ORDER="global" +CT_MPFR_V_4_0=y +# CT_MPFR_V_3_1 is not set +# CT_MPFR_NO_VERSIONS is not set +CT_MPFR_VERSION="4.0.2" +CT_MPFR_MIRRORS="http://www.mpfr.org/mpfr-${CT_MPFR_VERSION} $(CT_Mirrors GNU mpfr)" +CT_MPFR_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_MPFR_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_MPFR_ARCHIVE_FORMATS=".tar.xz .tar.bz2 .tar.gz .zip" +CT_MPFR_SIGNATURE_FORMAT="packed/.asc" +CT_MPFR_later_than_4_0_0=y +CT_MPFR_4_0_0_or_later=y +CT_MPFR_later_than_3_0_0=y +CT_MPFR_3_0_0_or_later=y +CT_MPFR_REQUIRE_3_0_0_or_later=y +CT_COMP_LIBS_NCURSES=y +CT_COMP_LIBS_NCURSES_PKG_KSYM="NCURSES" +CT_NCURSES_DIR_NAME="ncurses" +CT_NCURSES_PKG_NAME="ncurses" +CT_NCURSES_SRC_RELEASE=y +# CT_NCURSES_SRC_DEVEL is not set +# CT_NCURSES_SRC_CUSTOM is not set +CT_NCURSES_PATCH_GLOBAL=y +# CT_NCURSES_PATCH_BUNDLED is not set +# CT_NCURSES_PATCH_LOCAL is not set +# CT_NCURSES_PATCH_BUNDLED_LOCAL is not set +# CT_NCURSES_PATCH_LOCAL_BUNDLED is not set +# CT_NCURSES_PATCH_NONE is not set +CT_NCURSES_PATCH_ORDER="global" +CT_NCURSES_V_6_1=y +# CT_NCURSES_V_6_0 is not set +# CT_NCURSES_NO_VERSIONS is not set +CT_NCURSES_VERSION="6.1" +CT_NCURSES_MIRRORS="ftp://invisible-island.net/ncurses $(CT_Mirrors GNU ncurses)" +CT_NCURSES_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_NCURSES_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_NCURSES_ARCHIVE_FORMATS=".tar.gz" +CT_NCURSES_SIGNATURE_FORMAT="packed/.sig" +# CT_NCURSES_NEW_ABI is not set +CT_NCURSES_HOST_CONFIG_ARGS="" +CT_NCURSES_HOST_DISABLE_DB=y +CT_NCURSES_HOST_FALLBACKS="linux,xterm,xterm-color,xterm-256color,vt100" +CT_NCURSES_TARGET_CONFIG_ARGS="" +# CT_NCURSES_TARGET_DISABLE_DB is not set +CT_NCURSES_TARGET_FALLBACKS="" +CT_COMP_LIBS_ZLIB=y +CT_COMP_LIBS_ZLIB_PKG_KSYM="ZLIB" +CT_ZLIB_DIR_NAME="zlib" +CT_ZLIB_PKG_NAME="zlib" +CT_ZLIB_SRC_RELEASE=y +# CT_ZLIB_SRC_DEVEL is not set +# CT_ZLIB_SRC_CUSTOM is not set +CT_ZLIB_PATCH_GLOBAL=y +# CT_ZLIB_PATCH_BUNDLED is not set +# CT_ZLIB_PATCH_LOCAL is not set +# CT_ZLIB_PATCH_BUNDLED_LOCAL is not set +# CT_ZLIB_PATCH_LOCAL_BUNDLED is not set +# CT_ZLIB_PATCH_NONE is not set +CT_ZLIB_PATCH_ORDER="global" +CT_ZLIB_V_1_2_11=y +# CT_ZLIB_NO_VERSIONS is not set +CT_ZLIB_VERSION="1.2.11" +CT_ZLIB_MIRRORS="http://downloads.sourceforge.net/project/libpng/zlib/${CT_ZLIB_VERSION}" +CT_ZLIB_ARCHIVE_FILENAME="@{pkg_name}-@{version}" +CT_ZLIB_ARCHIVE_DIRNAME="@{pkg_name}-@{version}" +CT_ZLIB_ARCHIVE_FORMATS=".tar.xz .tar.gz" +CT_ZLIB_SIGNATURE_FORMAT="packed/.asc" +CT_ALL_COMP_LIBS_CHOICES="CLOOG EXPAT GETTEXT GMP ISL LIBELF LIBICONV MPC MPFR NCURSES ZLIB" +CT_LIBICONV_NEEDED=y +CT_GETTEXT_NEEDED=y +CT_GMP_NEEDED=y +CT_MPFR_NEEDED=y +CT_ISL_NEEDED=y +CT_MPC_NEEDED=y +CT_EXPAT_NEEDED=y +CT_NCURSES_NEEDED=y +CT_ZLIB_NEEDED=y +CT_LIBICONV=y +CT_GETTEXT=y +CT_GMP=y +CT_MPFR=y +CT_ISL=y +CT_MPC=y +CT_EXPAT=y +CT_NCURSES=y +CT_ZLIB=y + +# +# Companion tools +# +# CT_COMP_TOOLS_FOR_HOST is not set +# CT_COMP_TOOLS_AUTOCONF is not set +# CT_COMP_TOOLS_AUTOMAKE is not set +# CT_COMP_TOOLS_BISON is not set +# CT_COMP_TOOLS_DTC is not set +# CT_COMP_TOOLS_LIBTOOL is not set +# CT_COMP_TOOLS_M4 is not set +# CT_COMP_TOOLS_MAKE is not set +CT_ALL_COMP_TOOLS_CHOICES="AUTOCONF AUTOMAKE BISON DTC LIBTOOL M4 MAKE" + +# +# Test suite +# +# CT_TEST_SUITE_GCC is not set From 4b19c80819efbbf48a0efe0aba0e6e2fd3cafbc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 2 Jan 2020 00:19:29 +0100 Subject: [PATCH 011/169] Don't create strings in the fast path --- src/librustc_typeck/astconv.rs | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index c15bcd81443d6..84b63e986d978 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1318,10 +1318,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // those that do. self.one_bound_for_assoc_type( || traits::supertraits(tcx, trait_ref), - &trait_ref.print_only_trait_path().to_string(), + || trait_ref.print_only_trait_path().to_string(), binding.item_name, path_span, - match binding.kind { + || match binding.kind { ConvertedBindingKind::Equality(ty) => Some(ty.to_string()), _ => None, }, @@ -1878,10 +1878,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { predicates.iter().filter_map(|(p, _)| p.to_opt_poly_trait_ref()), ) }, - ¶m_name.as_str(), + || param_name.to_string(), assoc_name, span, - None, + || None, ) } @@ -1890,10 +1890,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { fn one_bound_for_assoc_type( &self, all_candidates: impl Fn() -> I, - ty_param_name: &str, + ty_param_name: impl Fn() -> String, assoc_name: ast::Ident, span: Span, - is_equality: Option, + is_equality: impl Fn() -> Option, ) -> Result, ErrorReported> where I: Iterator>, @@ -1906,7 +1906,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { None => { self.complain_about_assoc_type_not_found( all_candidates, - ty_param_name, + &ty_param_name(), assoc_name, span, ); @@ -1919,6 +1919,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { if let Some(bound2) = matching_candidates.next() { debug!("one_bound_for_assoc_type: bound2 = {:?}", bound2); + let is_equality = is_equality(); let bounds = iter::once(bound).chain(iter::once(bound2)).chain(matching_candidates); let mut err = if is_equality.is_some() { // More specific Error Index entry. @@ -1928,7 +1929,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { E0222, "ambiguous associated type `{}` in bounds of `{}`", assoc_name, - ty_param_name + ty_param_name() ) } else { struct_span_err!( @@ -1937,7 +1938,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { E0221, "ambiguous associated type `{}` in bounds of `{}`", assoc_name, - ty_param_name + ty_param_name() ) }; err.span_label(span, format!("ambiguous associated type `{}`", assoc_name)); @@ -1975,7 +1976,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { "use fully qualified syntax to disambiguate", format!( "<{} as {}>::{}", - ty_param_name, + ty_param_name(), bound.print_only_trait_path(), assoc_name, ), @@ -1985,7 +1986,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } else { err.note(&format!( "associated type `{}` could derive from `{}`", - ty_param_name, + ty_param_name(), bound.print_only_trait_path(), )); } @@ -1994,7 +1995,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { err.help(&format!( "consider introducing a new type parameter `T` and adding `where` constraints:\ \n where\n T: {},\n{}", - ty_param_name, + ty_param_name(), where_bounds.join(",\n"), )); } @@ -2108,10 +2109,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self.one_bound_for_assoc_type( || traits::supertraits(tcx, ty::Binder::bind(trait_ref)), - "Self", + || "Self".to_string(), assoc_ident, span, - None, + || None, )? } (&ty::Param(_), Res::SelfTy(Some(param_did), None)) From edee9c3898bdc3e319d90322259e535affd6ae49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 2 Jan 2020 00:44:34 +0100 Subject: [PATCH 012/169] Lift using interners instead of in_arena --- src/librustc/ty/context.rs | 39 ++++++++++++++----------- src/librustc_data_structures/sharded.rs | 14 +++++++++ 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 1b0b5fc4d078d..0c00f06b7b3f5 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -53,7 +53,7 @@ use rustc_hir::{ItemKind, ItemLocalId, ItemLocalMap, ItemLocalSet}; use arena::SyncDroplessArena; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::profiling::SelfProfilerRef; -use rustc_data_structures::sharded::ShardedHashMap; +use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap}; use rustc_data_structures::stable_hasher::{ hash_stable_hashmap, HashStable, StableHasher, StableVec, }; @@ -1560,11 +1560,11 @@ pub trait Lift<'tcx>: fmt::Debug { } macro_rules! nop_lift { - ($ty:ty => $lifted:ty) => { + ($set:ident; $ty:ty => $lifted:ty) => { impl<'a, 'tcx> Lift<'tcx> for $ty { type Lifted = $lifted; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { - if tcx.interners.arena.in_arena(*self as *const _) { + if tcx.interners.$set.contains_pointer_to(&Interned(*self)) { Some(unsafe { mem::transmute(*self) }) } else { None @@ -1575,14 +1575,14 @@ macro_rules! nop_lift { } macro_rules! nop_list_lift { - ($ty:ty => $lifted:ty) => { + ($set:ident; $ty:ty => $lifted:ty) => { impl<'a, 'tcx> Lift<'tcx> for &'a List<$ty> { type Lifted = &'tcx List<$lifted>; fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option { if self.is_empty() { return Some(List::empty()); } - if tcx.interners.arena.in_arena(*self as *const _) { + if tcx.interners.$set.contains_pointer_to(&Interned(*self)) { Some(unsafe { mem::transmute(*self) }) } else { None @@ -1592,21 +1592,21 @@ macro_rules! nop_list_lift { }; } -nop_lift! {Ty<'a> => Ty<'tcx>} -nop_lift! {Region<'a> => Region<'tcx>} -nop_lift! {Goal<'a> => Goal<'tcx>} -nop_lift! {&'a Const<'a> => &'tcx Const<'tcx>} +nop_lift! {type_; Ty<'a> => Ty<'tcx>} +nop_lift! {region; Region<'a> => Region<'tcx>} +nop_lift! {goal; Goal<'a> => Goal<'tcx>} +nop_lift! {const_; &'a Const<'a> => &'tcx Const<'tcx>} -nop_list_lift! {Goal<'a> => Goal<'tcx>} -nop_list_lift! {Clause<'a> => Clause<'tcx>} -nop_list_lift! {Ty<'a> => Ty<'tcx>} -nop_list_lift! {ExistentialPredicate<'a> => ExistentialPredicate<'tcx>} -nop_list_lift! {Predicate<'a> => Predicate<'tcx>} -nop_list_lift! {CanonicalVarInfo => CanonicalVarInfo} -nop_list_lift! {ProjectionKind => ProjectionKind} +nop_list_lift! {goal_list; Goal<'a> => Goal<'tcx>} +nop_list_lift! {clauses; Clause<'a> => Clause<'tcx>} +nop_list_lift! {type_list; Ty<'a> => Ty<'tcx>} +nop_list_lift! {existential_predicates; ExistentialPredicate<'a> => ExistentialPredicate<'tcx>} +nop_list_lift! {predicates; Predicate<'a> => Predicate<'tcx>} +nop_list_lift! {canonical_var_infos; CanonicalVarInfo => CanonicalVarInfo} +nop_list_lift! {projs; ProjectionKind => ProjectionKind} // This is the impl for `&'a InternalSubsts<'a>`. -nop_list_lift! {GenericArg<'a> => GenericArg<'tcx>} +nop_list_lift! {substs; GenericArg<'a> => GenericArg<'tcx>} pub mod tls { use super::{ptr_eq, GlobalCtxt, TyCtxt}; @@ -1930,6 +1930,11 @@ impl<'tcx, T: 'tcx + ?Sized> Clone for Interned<'tcx, T> { } impl<'tcx, T: 'tcx + ?Sized> Copy for Interned<'tcx, T> {} +impl<'tcx, T: 'tcx + ?Sized> IntoPointer for Interned<'tcx, T> { + fn into_pointer(&self) -> *const () { + self.0 as *const _ as *const () + } +} // N.B., an `Interned` compares and hashes as a `TyKind`. impl<'tcx> PartialEq for Interned<'tcx, TyS<'tcx>> { fn eq(&self, other: &Interned<'tcx, TyS<'tcx>>) -> bool { diff --git a/src/librustc_data_structures/sharded.rs b/src/librustc_data_structures/sharded.rs index 8b85d97a1d4fe..ee3f88ff1675f 100644 --- a/src/librustc_data_structures/sharded.rs +++ b/src/librustc_data_structures/sharded.rs @@ -137,6 +137,20 @@ impl ShardedHashMap { } } +pub trait IntoPointer { + /// Returns a pointer which outlives `self`. + fn into_pointer(&self) -> *const (); +} + +impl ShardedHashMap { + pub fn contains_pointer_to(&self, value: &T) -> bool { + let hash = make_hash(&value); + let shard = self.get_shard_by_hash(hash).lock(); + let value = value.into_pointer(); + shard.raw_entry().from_hash(hash, |entry| entry.into_pointer() == value).is_some() + } +} + #[inline] fn make_hash(val: &K) -> u64 { let mut state = FxHasher::default(); From b21c9dddb061faf2d0de0c05aa2c26ad295b470e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 2 Jan 2020 01:26:18 +0100 Subject: [PATCH 013/169] Use Arena for interning --- src/librustc/arena.rs | 5 ++++- src/librustc/ty/context.rs | 20 ++++---------------- src/librustc/ty/mod.rs | 10 ++++++---- src/librustc_interface/passes.rs | 4 +--- src/librustc_interface/queries.rs | 5 +---- 5 files changed, 16 insertions(+), 28 deletions(-) diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs index cb3fdff53a3b0..15e92d8d84219 100644 --- a/src/librustc/arena.rs +++ b/src/librustc/arena.rs @@ -123,6 +123,9 @@ macro_rules! arena_types { [few] inferred_outlives_crate: rustc::ty::CratePredicatesMap<'tcx>, [] upvars: rustc_data_structures::fx::FxIndexMap, + // Interned types + [] tys: rustc::ty::TyS<$tcx>, + // HIR types [few] hir_forest: rustc::hir::map::Forest<$tcx>, [] arm: rustc_hir::Arm<$tcx>, @@ -176,7 +179,7 @@ macro_rules! declare_arena { ([], [$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) => { #[derive(Default)] pub struct Arena<$tcx> { - dropless: DroplessArena, + pub dropless: DroplessArena, drop: DropArena, $($name: arena_for_type!($a[$ty]),)* } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 0c00f06b7b3f5..908fd9a529401 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -50,7 +50,6 @@ use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, DefIndex, LOCAL_CRA use rustc_hir::{HirId, Node, TraitCandidate}; use rustc_hir::{ItemKind, ItemLocalId, ItemLocalMap, ItemLocalSet}; -use arena::SyncDroplessArena; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::profiling::SelfProfilerRef; use rustc_data_structures::sharded::{IntoPointer, ShardedHashMap}; @@ -81,21 +80,11 @@ use syntax::ast; use syntax::attr; use syntax::expand::allocator::AllocatorKind; -pub struct AllArenas { - pub interner: SyncDroplessArena, -} - -impl AllArenas { - pub fn new() -> Self { - AllArenas { interner: SyncDroplessArena::default() } - } -} - type InternedSet<'tcx, T> = ShardedHashMap, ()>; pub struct CtxtInterners<'tcx> { /// The arena that types, regions, etc. are allocated from. - arena: &'tcx SyncDroplessArena, + arena: &'tcx WorkerLocal>, /// Specifically use a speedy hash algorithm for these hash sets, since /// they're accessed quite often. @@ -115,7 +104,7 @@ pub struct CtxtInterners<'tcx> { } impl<'tcx> CtxtInterners<'tcx> { - fn new(arena: &'tcx SyncDroplessArena) -> CtxtInterners<'tcx> { + fn new(arena: &'tcx WorkerLocal>) -> CtxtInterners<'tcx> { CtxtInterners { arena, type_: Default::default(), @@ -1118,7 +1107,6 @@ impl<'tcx> TyCtxt<'tcx> { lint_store: Lrc, local_providers: ty::query::Providers<'tcx>, extern_providers: ty::query::Providers<'tcx>, - arenas: &'tcx AllArenas, arena: &'tcx WorkerLocal>, resolutions: ty::ResolverOutputs, hir: hir_map::Map<'tcx>, @@ -1129,7 +1117,7 @@ impl<'tcx> TyCtxt<'tcx> { let data_layout = TargetDataLayout::parse(&s.target.target).unwrap_or_else(|err| { s.fatal(&err); }); - let interners = CtxtInterners::new(&arenas.interner); + let interners = CtxtInterners::new(arena); let common_types = CommonTypes::new(&interners); let common_lifetimes = CommonLifetimes::new(&interners); let common_consts = CommonConsts::new(&interners, &common_types); @@ -2087,7 +2075,7 @@ macro_rules! slice_interners { $(impl<'tcx> TyCtxt<'tcx> { pub fn $method(self, v: &[$ty]) -> &'tcx List<$ty> { self.interners.$field.intern_ref(v, || { - Interned(List::from_arena(&self.interners.arena, v)) + Interned(List::from_arena(&*self.arena, v)) }).0 } })+ diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index d1e37a4ea1151..78b00f259aa64 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -6,6 +6,7 @@ pub use self::BorrowKind::*; pub use self::IntVarValue::*; pub use self::Variance::*; +use crate::arena::Arena; use crate::hir::exports::ExportMap; use crate::hir::map as hir_map; @@ -26,7 +27,6 @@ use crate::ty::layout::VariantIdx; use crate::ty::subst::{InternalSubsts, Subst, SubstsRef}; use crate::ty::util::{Discr, IntTypeExt}; use crate::ty::walk::TypeWalker; -use arena::SyncDroplessArena; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxIndexMap; @@ -76,7 +76,7 @@ pub use crate::ty::diagnostics::*; pub use self::binding::BindingMode; pub use self::binding::BindingMode::*; -pub use self::context::{keep_local, tls, AllArenas, FreeRegionInfo, TyCtxt}; +pub use self::context::{keep_local, tls, FreeRegionInfo, TyCtxt}; pub use self::context::{ CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, ResolvedOpaqueTy, UserType, UserTypeAnnotationIndex, @@ -606,7 +606,7 @@ unsafe impl Sync for List {} impl List { #[inline] - fn from_arena<'tcx>(arena: &'tcx SyncDroplessArena, slice: &[T]) -> &'tcx List { + fn from_arena<'tcx>(arena: &'tcx Arena<'tcx>, slice: &[T]) -> &'tcx List { assert!(!mem::needs_drop::()); assert!(mem::size_of::() != 0); assert!(slice.len() != 0); @@ -619,7 +619,9 @@ impl List { let size = offset + slice.len() * mem::size_of::(); - let mem = arena.alloc_raw(size, cmp::max(mem::align_of::(), mem::align_of::())); + let mem = arena + .dropless + .alloc_raw(size, cmp::max(mem::align_of::(), mem::align_of::())); unsafe { let result = &mut *(mem.as_mut_ptr() as *mut List); // Write the length diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 9119466cbc048..5567d5bf201a0 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -15,7 +15,7 @@ use rustc::session::search_paths::PathKind; use rustc::session::Session; use rustc::traits; use rustc::ty::steal::Steal; -use rustc::ty::{self, AllArenas, GlobalCtxt, ResolverOutputs, TyCtxt}; +use rustc::ty::{self, GlobalCtxt, ResolverOutputs, TyCtxt}; use rustc::util::common::ErrorReported; use rustc_builtin_macros; use rustc_codegen_ssa::back::link::emit_metadata; @@ -711,7 +711,6 @@ pub fn create_global_ctxt<'tcx>( outputs: OutputFilenames, crate_name: &str, global_ctxt: &'tcx Once>, - all_arenas: &'tcx AllArenas, arena: &'tcx WorkerLocal>, ) -> QueryContext<'tcx> { let sess = &compiler.session(); @@ -742,7 +741,6 @@ pub fn create_global_ctxt<'tcx>( lint_store, local_providers, extern_providers, - &all_arenas, arena, resolver_outputs, hir_map, diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index 7de1c36ce4b2e..f0d0297d11a1e 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -9,7 +9,7 @@ use rustc::lint::LintStore; use rustc::session::config::{OutputFilenames, OutputType}; use rustc::session::Session; use rustc::ty::steal::Steal; -use rustc::ty::{AllArenas, GlobalCtxt, ResolverOutputs}; +use rustc::ty::{GlobalCtxt, ResolverOutputs}; use rustc::util::common::ErrorReported; use rustc_codegen_utils::codegen_backend::CodegenBackend; use rustc_data_structures::sync::{Lrc, Once, WorkerLocal}; @@ -67,7 +67,6 @@ pub struct Queries<'tcx> { compiler: &'tcx Compiler, gcx: Once>, - all_arenas: AllArenas, arena: WorkerLocal>, dep_graph_future: Query>, @@ -87,7 +86,6 @@ impl<'tcx> Queries<'tcx> { Queries { compiler, gcx: Once::new(), - all_arenas: AllArenas::new(), arena: WorkerLocal::new(|_| Arena::default()), dep_graph_future: Default::default(), parse: Default::default(), @@ -266,7 +264,6 @@ impl<'tcx> Queries<'tcx> { outputs, &crate_name, &self.gcx, - &self.all_arenas, &self.arena, )) }) From f4968c8e00daed7cc4e5658a7abe61557abd4570 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 2 Jan 2020 01:28:59 +0100 Subject: [PATCH 014/169] Remove SyncTypedArena, SyncDroplessArena and in_arena --- src/libarena/lib.rs | 73 --------------------------------------------- 1 file changed, 73 deletions(-) diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index beb0bac17d2ea..2a3d92edc4956 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -21,7 +21,6 @@ extern crate alloc; use rustc_data_structures::cold_path; -use rustc_data_structures::sync::MTLock; use smallvec::SmallVec; use std::cell::{Cell, RefCell}; @@ -116,11 +115,6 @@ impl Default for TypedArena { } impl TypedArena { - pub fn in_arena(&self, ptr: *const T) -> bool { - let ptr = ptr as *const T as *mut T; - - self.chunks.borrow().iter().any(|chunk| chunk.start() <= ptr && ptr < chunk.end()) - } /// Allocates an object in the `TypedArena`, returning a reference to it. #[inline] pub fn alloc(&self, object: T) -> &mut T { @@ -334,12 +328,6 @@ impl Default for DroplessArena { } impl DroplessArena { - pub fn in_arena(&self, ptr: *const T) -> bool { - let ptr = ptr as *const u8 as *mut u8; - - self.chunks.borrow().iter().any(|chunk| chunk.start() <= ptr && ptr < chunk.end()) - } - #[inline] fn align(&self, align: usize) { let final_address = ((self.ptr.get() as usize) + align - 1) & !(align - 1); @@ -500,66 +488,5 @@ impl DroplessArena { } } -#[derive(Default)] -// FIXME(@Zoxc): this type is entirely unused in rustc -pub struct SyncTypedArena { - lock: MTLock>, -} - -impl SyncTypedArena { - #[inline(always)] - pub fn alloc(&self, object: T) -> &mut T { - // Extend the lifetime of the result since it's limited to the lock guard - unsafe { &mut *(self.lock.lock().alloc(object) as *mut T) } - } - - #[inline(always)] - pub fn alloc_slice(&self, slice: &[T]) -> &mut [T] - where - T: Copy, - { - // Extend the lifetime of the result since it's limited to the lock guard - unsafe { &mut *(self.lock.lock().alloc_slice(slice) as *mut [T]) } - } - - #[inline(always)] - pub fn clear(&mut self) { - self.lock.get_mut().clear(); - } -} - -#[derive(Default)] -pub struct SyncDroplessArena { - lock: MTLock, -} - -impl SyncDroplessArena { - #[inline(always)] - pub fn in_arena(&self, ptr: *const T) -> bool { - self.lock.lock().in_arena(ptr) - } - - #[inline(always)] - pub fn alloc_raw(&self, bytes: usize, align: usize) -> &mut [u8] { - // Extend the lifetime of the result since it's limited to the lock guard - unsafe { &mut *(self.lock.lock().alloc_raw(bytes, align) as *mut [u8]) } - } - - #[inline(always)] - pub fn alloc(&self, object: T) -> &mut T { - // Extend the lifetime of the result since it's limited to the lock guard - unsafe { &mut *(self.lock.lock().alloc(object) as *mut T) } - } - - #[inline(always)] - pub fn alloc_slice(&self, slice: &[T]) -> &mut [T] - where - T: Copy, - { - // Extend the lifetime of the result since it's limited to the lock guard - unsafe { &mut *(self.lock.lock().alloc_slice(slice) as *mut [T]) } - } -} - #[cfg(test)] mod tests; From 6d5170c960d1cf0ad1137bbf65e4d1c992cc21fe Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 1 Jan 2020 19:10:11 +0100 Subject: [PATCH 015/169] Move some queries from rustc::ty to librustc_passes. --- src/librustc/ty/mod.rs | 356 +---------------------------------- src/librustc_passes/lib.rs | 3 + src/librustc_passes/ty.rs | 369 +++++++++++++++++++++++++++++++++++++ 3 files changed, 374 insertions(+), 354 deletions(-) create mode 100644 src/librustc_passes/ty.rs diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index d1e37a4ea1151..e6acb6b74dc63 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -18,7 +18,6 @@ use crate::middle::resolve_lifetime::ObjectLifetimeDefault; use crate::mir::interpret::ErrorHandled; use crate::mir::GeneratorLayout; use crate::mir::ReadOnlyBodyAndCache; -use crate::session::CrateDisambiguator; use crate::session::DataTypeKind; use crate::traits::{self, Reveal}; use crate::ty; @@ -31,7 +30,6 @@ use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_data_structures::svh::Svh; use rustc_data_structures::sync::{self, par_iter, Lrc, ParallelIterator}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; @@ -2423,70 +2421,6 @@ impl<'tcx> AdtDef { pub fn sized_constraint(&self, tcx: TyCtxt<'tcx>) -> &'tcx [Ty<'tcx>] { tcx.adt_sized_constraint(self.did).0 } - - fn sized_constraint_for_ty(&self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Vec> { - let result = match ty.kind { - Bool | Char | Int(..) | Uint(..) | Float(..) | RawPtr(..) | Ref(..) | FnDef(..) - | FnPtr(_) | Array(..) | Closure(..) | Generator(..) | Never => vec![], - - Str | Dynamic(..) | Slice(_) | Foreign(..) | Error | GeneratorWitness(..) => { - // these are never sized - return the target type - vec![ty] - } - - Tuple(ref tys) => match tys.last() { - None => vec![], - Some(ty) => self.sized_constraint_for_ty(tcx, ty.expect_ty()), - }, - - Adt(adt, substs) => { - // recursive case - let adt_tys = adt.sized_constraint(tcx); - debug!("sized_constraint_for_ty({:?}) intermediate = {:?}", ty, adt_tys); - adt_tys - .iter() - .map(|ty| ty.subst(tcx, substs)) - .flat_map(|ty| self.sized_constraint_for_ty(tcx, ty)) - .collect() - } - - Projection(..) | Opaque(..) => { - // must calculate explicitly. - // FIXME: consider special-casing always-Sized projections - vec![ty] - } - - UnnormalizedProjection(..) => bug!("only used with chalk-engine"), - - Param(..) => { - // perf hack: if there is a `T: Sized` bound, then - // we know that `T` is Sized and do not need to check - // it on the impl. - - let sized_trait = match tcx.lang_items().sized_trait() { - Some(x) => x, - _ => return vec![ty], - }; - let sized_predicate = Binder::dummy(TraitRef { - def_id: sized_trait, - substs: tcx.mk_substs_trait(ty, &[]), - }) - .to_predicate(); - let predicates = tcx.predicates_of(self.did).predicates; - if predicates.iter().any(|(p, _)| *p == sized_predicate) { - vec![] - } else { - vec![ty] - } - } - - Placeholder(..) | Bound(..) | Infer(..) => { - bug!("unexpected type `{:?}` in sized_constraint_for_ty", ty) - } - }; - debug!("sized_constraint_for_ty({:?}) = {:?}", ty, result); - result - } } impl<'tcx> FieldDef { @@ -2742,57 +2676,6 @@ impl<'tcx> TyCtxt<'tcx> { is_associated_item.then(|| self.associated_item(def_id)) } - fn associated_item_from_trait_item_ref( - self, - parent_def_id: DefId, - parent_vis: &hir::Visibility<'_>, - trait_item_ref: &hir::TraitItemRef, - ) -> AssocItem { - let def_id = self.hir().local_def_id(trait_item_ref.id.hir_id); - let (kind, has_self) = match trait_item_ref.kind { - hir::AssocItemKind::Const => (ty::AssocKind::Const, false), - hir::AssocItemKind::Method { has_self } => (ty::AssocKind::Method, has_self), - hir::AssocItemKind::Type => (ty::AssocKind::Type, false), - hir::AssocItemKind::OpaqueTy => bug!("only impls can have opaque types"), - }; - - AssocItem { - ident: trait_item_ref.ident, - kind, - // Visibility of trait items is inherited from their traits. - vis: Visibility::from_hir(parent_vis, trait_item_ref.id.hir_id, self), - defaultness: trait_item_ref.defaultness, - def_id, - container: TraitContainer(parent_def_id), - method_has_self_argument: has_self, - } - } - - fn associated_item_from_impl_item_ref( - self, - parent_def_id: DefId, - impl_item_ref: &hir::ImplItemRef<'_>, - ) -> AssocItem { - let def_id = self.hir().local_def_id(impl_item_ref.id.hir_id); - let (kind, has_self) = match impl_item_ref.kind { - hir::AssocItemKind::Const => (ty::AssocKind::Const, false), - hir::AssocItemKind::Method { has_self } => (ty::AssocKind::Method, has_self), - hir::AssocItemKind::Type => (ty::AssocKind::Type, false), - hir::AssocItemKind::OpaqueTy => (ty::AssocKind::OpaqueTy, false), - }; - - AssocItem { - ident: impl_item_ref.ident, - kind, - // Visibility of trait impl items doesn't matter. - vis: ty::Visibility::from_hir(&impl_item_ref.vis, impl_item_ref.id.hir_id, self), - defaultness: impl_item_ref.defaultness, - def_id, - container: ImplContainer(parent_def_id), - method_has_self_argument: has_self, - } - } - pub fn field_index(self, hir_id: hir::HirId, tables: &TypeckTables<'_>) -> usize { tables.field_indices().get(hir_id).cloned().expect("no index for a field") } @@ -3070,105 +2953,9 @@ impl Iterator for AssocItemsIterator<'_> { } } -fn associated_item(tcx: TyCtxt<'_>, def_id: DefId) -> AssocItem { - let id = tcx.hir().as_local_hir_id(def_id).unwrap(); - let parent_id = tcx.hir().get_parent_item(id); - let parent_def_id = tcx.hir().local_def_id(parent_id); - let parent_item = tcx.hir().expect_item(parent_id); - match parent_item.kind { - hir::ItemKind::Impl(.., ref impl_item_refs) => { - if let Some(impl_item_ref) = impl_item_refs.iter().find(|i| i.id.hir_id == id) { - let assoc_item = - tcx.associated_item_from_impl_item_ref(parent_def_id, impl_item_ref); - debug_assert_eq!(assoc_item.def_id, def_id); - return assoc_item; - } - } - - hir::ItemKind::Trait(.., ref trait_item_refs) => { - if let Some(trait_item_ref) = trait_item_refs.iter().find(|i| i.id.hir_id == id) { - let assoc_item = tcx.associated_item_from_trait_item_ref( - parent_def_id, - &parent_item.vis, - trait_item_ref, - ); - debug_assert_eq!(assoc_item.def_id, def_id); - return assoc_item; - } - } - - _ => {} - } - - span_bug!( - parent_item.span, - "unexpected parent of trait or impl item or item not found: {:?}", - parent_item.kind - ) -} - #[derive(Clone, HashStable)] pub struct AdtSizedConstraint<'tcx>(pub &'tcx [Ty<'tcx>]); -/// Calculates the `Sized` constraint. -/// -/// In fact, there are only a few options for the types in the constraint: -/// - an obviously-unsized type -/// - a type parameter or projection whose Sizedness can't be known -/// - a tuple of type parameters or projections, if there are multiple -/// such. -/// - a Error, if a type contained itself. The representability -/// check should catch this case. -fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> AdtSizedConstraint<'_> { - let def = tcx.adt_def(def_id); - - let result = tcx.mk_type_list( - def.variants - .iter() - .flat_map(|v| v.fields.last()) - .flat_map(|f| def.sized_constraint_for_ty(tcx, tcx.type_of(f.did))), - ); - - debug!("adt_sized_constraint: {:?} => {:?}", def, result); - - AdtSizedConstraint(result) -} - -fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: DefId) -> &[DefId] { - let id = tcx.hir().as_local_hir_id(def_id).unwrap(); - let item = tcx.hir().expect_item(id); - match item.kind { - hir::ItemKind::Trait(.., ref trait_item_refs) => tcx.arena.alloc_from_iter( - trait_item_refs - .iter() - .map(|trait_item_ref| trait_item_ref.id) - .map(|id| tcx.hir().local_def_id(id.hir_id)), - ), - hir::ItemKind::Impl(.., ref impl_item_refs) => tcx.arena.alloc_from_iter( - impl_item_refs - .iter() - .map(|impl_item_ref| impl_item_ref.id) - .map(|id| tcx.hir().local_def_id(id.hir_id)), - ), - hir::ItemKind::TraitAlias(..) => &[], - _ => span_bug!(item.span, "associated_item_def_ids: not impl or trait"), - } -} - -fn def_span(tcx: TyCtxt<'_>, def_id: DefId) -> Span { - tcx.hir().span_if_local(def_id).unwrap() -} - -/// If the given `DefId` describes an item belonging to a trait, -/// returns the `DefId` of the trait that the trait item belongs to; -/// otherwise, returns `None`. -fn trait_of_item(tcx: TyCtxt<'_>, def_id: DefId) -> Option { - tcx.opt_associated_item(def_id).and_then(|associated_item| match associated_item.container { - TraitContainer(def_id) => Some(def_id), - ImplContainer(_) => None, - }) -} - /// Yields the parent function's `DefId` if `def_id` is an `impl Trait` definition. pub fn is_impl_trait_defn(tcx: TyCtxt<'_>, def_id: DefId) -> Option { if let Some(hir_id) = tcx.hir().as_local_hir_id(def_id) { @@ -3181,151 +2968,12 @@ pub fn is_impl_trait_defn(tcx: TyCtxt<'_>, def_id: DefId) -> Option { None } -/// See `ParamEnv` struct definition for details. -fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ParamEnv<'_> { - // The param_env of an impl Trait type is its defining function's param_env - if let Some(parent) = is_impl_trait_defn(tcx, def_id) { - return param_env(tcx, parent); - } - // Compute the bounds on Self and the type parameters. - - let InstantiatedPredicates { predicates } = tcx.predicates_of(def_id).instantiate_identity(tcx); - - // Finally, we have to normalize the bounds in the environment, in - // case they contain any associated type projections. This process - // can yield errors if the put in illegal associated types, like - // `::Bar` where `i32` does not implement `Foo`. We - // report these errors right here; this doesn't actually feel - // right to me, because constructing the environment feels like a - // kind of a "idempotent" action, but I'm not sure where would be - // a better place. In practice, we construct environments for - // every fn once during type checking, and we'll abort if there - // are any errors at that point, so after type checking you can be - // sure that this will succeed without errors anyway. - - let unnormalized_env = ty::ParamEnv::new( - tcx.intern_predicates(&predicates), - traits::Reveal::UserFacing, - tcx.sess.opts.debugging_opts.chalk.then_some(def_id), - ); - - let body_id = tcx.hir().as_local_hir_id(def_id).map_or(hir::DUMMY_HIR_ID, |id| { - tcx.hir().maybe_body_owned_by(id).map_or(id, |body| body.hir_id) - }); - let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id); - traits::normalize_param_env_or_error(tcx, def_id, unnormalized_env, cause) -} - -fn crate_disambiguator(tcx: TyCtxt<'_>, crate_num: CrateNum) -> CrateDisambiguator { - assert_eq!(crate_num, LOCAL_CRATE); - tcx.sess.local_crate_disambiguator() -} - -fn original_crate_name(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Symbol { - assert_eq!(crate_num, LOCAL_CRATE); - tcx.crate_name.clone() -} - -fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh { - assert_eq!(crate_num, LOCAL_CRATE); - tcx.hir().crate_hash -} - -fn instance_def_size_estimate<'tcx>(tcx: TyCtxt<'tcx>, instance_def: InstanceDef<'tcx>) -> usize { - match instance_def { - InstanceDef::Item(..) | InstanceDef::DropGlue(..) => { - let mir = tcx.instance_mir(instance_def); - mir.basic_blocks().iter().map(|bb| bb.statements.len()).sum() - } - // Estimate the size of other compiler-generated shims to be 1. - _ => 1, - } -} - -/// If `def_id` is an issue 33140 hack impl, returns its self type; otherwise, returns `None`. -/// -/// See [`ImplOverlapKind::Issue33140`] for more details. -fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option> { - debug!("issue33140_self_ty({:?})", def_id); - - let trait_ref = tcx - .impl_trait_ref(def_id) - .unwrap_or_else(|| bug!("issue33140_self_ty called on inherent impl {:?}", def_id)); - - debug!("issue33140_self_ty({:?}), trait-ref={:?}", def_id, trait_ref); - - let is_marker_like = tcx.impl_polarity(def_id) == ty::ImplPolarity::Positive - && tcx.associated_item_def_ids(trait_ref.def_id).is_empty(); - - // Check whether these impls would be ok for a marker trait. - if !is_marker_like { - debug!("issue33140_self_ty - not marker-like!"); - return None; - } - - // impl must be `impl Trait for dyn Marker1 + Marker2 + ...` - if trait_ref.substs.len() != 1 { - debug!("issue33140_self_ty - impl has substs!"); - return None; - } - - let predicates = tcx.predicates_of(def_id); - if predicates.parent.is_some() || !predicates.predicates.is_empty() { - debug!("issue33140_self_ty - impl has predicates {:?}!", predicates); - return None; - } - - let self_ty = trait_ref.self_ty(); - let self_ty_matches = match self_ty.kind { - ty::Dynamic(ref data, ty::ReStatic) => data.principal().is_none(), - _ => false, - }; - - if self_ty_matches { - debug!("issue33140_self_ty - MATCHES!"); - Some(self_ty) - } else { - debug!("issue33140_self_ty - non-matching self type"); - None - } -} - -/// Check if a function is async. -fn asyncness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::IsAsync { - let hir_id = tcx - .hir() - .as_local_hir_id(def_id) - .unwrap_or_else(|| bug!("asyncness: expected local `DefId`, got `{:?}`", def_id)); - - let node = tcx.hir().get(hir_id); - - let fn_like = hir_map::blocks::FnLikeNode::from_node(node).unwrap_or_else(|| { - bug!("asyncness: expected fn-like node but got `{:?}`", def_id); - }); - - fn_like.asyncness() -} - pub fn provide(providers: &mut ty::query::Providers<'_>) { context::provide(providers); erase_regions::provide(providers); layout::provide(providers); - *providers = ty::query::Providers { - asyncness, - associated_item, - associated_item_def_ids, - adt_sized_constraint, - def_span, - param_env, - trait_of_item, - crate_disambiguator, - original_crate_name, - crate_hash, - trait_impls_of: trait_def::trait_impls_of_provider, - instance_def_size_estimate, - issue33140_self_ty, - ..*providers - }; + *providers = + ty::query::Providers { trait_impls_of: trait_def::trait_impls_of_provider, ..*providers }; } /// A map for the local crate mapping each type to a vector of its diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs index 65eb07b989d83..8bd06465628fa 100644 --- a/src/librustc_passes/lib.rs +++ b/src/librustc_passes/lib.rs @@ -5,6 +5,7 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] +#![feature(bool_to_option)] #![feature(in_band_lifetimes)] #![feature(nll)] #![feature(slice_patterns)] @@ -30,6 +31,7 @@ pub mod loops; mod reachable; mod region; pub mod stability; +mod ty; pub fn provide(providers: &mut Providers<'_>) { check_const::provide(providers); @@ -42,4 +44,5 @@ pub fn provide(providers: &mut Providers<'_>) { reachable::provide(providers); region::provide(providers); stability::provide(providers); + ty::provide(providers); } diff --git a/src/librustc_passes/ty.rs b/src/librustc_passes/ty.rs new file mode 100644 index 0000000000000..fc8beb67e4ada --- /dev/null +++ b/src/librustc_passes/ty.rs @@ -0,0 +1,369 @@ +use rustc::hir::map as hir_map; +use rustc::session::CrateDisambiguator; +use rustc::traits::{self}; +use rustc::ty::subst::Subst; +use rustc::ty::{self, ToPredicate, Ty, TyCtxt}; +use rustc_data_structures::svh::Svh; +use rustc_hir as hir; +use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; +use rustc_span::symbol::Symbol; +use rustc_span::Span; + +fn sized_constraint_for_ty(tcx: TyCtxt<'tcx>, adtdef: &ty::AdtDef, ty: Ty<'tcx>) -> Vec> { + use ty::TyKind::*; + + let result = match ty.kind { + Bool | Char | Int(..) | Uint(..) | Float(..) | RawPtr(..) | Ref(..) | FnDef(..) + | FnPtr(_) | Array(..) | Closure(..) | Generator(..) | Never => vec![], + + Str | Dynamic(..) | Slice(_) | Foreign(..) | Error | GeneratorWitness(..) => { + // these are never sized - return the target type + vec![ty] + } + + Tuple(ref tys) => match tys.last() { + None => vec![], + Some(ty) => sized_constraint_for_ty(tcx, adtdef, ty.expect_ty()), + }, + + Adt(adt, substs) => { + // recursive case + let adt_tys = adt.sized_constraint(tcx); + debug!("sized_constraint_for_ty({:?}) intermediate = {:?}", ty, adt_tys); + adt_tys + .iter() + .map(|ty| ty.subst(tcx, substs)) + .flat_map(|ty| sized_constraint_for_ty(tcx, adtdef, ty)) + .collect() + } + + Projection(..) | Opaque(..) => { + // must calculate explicitly. + // FIXME: consider special-casing always-Sized projections + vec![ty] + } + + UnnormalizedProjection(..) => bug!("only used with chalk-engine"), + + Param(..) => { + // perf hack: if there is a `T: Sized` bound, then + // we know that `T` is Sized and do not need to check + // it on the impl. + + let sized_trait = match tcx.lang_items().sized_trait() { + Some(x) => x, + _ => return vec![ty], + }; + let sized_predicate = ty::Binder::dummy(ty::TraitRef { + def_id: sized_trait, + substs: tcx.mk_substs_trait(ty, &[]), + }) + .to_predicate(); + let predicates = tcx.predicates_of(adtdef.did).predicates; + if predicates.iter().any(|(p, _)| *p == sized_predicate) { vec![] } else { vec![ty] } + } + + Placeholder(..) | Bound(..) | Infer(..) => { + bug!("unexpected type `{:?}` in sized_constraint_for_ty", ty) + } + }; + debug!("sized_constraint_for_ty({:?}) = {:?}", ty, result); + result +} + +fn associated_item_from_trait_item_ref( + tcx: TyCtxt<'_>, + parent_def_id: DefId, + parent_vis: &hir::Visibility<'_>, + trait_item_ref: &hir::TraitItemRef, +) -> ty::AssocItem { + let def_id = tcx.hir().local_def_id(trait_item_ref.id.hir_id); + let (kind, has_self) = match trait_item_ref.kind { + hir::AssocItemKind::Const => (ty::AssocKind::Const, false), + hir::AssocItemKind::Method { has_self } => (ty::AssocKind::Method, has_self), + hir::AssocItemKind::Type => (ty::AssocKind::Type, false), + hir::AssocItemKind::OpaqueTy => bug!("only impls can have opaque types"), + }; + + ty::AssocItem { + ident: trait_item_ref.ident, + kind, + // Visibility of trait items is inherited from their traits. + vis: ty::Visibility::from_hir(parent_vis, trait_item_ref.id.hir_id, tcx), + defaultness: trait_item_ref.defaultness, + def_id, + container: ty::TraitContainer(parent_def_id), + method_has_self_argument: has_self, + } +} + +fn associated_item_from_impl_item_ref( + tcx: TyCtxt<'_>, + parent_def_id: DefId, + impl_item_ref: &hir::ImplItemRef<'_>, +) -> ty::AssocItem { + let def_id = tcx.hir().local_def_id(impl_item_ref.id.hir_id); + let (kind, has_self) = match impl_item_ref.kind { + hir::AssocItemKind::Const => (ty::AssocKind::Const, false), + hir::AssocItemKind::Method { has_self } => (ty::AssocKind::Method, has_self), + hir::AssocItemKind::Type => (ty::AssocKind::Type, false), + hir::AssocItemKind::OpaqueTy => (ty::AssocKind::OpaqueTy, false), + }; + + ty::AssocItem { + ident: impl_item_ref.ident, + kind, + // Visibility of trait impl items doesn't matter. + vis: ty::Visibility::from_hir(&impl_item_ref.vis, impl_item_ref.id.hir_id, tcx), + defaultness: impl_item_ref.defaultness, + def_id, + container: ty::ImplContainer(parent_def_id), + method_has_self_argument: has_self, + } +} + +fn associated_item(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AssocItem { + let id = tcx.hir().as_local_hir_id(def_id).unwrap(); + let parent_id = tcx.hir().get_parent_item(id); + let parent_def_id = tcx.hir().local_def_id(parent_id); + let parent_item = tcx.hir().expect_item(parent_id); + match parent_item.kind { + hir::ItemKind::Impl(.., ref impl_item_refs) => { + if let Some(impl_item_ref) = impl_item_refs.iter().find(|i| i.id.hir_id == id) { + let assoc_item = + associated_item_from_impl_item_ref(tcx, parent_def_id, impl_item_ref); + debug_assert_eq!(assoc_item.def_id, def_id); + return assoc_item; + } + } + + hir::ItemKind::Trait(.., ref trait_item_refs) => { + if let Some(trait_item_ref) = trait_item_refs.iter().find(|i| i.id.hir_id == id) { + let assoc_item = associated_item_from_trait_item_ref( + tcx, + parent_def_id, + &parent_item.vis, + trait_item_ref, + ); + debug_assert_eq!(assoc_item.def_id, def_id); + return assoc_item; + } + } + + _ => {} + } + + span_bug!( + parent_item.span, + "unexpected parent of trait or impl item or item not found: {:?}", + parent_item.kind + ) +} + +/// Calculates the `Sized` constraint. +/// +/// In fact, there are only a few options for the types in the constraint: +/// - an obviously-unsized type +/// - a type parameter or projection whose Sizedness can't be known +/// - a tuple of type parameters or projections, if there are multiple +/// such. +/// - a Error, if a type contained itself. The representability +/// check should catch this case. +fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AdtSizedConstraint<'_> { + let def = tcx.adt_def(def_id); + + let result = tcx.mk_type_list( + def.variants + .iter() + .flat_map(|v| v.fields.last()) + .flat_map(|f| sized_constraint_for_ty(tcx, def, tcx.type_of(f.did))), + ); + + debug!("adt_sized_constraint: {:?} => {:?}", def, result); + + ty::AdtSizedConstraint(result) +} + +fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: DefId) -> &[DefId] { + let id = tcx.hir().as_local_hir_id(def_id).unwrap(); + let item = tcx.hir().expect_item(id); + match item.kind { + hir::ItemKind::Trait(.., ref trait_item_refs) => tcx.arena.alloc_from_iter( + trait_item_refs + .iter() + .map(|trait_item_ref| trait_item_ref.id) + .map(|id| tcx.hir().local_def_id(id.hir_id)), + ), + hir::ItemKind::Impl(.., ref impl_item_refs) => tcx.arena.alloc_from_iter( + impl_item_refs + .iter() + .map(|impl_item_ref| impl_item_ref.id) + .map(|id| tcx.hir().local_def_id(id.hir_id)), + ), + hir::ItemKind::TraitAlias(..) => &[], + _ => span_bug!(item.span, "associated_item_def_ids: not impl or trait"), + } +} + +fn def_span(tcx: TyCtxt<'_>, def_id: DefId) -> Span { + tcx.hir().span_if_local(def_id).unwrap() +} + +/// If the given `DefId` describes an item belonging to a trait, +/// returns the `DefId` of the trait that the trait item belongs to; +/// otherwise, returns `None`. +fn trait_of_item(tcx: TyCtxt<'_>, def_id: DefId) -> Option { + tcx.opt_associated_item(def_id).and_then(|associated_item| match associated_item.container { + ty::TraitContainer(def_id) => Some(def_id), + ty::ImplContainer(_) => None, + }) +} + +/// See `ParamEnv` struct definition for details. +fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { + // The param_env of an impl Trait type is its defining function's param_env + if let Some(parent) = ty::is_impl_trait_defn(tcx, def_id) { + return param_env(tcx, parent); + } + // Compute the bounds on Self and the type parameters. + + let ty::InstantiatedPredicates { predicates } = + tcx.predicates_of(def_id).instantiate_identity(tcx); + + // Finally, we have to normalize the bounds in the environment, in + // case they contain any associated type projections. This process + // can yield errors if the put in illegal associated types, like + // `::Bar` where `i32` does not implement `Foo`. We + // report these errors right here; this doesn't actually feel + // right to me, because constructing the environment feels like a + // kind of a "idempotent" action, but I'm not sure where would be + // a better place. In practice, we construct environments for + // every fn once during type checking, and we'll abort if there + // are any errors at that point, so after type checking you can be + // sure that this will succeed without errors anyway. + + let unnormalized_env = ty::ParamEnv::new( + tcx.intern_predicates(&predicates), + traits::Reveal::UserFacing, + tcx.sess.opts.debugging_opts.chalk.then_some(def_id), + ); + + let body_id = tcx.hir().as_local_hir_id(def_id).map_or(hir::DUMMY_HIR_ID, |id| { + tcx.hir().maybe_body_owned_by(id).map_or(id, |body| body.hir_id) + }); + let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id); + traits::normalize_param_env_or_error(tcx, def_id, unnormalized_env, cause) +} + +fn crate_disambiguator(tcx: TyCtxt<'_>, crate_num: CrateNum) -> CrateDisambiguator { + assert_eq!(crate_num, LOCAL_CRATE); + tcx.sess.local_crate_disambiguator() +} + +fn original_crate_name(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Symbol { + assert_eq!(crate_num, LOCAL_CRATE); + tcx.crate_name.clone() +} + +fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh { + assert_eq!(crate_num, LOCAL_CRATE); + tcx.hir().crate_hash +} + +fn instance_def_size_estimate<'tcx>( + tcx: TyCtxt<'tcx>, + instance_def: ty::InstanceDef<'tcx>, +) -> usize { + use ty::InstanceDef; + + match instance_def { + InstanceDef::Item(..) | InstanceDef::DropGlue(..) => { + let mir = tcx.instance_mir(instance_def); + mir.basic_blocks().iter().map(|bb| bb.statements.len()).sum() + } + // Estimate the size of other compiler-generated shims to be 1. + _ => 1, + } +} + +/// If `def_id` is an issue 33140 hack impl, returns its self type; otherwise, returns `None`. +/// +/// See [`ImplOverlapKind::Issue33140`] for more details. +fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option> { + debug!("issue33140_self_ty({:?})", def_id); + + let trait_ref = tcx + .impl_trait_ref(def_id) + .unwrap_or_else(|| bug!("issue33140_self_ty called on inherent impl {:?}", def_id)); + + debug!("issue33140_self_ty({:?}), trait-ref={:?}", def_id, trait_ref); + + let is_marker_like = tcx.impl_polarity(def_id) == ty::ImplPolarity::Positive + && tcx.associated_item_def_ids(trait_ref.def_id).is_empty(); + + // Check whether these impls would be ok for a marker trait. + if !is_marker_like { + debug!("issue33140_self_ty - not marker-like!"); + return None; + } + + // impl must be `impl Trait for dyn Marker1 + Marker2 + ...` + if trait_ref.substs.len() != 1 { + debug!("issue33140_self_ty - impl has substs!"); + return None; + } + + let predicates = tcx.predicates_of(def_id); + if predicates.parent.is_some() || !predicates.predicates.is_empty() { + debug!("issue33140_self_ty - impl has predicates {:?}!", predicates); + return None; + } + + let self_ty = trait_ref.self_ty(); + let self_ty_matches = match self_ty.kind { + ty::Dynamic(ref data, ty::ReStatic) => data.principal().is_none(), + _ => false, + }; + + if self_ty_matches { + debug!("issue33140_self_ty - MATCHES!"); + Some(self_ty) + } else { + debug!("issue33140_self_ty - non-matching self type"); + None + } +} + +/// Check if a function is async. +fn asyncness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::IsAsync { + let hir_id = tcx + .hir() + .as_local_hir_id(def_id) + .unwrap_or_else(|| bug!("asyncness: expected local `DefId`, got `{:?}`", def_id)); + + let node = tcx.hir().get(hir_id); + + let fn_like = hir_map::blocks::FnLikeNode::from_node(node).unwrap_or_else(|| { + bug!("asyncness: expected fn-like node but got `{:?}`", def_id); + }); + + fn_like.asyncness() +} + +pub fn provide(providers: &mut ty::query::Providers<'_>) { + *providers = ty::query::Providers { + asyncness, + associated_item, + associated_item_def_ids, + adt_sized_constraint, + def_span, + param_env, + trait_of_item, + crate_disambiguator, + original_crate_name, + crate_hash, + instance_def_size_estimate, + issue33140_self_ty, + ..*providers + }; +} From d59e9b40a3712fa29e59b17cc2a9a10549cae79f Mon Sep 17 00:00:00 2001 From: Charles Lew Date: Sat, 11 Jan 2020 16:56:21 +0800 Subject: [PATCH 016/169] Implement Cursor for linked lists. (RFC 2570). --- src/liballoc/collections/linked_list.rs | 457 +++++++++++++++++- src/liballoc/collections/linked_list/tests.rs | 98 ++++ 2 files changed, 531 insertions(+), 24 deletions(-) diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index 29bf2fdb30cf7..d0ad1ec283942 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -242,6 +242,88 @@ impl LinkedList { self.len -= 1; } + + /// Splices a series of nodes between two existing nodes. + /// + /// Warning: this will not check that the provided node belongs to the two existing lists. + #[inline] + unsafe fn splice_nodes( + &mut self, + existing_prev: Option>>, + existing_next: Option>>, + splice_start: NonNull>, + splice_end: NonNull>, + splice_length: usize, + ) { + // This method takes care not to create multiple mutable references to whole nodes at the same time, + // to maintain validity of aliasing pointers into `element`. + if let Some(mut existing_prev) = existing_prev { + existing_prev.as_mut().next = Some(splice_start); + } else { + self.head = Some(splice_start); + } + if let Some(mut existing_next) = existing_next { + existing_next.as_mut().prev = Some(splice_end); + } else { + self.tail = Some(splice_end); + } + let mut splice_start = splice_start; + splice_start.as_mut().prev = existing_prev; + let mut splice_end = splice_end; + splice_end.as_mut().next = existing_next; + + self.len += splice_length; + } + + /// Detaches all nodes from a linked list as a series of nodes. + #[inline] + fn detach_all_nodes(mut self) -> Option<(NonNull>, NonNull>, usize)> { + let head = self.head.take(); + let tail = self.tail.take(); + let len = mem::replace(&mut self.len, 0); + if let Some(head) = head { + let tail = tail.unwrap_or_else(|| unsafe { core::hint::unreachable_unchecked() }); + Some((head, tail, len)) + } else { + None + } + } + + #[inline] + unsafe fn split_off_after_node( + &mut self, + split_node: Option>>, + at: usize, + ) -> Self { + // The split node is the new tail node of the first part and owns + // the head of the second part. + if let Some(mut split_node) = split_node { + let second_part_head; + let second_part_tail; + second_part_head = split_node.as_mut().next.take(); + if let Some(mut head) = second_part_head { + head.as_mut().prev = None; + second_part_tail = self.tail; + } else { + second_part_tail = None; + } + + let second_part = LinkedList { + head: second_part_head, + tail: second_part_tail, + len: self.len - at, + marker: PhantomData, + }; + + // Fix the tail ptr of the first part + self.tail = Some(split_node); + self.len = at; + + second_part + } else { + mem::replace(self, LinkedList::new()) + } + } } #[stable(feature = "rust1", since = "1.0.0")] @@ -319,6 +401,27 @@ impl LinkedList { } } + /// Moves all elements from `other` to the begin of the list. + #[unstable(feature = "linked_list_prepend", issue = "none")] + pub fn prepend(&mut self, other: &mut Self) { + match self.head { + None => mem::swap(self, other), + Some(mut head) => { + // `as_mut` is okay here because we have exclusive access to the entirety + // of both lists. + if let Some(mut other_tail) = other.tail.take() { + unsafe { + head.as_mut().prev = Some(other_tail); + other_tail.as_mut().next = Some(head); + } + + self.head = other.head.take(); + self.len += mem::replace(&mut other.len, 0); + } + } + } + } + /// Provides a forward iterator. /// /// # Examples @@ -373,6 +476,20 @@ impl LinkedList { IterMut { head: self.head, tail: self.tail, len: self.len, list: self } } + /// Provides a cursor. + #[inline] + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn cursor(&self) -> Cursor<'_, T> { + Cursor { index: 0, current: self.head, list: self } + } + + /// Provides a cursor with editing operations. + #[inline] + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn cursor_mut(&mut self) -> CursorMut<'_, T> { + CursorMut { index: 0, current: self.head, list: self } + } + /// Returns `true` if the `LinkedList` is empty. /// /// This operation should compute in O(1) time. @@ -703,30 +820,7 @@ impl LinkedList { } iter.tail }; - - // The split node is the new tail node of the first part and owns - // the head of the second part. - let second_part_head; - - unsafe { - second_part_head = split_node.unwrap().as_mut().next.take(); - if let Some(mut head) = second_part_head { - head.as_mut().prev = None; - } - } - - let second_part = LinkedList { - head: second_part_head, - tail: self.tail, - len: len - at, - marker: PhantomData, - }; - - // Fix the tail ptr of the first part - self.tail = split_node; - self.len = at; - - second_part + unsafe { self.split_off_after_node(split_node, at) } } /// Creates an iterator which uses a closure to determine if an element should be removed. @@ -986,6 +1080,321 @@ impl IterMut<'_, T> { } } +/// A cursor over a `LinkedList`. +/// +/// A `Cursor` is like an iterator, except that it can freely seek back-and-forth, and can +/// safely mutate the list during iteration. This is because the lifetime of its yielded +/// references is tied to its own lifetime, instead of just the underlying list. This means +/// cursors cannot yield multiple elements at once. +/// +/// Cursors always rest between two elements in the list, and index in a logically circular way. +/// To accommodate this, there is a "ghost" non-element that yields `None` between the head and +/// tail of the list. +/// +/// When created, cursors start at the front of the list, or the ghost element if the list is empty. +#[unstable(feature = "linked_list_cursors", issue = "58533")] +pub struct Cursor<'a, T: 'a> { + index: usize, + current: Option>>, + list: &'a LinkedList, +} + +#[unstable(feature = "linked_list_cursors", issue = "58533")] +impl fmt::Debug for Cursor<'_, T> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("Cursor").field(&self.list).field(&self.index).finish() + } +} + +/// A cursor over a `LinkedList` with editing operations. +/// +/// A `Cursor` is like an iterator, except that it can freely seek back-and-forth, and can +/// safely mutate the list during iteration. This is because the lifetime of its yielded +/// references is tied to its own lifetime, instead of just the underlying list. This means +/// cursors cannot yield multiple elements at once. +/// +/// Cursors always rest between two elements in the list, and index in a logically circular way. +/// To accommodate this, there is a "ghost" non-element that yields `None` between the head and +/// tail of the list. +/// +/// When created, cursors start at the front of the list, or the ghost element if the list is empty. +#[unstable(feature = "linked_list_cursors", issue = "58533")] +pub struct CursorMut<'a, T: 'a> { + index: usize, + current: Option>>, + list: &'a mut LinkedList, +} + +#[unstable(feature = "linked_list_cursors", issue = "58533")] +impl fmt::Debug for CursorMut<'_, T> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("CursorMut").field(&self.list).field(&self.index).finish() + } +} + +impl<'a, T> Cursor<'a, T> { + /// Move to the subsequent element of the list if it exists or the empty + /// element + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn move_next(&mut self) { + match self.current.take() { + // We had no current element; the cursor was sitting at the start position + // Next element should be the head of the list + None => { + self.current = self.list.head; + self.index = 0; + } + // We had a previous element, so let's go to its next + Some(current) => unsafe { + self.current = current.as_ref().next; + self.index += 1; + }, + } + } + + /// Move to the previous element of the list + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn move_prev(&mut self) { + match self.current.take() { + // No current. We're at the start of the list. Yield None and jump to the end. + None => { + self.current = self.list.tail; + self.index = self.list.len().checked_sub(1).unwrap_or(0); + } + // Have a prev. Yield it and go to the previous element. + Some(current) => unsafe { + self.current = current.as_ref().prev; + self.index = self.index.checked_sub(1).unwrap_or_else(|| self.list.len()); + }, + } + } + + /// Get the current element + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn current(&self) -> Option<&'a T> { + unsafe { self.current.map(|current| &(*current.as_ptr()).element) } + } + + /// Get the next element + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn peek_next(&self) -> Option<&'a T> { + unsafe { + let next = match self.current { + None => self.list.head, + Some(current) => current.as_ref().next, + }; + next.map(|next| &(*next.as_ptr()).element) + } + } + + /// Get the previous element + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn peek_prev(&self) -> Option<&'a T> { + unsafe { + let prev = match self.current { + None => self.list.tail, + Some(current) => current.as_ref().prev, + }; + prev.map(|prev| &(*prev.as_ptr()).element) + } + } +} + +impl<'a, T> CursorMut<'a, T> { + /// Move to the subsequent element of the list if it exists or the empty + /// element + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn move_next(&mut self) { + match self.current.take() { + // We had no current element; the cursor was sitting at the start position + // Next element should be the head of the list + None => { + self.current = self.list.head; + self.index = 0; + } + // We had a previous element, so let's go to its next + Some(current) => unsafe { + self.current = current.as_ref().next; + self.index += 1; + }, + } + } + + /// Move to the previous element of the list + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn move_prev(&mut self) { + match self.current.take() { + // No current. We're at the start of the list. Yield None and jump to the end. + None => { + self.current = self.list.tail; + self.index = self.list.len().checked_sub(1).unwrap_or(0); + } + // Have a prev. Yield it and go to the previous element. + Some(current) => unsafe { + self.current = current.as_ref().prev; + self.index = self.index.checked_sub(1).unwrap_or_else(|| self.list.len()); + }, + } + } + + /// Get the current element + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn current(&mut self) -> Option<&mut T> { + unsafe { self.current.map(|current| &mut (*current.as_ptr()).element) } + } + + /// Get the next element + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn peek_next(&mut self) -> Option<&mut T> { + unsafe { + let next = match self.current { + None => self.list.head, + Some(current) => current.as_ref().next, + }; + next.map(|next| &mut (*next.as_ptr()).element) + } + } + + /// Get the previous element + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn peek_prev(&mut self) -> Option<&mut T> { + unsafe { + let prev = match self.current { + None => self.list.tail, + Some(current) => current.as_ref().prev, + }; + prev.map(|prev| &mut (*prev.as_ptr()).element) + } + } + + /// Get an immutable cursor at the current element + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn as_cursor<'cm>(&'cm self) -> Cursor<'cm, T> { + Cursor { list: self.list, current: self.current, index: self.index } + } +} + +// Now the list editing operations + +impl<'a, T> CursorMut<'a, T> { + /// Insert `item` after the cursor + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn insert_after(&mut self, item: T) { + unsafe { + let spliced_node = Box::into_raw_non_null(Box::new(Node::new(item))); + let (node, node_next) = match self.current { + None => (None, self.list.head), + Some(node) => { + let node_next = node.as_ref().next; + (Some(node), node_next) + } + }; + self.list.splice_nodes(node, node_next, spliced_node, spliced_node, 1); + if self.current.is_none() { + // The ghost element's index has increased by 1. + self.index += 1; + } + } + } + + /// Insert `item` before the cursor + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn insert_before(&mut self, item: T) { + unsafe { + let spliced_node = Box::into_raw_non_null(Box::new(Node::new(item))); + let (node_prev, node) = match self.current { + None => (self.list.tail, None), + Some(node) => { + let node_prev = node.as_ref().prev; + (node_prev, Some(node)) + } + }; + self.list.splice_nodes(node_prev, node, spliced_node, spliced_node, 1); + self.index += 1; + } + } + + /// Remove and return the current item, moving the cursor to the next item + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn remove(&mut self) -> Option { + let unlinked_node = self.current?; + unsafe { + self.current = unlinked_node.as_ref().next; + self.list.unlink_node(unlinked_node); + let unlinked_node = Box::from_raw(unlinked_node.as_ptr()); + Some((*unlinked_node).element) + } + } + + /// Insert `list` between the current element and the next + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn splice_after(&mut self, list: LinkedList) { + unsafe { + let (splice_head, splice_tail, splice_len) = match list.detach_all_nodes() { + Some(parts) => parts, + _ => return, + }; + let (node, node_next) = match self.current { + None => (None, self.list.head), + Some(node) => { + let node_next = node.as_ref().next; + (Some(node), node_next) + } + }; + self.list.splice_nodes(node, node_next, splice_head, splice_tail, splice_len); + if self.current.is_none() { + // The ghost element's index has increased by `splice_len`. + self.index += splice_len; + } + } + } + + /// Insert `list` between the previous element and current + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn splice_before(&mut self, list: LinkedList) { + unsafe { + let (splice_head, splice_tail, splice_len) = match list.detach_all_nodes() { + Some(parts) => parts, + _ => return, + }; + let (node_prev, node) = match self.current { + None => (self.list.tail, None), + Some(node) => { + let node_prev = node.as_ref().prev; + (node_prev, Some(node)) + } + }; + self.list.splice_nodes(node_prev, node, splice_head, splice_tail, splice_len); + self.index += splice_len; + } + } + + /// Split the list in two after the current element + /// The returned list consists of all elements following the current one. + // note: consuming the cursor is not necessary here, but it makes sense + // given the interface + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn split_after(self) -> LinkedList { + let split_off_idx = if self.index == self.list.len { 0 } else { self.index + 1 }; + unsafe { + let split_off_node = self.current; + self.list.split_off_after_node(split_off_node, split_off_idx) + } + } + /// Split the list in two before the current element + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn split_before(self) -> LinkedList { + let split_off_idx = self.index; + unsafe { + let split_off_node = match self.current { + Some(node) => node.as_ref().prev, + None => self.list.tail, + }; + self.list.split_off_after_node(split_off_node, split_off_idx) + } + } +} + /// An iterator produced by calling `drain_filter` on LinkedList. #[unstable(feature = "drain_filter", reason = "recently added", issue = "43244")] pub struct DrainFilter<'a, T: 'a, F: 'a> diff --git a/src/liballoc/collections/linked_list/tests.rs b/src/liballoc/collections/linked_list/tests.rs index 1b1d8eab39bfc..51b23e23cd276 100644 --- a/src/liballoc/collections/linked_list/tests.rs +++ b/src/liballoc/collections/linked_list/tests.rs @@ -304,3 +304,101 @@ fn drain_to_empty_test() { assert_eq!(deleted, &[1, 2, 3, 4, 5, 6]); assert_eq!(m.into_iter().collect::>(), &[]); } + +#[test] +fn test_cursor_move_peek() { + let mut m: LinkedList = LinkedList::new(); + m.extend(&[1, 2, 3, 4, 5, 6]); + let mut cursor = m.cursor(); + assert_eq!(cursor.current(), Some(&1)); + assert_eq!(cursor.peek_next(), Some(&2)); + assert_eq!(cursor.peek_prev(), None); + cursor.move_prev(); + assert_eq!(cursor.current(), None); + assert_eq!(cursor.peek_next(), Some(&1)); + assert_eq!(cursor.peek_prev(), Some(&6)); + cursor.move_next(); + cursor.move_next(); + assert_eq!(cursor.current(), Some(&2)); + assert_eq!(cursor.peek_next(), Some(&3)); + assert_eq!(cursor.peek_prev(), Some(&1)); + + let mut m: LinkedList = LinkedList::new(); + m.extend(&[1, 2, 3, 4, 5, 6]); + let mut cursor = m.cursor_mut(); + assert_eq!(cursor.current(), Some(&mut 1)); + assert_eq!(cursor.peek_next(), Some(&mut 2)); + assert_eq!(cursor.peek_prev(), None); + cursor.move_prev(); + assert_eq!(cursor.current(), None); + assert_eq!(cursor.peek_next(), Some(&mut 1)); + assert_eq!(cursor.peek_prev(), Some(&mut 6)); + cursor.move_next(); + cursor.move_next(); + assert_eq!(cursor.current(), Some(&mut 2)); + assert_eq!(cursor.peek_next(), Some(&mut 3)); + assert_eq!(cursor.peek_prev(), Some(&mut 1)); + let mut cursor2 = cursor.as_cursor(); + assert_eq!(cursor2.current(), Some(&2)); + cursor2.move_next(); + assert_eq!(cursor2.current(), Some(&3)); + assert_eq!(cursor.current(), Some(&mut 2)); +} + +#[test] +fn test_cursor_mut_insert() { + let mut m: LinkedList = LinkedList::new(); + m.extend(&[1, 2, 3, 4, 5, 6]); + let mut cursor = m.cursor_mut(); + cursor.insert_before(7); + cursor.insert_after(8); + check_links(&m); + assert_eq!(m.iter().cloned().collect::>(), &[7, 1, 8, 2, 3, 4, 5, 6]); + let mut cursor = m.cursor_mut(); + cursor.move_prev(); + cursor.insert_before(9); + cursor.insert_after(10); + check_links(&m); + assert_eq!(m.iter().cloned().collect::>(), &[10, 7, 1, 8, 2, 3, 4, 5, 6, 9]); + let mut cursor = m.cursor_mut(); + cursor.move_prev(); + assert_eq!(cursor.remove(), None); + cursor.move_next(); + cursor.move_next(); + assert_eq!(cursor.remove(), Some(7)); + cursor.move_prev(); + cursor.move_prev(); + cursor.move_prev(); + assert_eq!(cursor.remove(), Some(9)); + cursor.move_next(); + assert_eq!(cursor.remove(), Some(10)); + check_links(&m); + assert_eq!(m.iter().cloned().collect::>(), &[1, 8, 2, 3, 4, 5, 6]); + let mut cursor = m.cursor_mut(); + let mut p: LinkedList = LinkedList::new(); + p.extend(&[100, 101, 102, 103]); + let mut q: LinkedList = LinkedList::new(); + q.extend(&[200, 201, 202, 203]); + cursor.splice_after(p); + cursor.splice_before(q); + check_links(&m); + assert_eq!( + m.iter().cloned().collect::>(), + &[200, 201, 202, 203, 1, 100, 101, 102, 103, 8, 2, 3, 4, 5, 6] + ); + let mut cursor = m.cursor_mut(); + cursor.move_prev(); + let tmp = cursor.split_before(); + assert_eq!(tmp.into_iter().collect::>(), &[]); + let mut cursor = m.cursor_mut(); + cursor.move_next(); + cursor.move_next(); + cursor.move_next(); + cursor.move_next(); + cursor.move_next(); + cursor.move_next(); + let tmp = cursor.split_after(); + assert_eq!(tmp.into_iter().collect::>(), &[102, 103, 8, 2, 3, 4, 5, 6]); + check_links(&m); + assert_eq!(m.iter().cloned().collect::>(), &[200, 201, 202, 203, 1, 100, 101]); +} From 7b564c67deb6f5e9d7102871d63a9ad3d7161278 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Sat, 4 Jan 2020 16:46:47 -0500 Subject: [PATCH 017/169] use winapi for non-stdlib Windows bindings --- Cargo.lock | 6 ++ src/bootstrap/Cargo.toml | 4 ++ src/bootstrap/job.rs | 88 +++-------------------- src/bootstrap/util.rs | 62 ++++------------ src/librustc/lib.rs | 1 - src/librustc_data_structures/Cargo.toml | 3 + src/librustc_data_structures/flock.rs | 34 +-------- src/librustc_data_structures/lib.rs | 3 - src/librustc_data_structures/profiling.rs | 46 ++++-------- src/librustc_driver/Cargo.toml | 3 + src/librustc_driver/lib.rs | 18 ++--- src/librustc_errors/Cargo.toml | 3 + src/librustc_errors/lock.rs | 27 ++----- src/librustc_interface/Cargo.toml | 3 + src/librustc_interface/util.rs | 14 ++-- src/librustc_metadata/Cargo.toml | 3 + src/librustc_metadata/dynamic_lib.rs | 33 ++++----- src/tools/compiletest/src/runtest.rs | 6 +- 18 files changed, 94 insertions(+), 263 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 54ad60e71506b..0e7f91283cfaa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -201,6 +201,7 @@ dependencies = [ "serde_json", "time", "toml", + "winapi 0.3.8", ] [[package]] @@ -3491,6 +3492,7 @@ dependencies = [ "serialize", "smallvec 1.0.0", "stable_deref_trait", + "winapi 0.3.8", ] [[package]] @@ -3518,6 +3520,7 @@ dependencies = [ "rustc_target", "serialize", "syntax", + "winapi 0.3.8", ] [[package]] @@ -3537,6 +3540,7 @@ dependencies = [ "term_size", "termcolor", "unicode-width", + "winapi 0.3.8", ] [[package]] @@ -3647,6 +3651,7 @@ dependencies = [ "smallvec 1.0.0", "syntax", "tempfile", + "winapi 0.3.8", ] [[package]] @@ -3715,6 +3720,7 @@ dependencies = [ "smallvec 1.0.0", "stable_deref_trait", "syntax", + "winapi 0.3.8", ] [[package]] diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 3ab00a6e147fc..c09f58cc591a6 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -49,5 +49,9 @@ lazy_static = "1.3.0" time = "0.1" ignore = "0.4.10" +[target.'cfg(windows)'.dependencies.winapi] +version = "0.3" +features = ["fileapi", "ioapiset", "jobapi2", "handleapi", "winioctl"] + [dev-dependencies] pretty_assertions = "0.5" diff --git a/src/bootstrap/job.rs b/src/bootstrap/job.rs index 57153e2ad39f4..efeb86540b7b7 100644 --- a/src/bootstrap/job.rs +++ b/src/bootstrap/job.rs @@ -35,84 +35,16 @@ use std::io; use std::mem; use std::ptr; -type HANDLE = *mut u8; -type BOOL = i32; -type DWORD = u32; -type LPHANDLE = *mut HANDLE; -type LPVOID = *mut u8; -type JOBOBJECTINFOCLASS = i32; -type SIZE_T = usize; -type LARGE_INTEGER = i64; -type UINT = u32; -type ULONG_PTR = usize; -type ULONGLONG = u64; - -const FALSE: BOOL = 0; -const DUPLICATE_SAME_ACCESS: DWORD = 0x2; -const PROCESS_DUP_HANDLE: DWORD = 0x40; -const JobObjectExtendedLimitInformation: JOBOBJECTINFOCLASS = 9; -const JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE: DWORD = 0x2000; -const JOB_OBJECT_LIMIT_PRIORITY_CLASS: DWORD = 0x00000020; -const SEM_FAILCRITICALERRORS: UINT = 0x0001; -const SEM_NOGPFAULTERRORBOX: UINT = 0x0002; -const BELOW_NORMAL_PRIORITY_CLASS: DWORD = 0x00004000; - -extern "system" { - fn CreateJobObjectW(lpJobAttributes: *mut u8, lpName: *const u8) -> HANDLE; - fn CloseHandle(hObject: HANDLE) -> BOOL; - fn GetCurrentProcess() -> HANDLE; - fn OpenProcess(dwDesiredAccess: DWORD, bInheritHandle: BOOL, dwProcessId: DWORD) -> HANDLE; - fn DuplicateHandle( - hSourceProcessHandle: HANDLE, - hSourceHandle: HANDLE, - hTargetProcessHandle: HANDLE, - lpTargetHandle: LPHANDLE, - dwDesiredAccess: DWORD, - bInheritHandle: BOOL, - dwOptions: DWORD, - ) -> BOOL; - fn AssignProcessToJobObject(hJob: HANDLE, hProcess: HANDLE) -> BOOL; - fn SetInformationJobObject( - hJob: HANDLE, - JobObjectInformationClass: JOBOBJECTINFOCLASS, - lpJobObjectInformation: LPVOID, - cbJobObjectInformationLength: DWORD, - ) -> BOOL; - fn SetErrorMode(mode: UINT) -> UINT; -} - -#[repr(C)] -struct JOBOBJECT_EXTENDED_LIMIT_INFORMATION { - BasicLimitInformation: JOBOBJECT_BASIC_LIMIT_INFORMATION, - IoInfo: IO_COUNTERS, - ProcessMemoryLimit: SIZE_T, - JobMemoryLimit: SIZE_T, - PeakProcessMemoryUsed: SIZE_T, - PeakJobMemoryUsed: SIZE_T, -} - -#[repr(C)] -struct IO_COUNTERS { - ReadOperationCount: ULONGLONG, - WriteOperationCount: ULONGLONG, - OtherOperationCount: ULONGLONG, - ReadTransferCount: ULONGLONG, - WriteTransferCount: ULONGLONG, - OtherTransferCount: ULONGLONG, -} - -#[repr(C)] -struct JOBOBJECT_BASIC_LIMIT_INFORMATION { - PerProcessUserTimeLimit: LARGE_INTEGER, - PerJobUserTimeLimit: LARGE_INTEGER, - LimitFlags: DWORD, - MinimumWorkingsetSize: SIZE_T, - MaximumWorkingsetSize: SIZE_T, - ActiveProcessLimit: DWORD, - Affinity: ULONG_PTR, - PriorityClass: DWORD, - SchedulingClass: DWORD, -} +use winapi::shared::minwindef::{DWORD, FALSE, LPVOID}; +use winapi::um::errhandlingapi::SetErrorMode; +use winapi::um::handleapi::{CloseHandle, DuplicateHandle}; +use winapi::um::jobapi2::{AssignProcessToJobObject, CreateJobObjectW, SetInformationJobObject}; +use winapi::um::processthreadsapi::{GetCurrentProcess, OpenProcess}; +use winapi::um::winbase::{BELOW_NORMAL_PRIORITY_CLASS, SEM_NOGPFAULTERRORBOX}; +use winapi::um::winnt::{ + JobObjectExtendedLimitInformation, DUPLICATE_SAME_ACCESS, JOBOBJECT_EXTENDED_LIMIT_INFORMATION, + JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE, JOB_OBJECT_LIMIT_PRIORITY_CLASS, PROCESS_DUP_HANDLE, +}; pub unsafe fn setup(build: &mut Build) { // Enable the Windows Error Reporting dialog which msys disables, diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs index 5fd25981851d4..7d1efe4610f9c 100644 --- a/src/bootstrap/util.rs +++ b/src/bootstrap/util.rs @@ -123,37 +123,24 @@ pub fn symlink_dir(config: &Config, src: &Path, dest: &Path) -> io::Result<()> { // what can be found here: // // http://www.flexhex.com/docs/articles/hard-links.phtml - // - // Copied from std #[cfg(windows)] - #[allow(nonstandard_style)] fn symlink_dir_inner(target: &Path, junction: &Path) -> io::Result<()> { use std::ffi::OsStr; use std::os::windows::ffi::OsStrExt; use std::ptr; - const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: usize = 16 * 1024; - const GENERIC_WRITE: DWORD = 0x40000000; - const OPEN_EXISTING: DWORD = 3; - const FILE_FLAG_OPEN_REPARSE_POINT: DWORD = 0x00200000; - const FILE_FLAG_BACKUP_SEMANTICS: DWORD = 0x02000000; - const FSCTL_SET_REPARSE_POINT: DWORD = 0x900a4; - const IO_REPARSE_TAG_MOUNT_POINT: DWORD = 0xa0000003; - const FILE_SHARE_DELETE: DWORD = 0x4; - const FILE_SHARE_READ: DWORD = 0x1; - const FILE_SHARE_WRITE: DWORD = 0x2; - - type BOOL = i32; - type DWORD = u32; - type HANDLE = *mut u8; - type LPCWSTR = *const u16; - type LPDWORD = *mut DWORD; - type LPOVERLAPPED = *mut u8; - type LPSECURITY_ATTRIBUTES = *mut u8; - type LPVOID = *mut u8; - type WCHAR = u16; - type WORD = u16; - + use winapi::shared::minwindef::{DWORD, WORD}; + use winapi::um::fileapi::{CreateFileW, OPEN_EXISTING}; + use winapi::um::handleapi::CloseHandle; + use winapi::um::ioapiset::DeviceIoControl; + use winapi::um::winbase::{FILE_FLAG_BACKUP_SEMANTICS, FILE_FLAG_OPEN_REPARSE_POINT}; + use winapi::um::winioctl::FSCTL_SET_REPARSE_POINT; + use winapi::um::winnt::{ + FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE, GENERIC_WRITE, + IO_REPARSE_TAG_MOUNT_POINT, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, WCHAR, + }; + + #[allow(non_snake_case)] #[repr(C)] struct REPARSE_MOUNTPOINT_DATA_BUFFER { ReparseTag: DWORD, @@ -165,29 +152,6 @@ pub fn symlink_dir(config: &Config, src: &Path, dest: &Path) -> io::Result<()> { ReparseTarget: WCHAR, } - extern "system" { - fn CreateFileW( - lpFileName: LPCWSTR, - dwDesiredAccess: DWORD, - dwShareMode: DWORD, - lpSecurityAttributes: LPSECURITY_ATTRIBUTES, - dwCreationDisposition: DWORD, - dwFlagsAndAttributes: DWORD, - hTemplateFile: HANDLE, - ) -> HANDLE; - fn DeviceIoControl( - hDevice: HANDLE, - dwIoControlCode: DWORD, - lpInBuffer: LPVOID, - nInBufferSize: DWORD, - lpOutBuffer: LPVOID, - nOutBufferSize: DWORD, - lpBytesReturned: LPDWORD, - lpOverlapped: LPOVERLAPPED, - ) -> BOOL; - fn CloseHandle(hObject: HANDLE) -> BOOL; - } - fn to_u16s>(s: S) -> io::Result> { Ok(s.as_ref().encode_wide().chain(Some(0)).collect()) } @@ -212,7 +176,7 @@ pub fn symlink_dir(config: &Config, src: &Path, dest: &Path) -> io::Result<()> { ptr::null_mut(), ); - let mut data = [0u8; MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; + let mut data = [0u8; MAXIMUM_REPARSE_DATA_BUFFER_SIZE as usize]; let db = data.as_mut_ptr() as *mut REPARSE_MOUNTPOINT_DATA_BUFFER; let buf = &mut (*db).ReparseTarget as *mut u16; let mut i = 0; diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index 3c0160a04527e..30372e4af5033 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -34,7 +34,6 @@ #![feature(const_transmute)] #![feature(core_intrinsics)] #![feature(drain_filter)] -#![cfg_attr(windows, feature(libc))] #![feature(never_type)] #![feature(exhaustive_patterns)] #![feature(overlapping_marker_traits)] diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml index 19db9834fd48e..fb4f818c4b249 100644 --- a/src/librustc_data_structures/Cargo.toml +++ b/src/librustc_data_structures/Cargo.toml @@ -31,3 +31,6 @@ measureme = "0.7.1" [dependencies.parking_lot] version = "0.9" features = ["nightly"] + +[target.'cfg(windows)'.dependencies] +winapi = { version = "0.3", features = ["fileapi", "psapi"] } diff --git a/src/librustc_data_structures/flock.rs b/src/librustc_data_structures/flock.rs index e3282c5d276b0..2a0139fa90d5a 100644 --- a/src/librustc_data_structures/flock.rs +++ b/src/librustc_data_structures/flock.rs @@ -87,39 +87,11 @@ cfg_if! { } else if #[cfg(windows)] { use std::mem; use std::os::windows::prelude::*; - use std::os::windows::raw::HANDLE; use std::fs::{File, OpenOptions}; - use std::os::raw::{c_ulong, c_int}; - - type DWORD = c_ulong; - type BOOL = c_int; - type ULONG_PTR = usize; - - type LPOVERLAPPED = *mut OVERLAPPED; - const LOCKFILE_EXCLUSIVE_LOCK: DWORD = 0x0000_0002; - const LOCKFILE_FAIL_IMMEDIATELY: DWORD = 0x0000_0001; - - const FILE_SHARE_DELETE: DWORD = 0x4; - const FILE_SHARE_READ: DWORD = 0x1; - const FILE_SHARE_WRITE: DWORD = 0x2; - - #[repr(C)] - struct OVERLAPPED { - Internal: ULONG_PTR, - InternalHigh: ULONG_PTR, - Offset: DWORD, - OffsetHigh: DWORD, - hEvent: HANDLE, - } - extern "system" { - fn LockFileEx(hFile: HANDLE, - dwFlags: DWORD, - dwReserved: DWORD, - nNumberOfBytesToLockLow: DWORD, - nNumberOfBytesToLockHigh: DWORD, - lpOverlapped: LPOVERLAPPED) -> BOOL; - } + use winapi::um::minwinbase::{OVERLAPPED, LOCKFILE_FAIL_IMMEDIATELY, LOCKFILE_EXCLUSIVE_LOCK}; + use winapi::um::fileapi::LockFileEx; + use winapi::um::winnt::{FILE_SHARE_DELETE, FILE_SHARE_READ, FILE_SHARE_WRITE}; #[derive(Debug)] pub struct Lock { diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 51a38a7d2ab9c..6db2910bca496 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -33,9 +33,6 @@ extern crate libc; #[macro_use] extern crate cfg_if; -#[cfg(windows)] -extern crate libc; - pub use rustc_serialize::hex::ToHex; #[inline(never)] diff --git a/src/librustc_data_structures/profiling.rs b/src/librustc_data_structures/profiling.rs index 8deb43d50f938..004db0a79a880 100644 --- a/src/librustc_data_structures/profiling.rs +++ b/src/librustc_data_structures/profiling.rs @@ -569,39 +569,19 @@ fn get_resident() -> Option { #[cfg(windows)] fn get_resident() -> Option { - type BOOL = i32; - type DWORD = u32; - type HANDLE = *mut u8; - use libc::size_t; - #[repr(C)] - #[allow(non_snake_case)] - struct PROCESS_MEMORY_COUNTERS { - cb: DWORD, - PageFaultCount: DWORD, - PeakWorkingSetSize: size_t, - WorkingSetSize: size_t, - QuotaPeakPagedPoolUsage: size_t, - QuotaPagedPoolUsage: size_t, - QuotaPeakNonPagedPoolUsage: size_t, - QuotaNonPagedPoolUsage: size_t, - PagefileUsage: size_t, - PeakPagefileUsage: size_t, - } - #[allow(non_camel_case_types)] - type PPROCESS_MEMORY_COUNTERS = *mut PROCESS_MEMORY_COUNTERS; - #[link(name = "psapi")] - extern "system" { - fn GetCurrentProcess() -> HANDLE; - fn GetProcessMemoryInfo( - Process: HANDLE, - ppsmemCounters: PPROCESS_MEMORY_COUNTERS, - cb: DWORD, - ) -> BOOL; - } - let mut pmc: PROCESS_MEMORY_COUNTERS = unsafe { std::mem::zeroed() }; - pmc.cb = std::mem::size_of_val(&pmc) as DWORD; - match unsafe { GetProcessMemoryInfo(GetCurrentProcess(), &mut pmc, pmc.cb) } { + use std::mem::{self, MaybeUninit}; + use winapi::shared::minwindef::DWORD; + use winapi::um::processthreadsapi::GetCurrentProcess; + use winapi::um::psapi::{GetProcessMemoryInfo, PROCESS_MEMORY_COUNTERS}; + + let mut pmc = MaybeUninit::::uninit(); + match unsafe { + GetProcessMemoryInfo(GetCurrentProcess(), pmc.as_mut_ptr(), mem::size_of_val(&pmc) as DWORD) + } { 0 => None, - _ => Some(pmc.WorkingSetSize as usize), + _ => { + let pmc = unsafe { pmc.assume_init() }; + Some(pmc.WorkingSetSize as usize) + } } } diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index 37449f9402eff..b856e5da5a093 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -32,5 +32,8 @@ rustc_serialize = { path = "../libserialize", package = "serialize" } syntax = { path = "../libsyntax" } rustc_span = { path = "../librustc_span" } +[target.'cfg(windows)'.dependencies] +winapi = { version = "0.3", features = ["consoleapi", "debugapi", "processenv"] } + [features] llvm = ['rustc_interface/llvm'] diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 3d31f240a34e0..5aba824e32c7a 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -515,15 +515,10 @@ fn stdout_isatty() -> bool { #[cfg(windows)] fn stdout_isatty() -> bool { - type DWORD = u32; - type BOOL = i32; - type HANDLE = *mut u8; - type LPDWORD = *mut u32; - const STD_OUTPUT_HANDLE: DWORD = -11i32 as DWORD; - extern "system" { - fn GetStdHandle(which: DWORD) -> HANDLE; - fn GetConsoleMode(hConsoleHandle: HANDLE, lpMode: LPDWORD) -> BOOL; - } + use winapi::um::consoleapi::GetConsoleMode; + use winapi::um::processenv::GetStdHandle; + use winapi::um::winbase::STD_OUTPUT_HANDLE; + unsafe { let handle = GetStdHandle(STD_OUTPUT_HANDLE); let mut out = 0; @@ -1215,11 +1210,8 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { #[cfg(windows)] unsafe { if env::var("RUSTC_BREAK_ON_ICE").is_ok() { - extern "system" { - fn DebugBreak(); - } // Trigger a debugger if we crashed during bootstrap - DebugBreak(); + winapi::um::debugapi::DebugBreak(); } } } diff --git a/src/librustc_errors/Cargo.toml b/src/librustc_errors/Cargo.toml index 0d0989677c585..01ea80659d6b9 100644 --- a/src/librustc_errors/Cargo.toml +++ b/src/librustc_errors/Cargo.toml @@ -19,3 +19,6 @@ atty = "0.2" termcolor = "1.0" annotate-snippets = "0.6.1" term_size = "0.3.1" + +[target.'cfg(windows)'.dependencies] +winapi = { version = "0.3", features = ["handleapi", "synchapi", "winbase"] } diff --git a/src/librustc_errors/lock.rs b/src/librustc_errors/lock.rs index 198a9c12406e5..a73472021d412 100644 --- a/src/librustc_errors/lock.rs +++ b/src/librustc_errors/lock.rs @@ -12,31 +12,14 @@ use std::any::Any; #[cfg(windows)] -#[allow(nonstandard_style)] pub fn acquire_global_lock(name: &str) -> Box { use std::ffi::CString; use std::io; - type LPSECURITY_ATTRIBUTES = *mut u8; - type BOOL = i32; - type LPCSTR = *const u8; - type HANDLE = *mut u8; - type DWORD = u32; - - const INFINITE: DWORD = !0; - const WAIT_OBJECT_0: DWORD = 0; - const WAIT_ABANDONED: DWORD = 0x00000080; - - extern "system" { - fn CreateMutexA( - lpMutexAttributes: LPSECURITY_ATTRIBUTES, - bInitialOwner: BOOL, - lpName: LPCSTR, - ) -> HANDLE; - fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) -> DWORD; - fn ReleaseMutex(hMutex: HANDLE) -> BOOL; - fn CloseHandle(hObject: HANDLE) -> BOOL; - } + use winapi::shared::ntdef::HANDLE; + use winapi::um::handleapi::CloseHandle; + use winapi::um::synchapi::{CreateMutexA, ReleaseMutex, WaitForSingleObject}; + use winapi::um::winbase::{INFINITE, WAIT_ABANDONED, WAIT_OBJECT_0}; struct Handle(HANDLE); @@ -65,7 +48,7 @@ pub fn acquire_global_lock(name: &str) -> Box { // // This will silently create one if it doesn't already exist, or it'll // open up a handle to one if it already exists. - let mutex = CreateMutexA(std::ptr::null_mut(), 0, cname.as_ptr() as *const u8); + let mutex = CreateMutexA(std::ptr::null_mut(), 0, cname.as_ptr()); if mutex.is_null() { panic!( "failed to create global mutex named `{}`: {}", diff --git a/src/librustc_interface/Cargo.toml b/src/librustc_interface/Cargo.toml index eb0551c606548..548985c451408 100644 --- a/src/librustc_interface/Cargo.toml +++ b/src/librustc_interface/Cargo.toml @@ -42,6 +42,9 @@ rustc_resolve = { path = "../librustc_resolve" } tempfile = "3.0.5" once_cell = "1" +[target.'cfg(windows)'.dependencies] +winapi = { version = "0.3", features = ["libloaderapi"] } + [dev-dependencies] rustc_target = { path = "../librustc_target" } diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 2fafd3af7a5ff..21f9fa4816591 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -340,19 +340,17 @@ fn sysroot_candidates() -> Vec { fn current_dll_path() -> Option { use std::ffi::OsString; use std::os::windows::prelude::*; + use std::ptr; - extern "system" { - fn GetModuleHandleExW(dwFlags: u32, lpModuleName: usize, phModule: *mut usize) -> i32; - fn GetModuleFileNameW(hModule: usize, lpFilename: *mut u16, nSize: u32) -> u32; - } - - const GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS: u32 = 0x00000004; + use winapi::um::libloaderapi::{ + GetModuleFileNameW, GetModuleHandleExW, GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, + }; unsafe { - let mut module = 0; + let mut module = ptr::null_mut(); let r = GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, - current_dll_path as usize, + current_dll_path as usize as *mut _, &mut module, ); if r == 0 { diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml index 48767c377a94c..0a0bcb190bea7 100644 --- a/src/librustc_metadata/Cargo.toml +++ b/src/librustc_metadata/Cargo.toml @@ -27,3 +27,6 @@ rustc_expand = { path = "../librustc_expand" } rustc_parse = { path = "../librustc_parse" } rustc_span = { path = "../librustc_span" } rustc_error_codes = { path = "../librustc_error_codes" } + +[target.'cfg(windows)'.dependencies] +winapi = { version = "0.3", features = ["errhandlingapi", "libloaderapi"] } diff --git a/src/librustc_metadata/dynamic_lib.rs b/src/librustc_metadata/dynamic_lib.rs index fa4983d8a815e..f04d0239d4923 100644 --- a/src/librustc_metadata/dynamic_lib.rs +++ b/src/librustc_metadata/dynamic_lib.rs @@ -111,9 +111,9 @@ mod dl { ) -> Result<*mut u8, String> { check_for_errors_in(|| libc::dlsym(handle as *mut libc::c_void, symbol) as *mut u8) } + pub(super) unsafe fn close(handle: *mut u8) { libc::dlclose(handle as *mut libc::c_void); - () } } @@ -124,27 +124,15 @@ mod dl { use std::os::windows::prelude::*; use std::ptr; - use libc::{c_char, c_uint, c_void}; - - type DWORD = u32; - type HMODULE = *mut u8; - type BOOL = i32; - type LPCWSTR = *const u16; - type LPCSTR = *const i8; - - extern "system" { - fn SetThreadErrorMode(dwNewMode: DWORD, lpOldMode: *mut DWORD) -> c_uint; - fn LoadLibraryW(name: LPCWSTR) -> HMODULE; - fn GetModuleHandleExW(dwFlags: DWORD, name: LPCWSTR, handle: *mut HMODULE) -> BOOL; - fn GetProcAddress(handle: HMODULE, name: LPCSTR) -> *mut c_void; - fn FreeLibrary(handle: HMODULE) -> BOOL; - } + use winapi::shared::minwindef::HMODULE; + use winapi::um::errhandlingapi::SetThreadErrorMode; + use winapi::um::libloaderapi::{FreeLibrary, GetModuleHandleExW, GetProcAddress, LoadLibraryW}; + use winapi::um::winbase::SEM_FAILCRITICALERRORS; pub(super) fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> { // disable "dll load failed" error dialog. let prev_error_mode = unsafe { - // SEM_FAILCRITICALERRORS 0x01 - let new_error_mode = 1; + let new_error_mode = SEM_FAILCRITICALERRORS; let mut prev_error_mode = 0; let result = SetThreadErrorMode(new_error_mode, &mut prev_error_mode); if result == 0 { @@ -156,12 +144,12 @@ mod dl { let result = match filename { Some(filename) => { let filename_str: Vec<_> = filename.encode_wide().chain(Some(0)).collect(); - let result = unsafe { LoadLibraryW(filename_str.as_ptr()) }; + let result = unsafe { LoadLibraryW(filename_str.as_ptr()) } as *mut u8; ptr_result(result) } None => { let mut handle = ptr::null_mut(); - let succeeded = unsafe { GetModuleHandleExW(0 as DWORD, ptr::null(), &mut handle) }; + let succeeded = unsafe { GetModuleHandleExW(0, ptr::null(), &mut handle) }; if succeeded == 0 { Err(io::Error::last_os_error().to_string()) } else { @@ -177,7 +165,10 @@ mod dl { result } - pub(super) unsafe fn symbol(handle: *mut u8, symbol: *const c_char) -> Result<*mut u8, String> { + pub(super) unsafe fn symbol( + handle: *mut u8, + symbol: *const libc::c_char, + ) -> Result<*mut u8, String> { let ptr = GetProcAddress(handle as HMODULE, symbol) as *mut u8; ptr_result(ptr) } diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 1912c9ef5baeb..3a114a0b71517 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -42,10 +42,8 @@ mod tests; #[cfg(windows)] fn disable_error_reporting R, R>(f: F) -> R { use std::sync::Mutex; - const SEM_NOGPFAULTERRORBOX: u32 = 0x0002; - extern "system" { - fn SetErrorMode(mode: u32) -> u32; - } + use winapi::um::errhandlingapi::SetErrorMode; + use winapi::um::winbase::SEM_NOGPFAULTERRORBOX; lazy_static! { static ref LOCK: Mutex<()> = { Mutex::new(()) }; From 091ba6daa0a0a528b5d9fc816529a9bb25503960 Mon Sep 17 00:00:00 2001 From: Charles Lew Date: Sun, 12 Jan 2020 13:15:00 +0800 Subject: [PATCH 018/169] Address review comments. --- src/liballoc/collections/linked_list.rs | 233 ++++++++++++------ src/liballoc/collections/linked_list/tests.rs | 11 +- 2 files changed, 161 insertions(+), 83 deletions(-) diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index d0ad1ec283942..3524c6e9817e1 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -251,8 +251,8 @@ impl LinkedList { &mut self, existing_prev: Option>>, existing_next: Option>>, - splice_start: NonNull>, - splice_end: NonNull>, + mut splice_start: NonNull>, + mut splice_end: NonNull>, splice_length: usize, ) { // This method takes care not to create multiple mutable references to whole nodes at the same time, @@ -267,9 +267,7 @@ impl LinkedList { } else { self.tail = Some(splice_end); } - let mut splice_start = splice_start; splice_start.as_mut().prev = existing_prev; - let mut splice_end = splice_end; splice_end.as_mut().next = existing_next; self.len += splice_length; @@ -289,6 +287,41 @@ impl LinkedList { } } + #[inline] + unsafe fn split_off_before_node( + &mut self, + split_node: Option>>, + at: usize, + ) -> Self { + // The split node is the new head node of the second part + if let Some(mut split_node) = split_node { + let first_part_head; + let first_part_tail; + first_part_tail = split_node.as_mut().prev.take(); + if let Some(mut tail) = first_part_tail { + tail.as_mut().next = None; + first_part_head = self.head; + } else { + first_part_head = None; + } + + let first_part = LinkedList { + head: first_part_head, + tail: first_part_tail, + len: at, + marker: PhantomData, + }; + + // Fix the head ptr of the second part + self.head = Some(split_node); + self.len = self.len - at; + + first_part + } else { + mem::replace(self, LinkedList::new()) + } + } + #[inline] unsafe fn split_off_after_node( &mut self, @@ -1082,16 +1115,13 @@ impl IterMut<'_, T> { /// A cursor over a `LinkedList`. /// -/// A `Cursor` is like an iterator, except that it can freely seek back-and-forth, and can -/// safely mutate the list during iteration. This is because the lifetime of its yielded -/// references is tied to its own lifetime, instead of just the underlying list. This means -/// cursors cannot yield multiple elements at once. +/// A `Cursor` is like an iterator, except that it can freely seek back-and-forth. /// /// Cursors always rest between two elements in the list, and index in a logically circular way. /// To accommodate this, there is a "ghost" non-element that yields `None` between the head and /// tail of the list. /// -/// When created, cursors start at the front of the list, or the ghost element if the list is empty. +/// When created, cursors start at the front of the list, or the "ghost" non-element if the list is empty. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub struct Cursor<'a, T: 'a> { index: usize, @@ -1117,7 +1147,7 @@ impl fmt::Debug for Cursor<'_, T> { /// To accommodate this, there is a "ghost" non-element that yields `None` between the head and /// tail of the list. /// -/// When created, cursors start at the front of the list, or the ghost element if the list is empty. +/// When created, cursors start at the front of the list, or the "ghost" non-element if the list is empty. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub struct CursorMut<'a, T: 'a> { index: usize, @@ -1133,8 +1163,11 @@ impl fmt::Debug for CursorMut<'_, T> { } impl<'a, T> Cursor<'a, T> { - /// Move to the subsequent element of the list if it exists or the empty - /// element + /// Moves the cursor to the next element of the `LinkedList`. + /// + /// If the cursor is pointing to the "ghost" non-element then this will move it to + /// the first element of the `LinkedList`. If it is pointing to the last + /// element of the `LinkedList` then this will move it to the "ghost" non-element. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn move_next(&mut self) { match self.current.take() { @@ -1152,7 +1185,11 @@ impl<'a, T> Cursor<'a, T> { } } - /// Move to the previous element of the list + /// Moves the cursor to the previous element of the `LinkedList`. + /// + /// If the cursor is pointing to the "ghost" non-element then this will move it to + /// the last element of the `LinkedList`. If it is pointing to the first + /// element of the `LinkedList` then this will move it to the "ghost" non-element. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn move_prev(&mut self) { match self.current.take() { @@ -1169,13 +1206,21 @@ impl<'a, T> Cursor<'a, T> { } } - /// Get the current element + /// Returns a reference to the element that the cursor is currently + /// pointing to. + /// + /// This returns `None` if the cursor is currently pointing to the + /// "ghost" non-element. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn current(&self) -> Option<&'a T> { unsafe { self.current.map(|current| &(*current.as_ptr()).element) } } - /// Get the next element + /// Returns a reference to the next element. + /// + /// If the cursor is pointing to the "ghost" non-element then this returns + /// the first element of the `LinkedList`. If it is pointing to the last + /// element of the `LinkedList` then this returns `None`. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn peek_next(&self) -> Option<&'a T> { unsafe { @@ -1187,7 +1232,11 @@ impl<'a, T> Cursor<'a, T> { } } - /// Get the previous element + /// Returns a reference to the previous element. + /// + /// If the cursor is pointing to the "ghost" non-element then this returns + /// the last element of the `LinkedList`. If it is pointing to the first + /// element of the `LinkedList` then this returns `None`. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn peek_prev(&self) -> Option<&'a T> { unsafe { @@ -1201,8 +1250,11 @@ impl<'a, T> Cursor<'a, T> { } impl<'a, T> CursorMut<'a, T> { - /// Move to the subsequent element of the list if it exists or the empty - /// element + /// Moves the cursor to the next element of the `LinkedList`. + /// + /// If the cursor is pointing to the "ghost" non-element then this will move it to + /// the first element of the `LinkedList`. If it is pointing to the last + /// element of the `LinkedList` then this will move it to the "ghost" non-element. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn move_next(&mut self) { match self.current.take() { @@ -1220,7 +1272,11 @@ impl<'a, T> CursorMut<'a, T> { } } - /// Move to the previous element of the list + /// Moves the cursor to the previous element of the `LinkedList`. + /// + /// If the cursor is pointing to the "ghost" non-element then this will move it to + /// the last element of the `LinkedList`. If it is pointing to the first + /// element of the `LinkedList` then this will move it to the "ghost" non-element. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn move_prev(&mut self) { match self.current.take() { @@ -1237,13 +1293,21 @@ impl<'a, T> CursorMut<'a, T> { } } - /// Get the current element + /// Returns a reference to the element that the cursor is currently + /// pointing to. + /// + /// This returns `None` if the cursor is currently pointing to the + /// "ghost" non-element. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn current(&mut self) -> Option<&mut T> { unsafe { self.current.map(|current| &mut (*current.as_ptr()).element) } } - /// Get the next element + /// Returns a reference to the next element. + /// + /// If the cursor is pointing to the "ghost" non-element then this returns + /// the first element of the `LinkedList`. If it is pointing to the last + /// element of the `LinkedList` then this returns `None`. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn peek_next(&mut self) -> Option<&mut T> { unsafe { @@ -1255,7 +1319,11 @@ impl<'a, T> CursorMut<'a, T> { } } - /// Get the previous element + /// Returns a reference to the previous element. + /// + /// If the cursor is pointing to the "ghost" non-element then this returns + /// the last element of the `LinkedList`. If it is pointing to the first + /// element of the `LinkedList` then this returns `None`. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn peek_prev(&mut self) -> Option<&mut T> { unsafe { @@ -1267,7 +1335,11 @@ impl<'a, T> CursorMut<'a, T> { } } - /// Get an immutable cursor at the current element + /// Returns a read-only cursor pointing to the current element. + /// + /// The lifetime of the returned `Cursor` is bound to that of the + /// `CursorMut`, which means it cannot outlive the `CursorMut` and that the + /// `CursorMut` is frozen for the lifetime of the `Cursor`. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn as_cursor<'cm>(&'cm self) -> Cursor<'cm, T> { Cursor { list: self.list, current: self.current, index: self.index } @@ -1277,56 +1349,65 @@ impl<'a, T> CursorMut<'a, T> { // Now the list editing operations impl<'a, T> CursorMut<'a, T> { - /// Insert `item` after the cursor + /// Inserts a new element into the `LinkedList` after the current one. + /// + /// If the cursor is pointing at the "ghost" non-element then the new element is + /// inserted at the front of the `LinkedList`. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn insert_after(&mut self, item: T) { unsafe { let spliced_node = Box::into_raw_non_null(Box::new(Node::new(item))); - let (node, node_next) = match self.current { - None => (None, self.list.head), - Some(node) => { - let node_next = node.as_ref().next; - (Some(node), node_next) - } + let node_next = match self.current { + None => self.list.head, + Some(node) => node.as_ref().next, }; - self.list.splice_nodes(node, node_next, spliced_node, spliced_node, 1); + self.list.splice_nodes(self.current, node_next, spliced_node, spliced_node, 1); if self.current.is_none() { - // The ghost element's index has increased by 1. - self.index += 1; + // The "ghost" non-element's index has changed. + self.index = self.list.len; } } } - /// Insert `item` before the cursor + /// Inserts a new element into the `LinkedList` before the current one. + /// + /// If the cursor is pointing at the "ghost" non-element then the new element is + /// inserted at the end of the `LinkedList`. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn insert_before(&mut self, item: T) { unsafe { let spliced_node = Box::into_raw_non_null(Box::new(Node::new(item))); - let (node_prev, node) = match self.current { - None => (self.list.tail, None), - Some(node) => { - let node_prev = node.as_ref().prev; - (node_prev, Some(node)) - } + let node_prev = match self.current { + None => self.list.tail, + Some(node) => node.as_ref().prev, }; - self.list.splice_nodes(node_prev, node, spliced_node, spliced_node, 1); + self.list.splice_nodes(node_prev, self.current, spliced_node, spliced_node, 1); self.index += 1; } } - /// Remove and return the current item, moving the cursor to the next item + /// Removes the current element from the `LinkedList`. + /// + /// The element that was removed is returned, and the cursor is + /// moved to point to the next element in the `LinkedList`. + /// + /// If the cursor is currently pointing to the "ghost" non-element then no element + /// is removed and `None` is returned. #[unstable(feature = "linked_list_cursors", issue = "58533")] - pub fn remove(&mut self) -> Option { + pub fn remove_current(&mut self) -> Option { let unlinked_node = self.current?; unsafe { self.current = unlinked_node.as_ref().next; self.list.unlink_node(unlinked_node); let unlinked_node = Box::from_raw(unlinked_node.as_ptr()); - Some((*unlinked_node).element) + Some(unlinked_node.element) } } - /// Insert `list` between the current element and the next + /// Inserts the elements from the given `LinkedList` after the current one. + /// + /// If the cursor is pointing at the "ghost" non-element then the new elements are + /// inserted at the start of the `LinkedList`. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn splice_after(&mut self, list: LinkedList) { unsafe { @@ -1334,22 +1415,22 @@ impl<'a, T> CursorMut<'a, T> { Some(parts) => parts, _ => return, }; - let (node, node_next) = match self.current { - None => (None, self.list.head), - Some(node) => { - let node_next = node.as_ref().next; - (Some(node), node_next) - } + let node_next = match self.current { + None => self.list.head, + Some(node) => node.as_ref().next, }; - self.list.splice_nodes(node, node_next, splice_head, splice_tail, splice_len); + self.list.splice_nodes(self.current, node_next, splice_head, splice_tail, splice_len); if self.current.is_none() { - // The ghost element's index has increased by `splice_len`. - self.index += splice_len; + // The "ghost" non-element's index has changed. + self.index = self.list.len; } } } - /// Insert `list` between the previous element and current + /// Inserts the elements from the given `LinkedList` before the current one. + /// + /// If the cursor is pointing at the "ghost" non-element then the new elements are + /// inserted at the end of the `LinkedList`. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn splice_before(&mut self, list: LinkedList) { unsafe { @@ -1357,41 +1438,37 @@ impl<'a, T> CursorMut<'a, T> { Some(parts) => parts, _ => return, }; - let (node_prev, node) = match self.current { - None => (self.list.tail, None), - Some(node) => { - let node_prev = node.as_ref().prev; - (node_prev, Some(node)) - } + let node_prev = match self.current { + None => self.list.tail, + Some(node) => node.as_ref().prev, }; - self.list.splice_nodes(node_prev, node, splice_head, splice_tail, splice_len); + self.list.splice_nodes(node_prev, self.current, splice_head, splice_tail, splice_len); self.index += splice_len; } } - /// Split the list in two after the current element - /// The returned list consists of all elements following the current one. - // note: consuming the cursor is not necessary here, but it makes sense - // given the interface + /// Splits the list into two after the current element. This will return a + /// new list consisting of everything after the cursor, with the original + /// list retaining everything before. + /// + /// If the cursor is pointing at the "ghost" non-element then the entire contents + /// of the `LinkedList` are moved. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn split_after(self) -> LinkedList { let split_off_idx = if self.index == self.list.len { 0 } else { self.index + 1 }; - unsafe { - let split_off_node = self.current; - self.list.split_off_after_node(split_off_node, split_off_idx) - } + unsafe { self.list.split_off_after_node(self.current, split_off_idx) } } - /// Split the list in two before the current element + + /// Splits the list into two before the current element. This will return a + /// new list consisting of everything before the cursor, with the original + /// list retaining everything after. + /// + /// If the cursor is pointing at the "ghost" non-element then the entire contents + /// of the `LinkedList` are moved. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn split_before(self) -> LinkedList { let split_off_idx = self.index; - unsafe { - let split_off_node = match self.current { - Some(node) => node.as_ref().prev, - None => self.list.tail, - }; - self.list.split_off_after_node(split_off_node, split_off_idx) - } + unsafe { self.list.split_off_before_node(self.current, split_off_idx) } } } diff --git a/src/liballoc/collections/linked_list/tests.rs b/src/liballoc/collections/linked_list/tests.rs index 51b23e23cd276..29eb1b4abd732 100644 --- a/src/liballoc/collections/linked_list/tests.rs +++ b/src/liballoc/collections/linked_list/tests.rs @@ -362,16 +362,16 @@ fn test_cursor_mut_insert() { assert_eq!(m.iter().cloned().collect::>(), &[10, 7, 1, 8, 2, 3, 4, 5, 6, 9]); let mut cursor = m.cursor_mut(); cursor.move_prev(); - assert_eq!(cursor.remove(), None); + assert_eq!(cursor.remove_current(), None); cursor.move_next(); cursor.move_next(); - assert_eq!(cursor.remove(), Some(7)); + assert_eq!(cursor.remove_current(), Some(7)); cursor.move_prev(); cursor.move_prev(); cursor.move_prev(); - assert_eq!(cursor.remove(), Some(9)); + assert_eq!(cursor.remove_current(), Some(9)); cursor.move_next(); - assert_eq!(cursor.remove(), Some(10)); + assert_eq!(cursor.remove_current(), Some(10)); check_links(&m); assert_eq!(m.iter().cloned().collect::>(), &[1, 8, 2, 3, 4, 5, 6]); let mut cursor = m.cursor_mut(); @@ -389,7 +389,8 @@ fn test_cursor_mut_insert() { let mut cursor = m.cursor_mut(); cursor.move_prev(); let tmp = cursor.split_before(); - assert_eq!(tmp.into_iter().collect::>(), &[]); + assert_eq!(m.into_iter().collect::>(), &[]); + m = tmp; let mut cursor = m.cursor_mut(); cursor.move_next(); cursor.move_next(); From d2c509a3c6b06ba02807bf94c00fad4c4a9262a5 Mon Sep 17 00:00:00 2001 From: Charles Lew Date: Sun, 12 Jan 2020 18:01:24 +0800 Subject: [PATCH 019/169] Address review comments. --- src/liballoc/collections/linked_list.rs | 26 +++++++++++++++++-- src/liballoc/collections/linked_list/tests.rs | 9 +++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index 3524c6e9817e1..d7504b0b80bd9 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -1132,7 +1132,7 @@ pub struct Cursor<'a, T: 'a> { #[unstable(feature = "linked_list_cursors", issue = "58533")] impl fmt::Debug for Cursor<'_, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("Cursor").field(&self.list).field(&self.index).finish() + f.debug_tuple("Cursor").field(&self.list).field(&self.index()).finish() } } @@ -1158,11 +1158,21 @@ pub struct CursorMut<'a, T: 'a> { #[unstable(feature = "linked_list_cursors", issue = "58533")] impl fmt::Debug for CursorMut<'_, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_tuple("CursorMut").field(&self.list).field(&self.index).finish() + f.debug_tuple("CursorMut").field(&self.list).field(&self.index()).finish() } } impl<'a, T> Cursor<'a, T> { + /// Returns the cursor position index within the `LinkedList`. + /// + /// This returns `None` if the cursor is currently pointing to the + /// "ghost" non-element. + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn index(&self) -> Option { + let _ = self.current?; + Some(self.index) + } + /// Moves the cursor to the next element of the `LinkedList`. /// /// If the cursor is pointing to the "ghost" non-element then this will move it to @@ -1250,6 +1260,16 @@ impl<'a, T> Cursor<'a, T> { } impl<'a, T> CursorMut<'a, T> { + /// Returns the cursor position index within the `LinkedList`. + /// + /// This returns `None` if the cursor is currently pointing to the + /// "ghost" non-element. + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn index(&self) -> Option { + let _ = self.current?; + Some(self.index) + } + /// Moves the cursor to the next element of the `LinkedList`. /// /// If the cursor is pointing to the "ghost" non-element then this will move it to @@ -1456,6 +1476,7 @@ impl<'a, T> CursorMut<'a, T> { #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn split_after(self) -> LinkedList { let split_off_idx = if self.index == self.list.len { 0 } else { self.index + 1 }; + // no need to update `self.index` because the cursor is consumed. unsafe { self.list.split_off_after_node(self.current, split_off_idx) } } @@ -1468,6 +1489,7 @@ impl<'a, T> CursorMut<'a, T> { #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn split_before(self) -> LinkedList { let split_off_idx = self.index; + // no need to update `self.index` because the cursor is consumed. unsafe { self.list.split_off_before_node(self.current, split_off_idx) } } } diff --git a/src/liballoc/collections/linked_list/tests.rs b/src/liballoc/collections/linked_list/tests.rs index 29eb1b4abd732..d223752c7f7ec 100644 --- a/src/liballoc/collections/linked_list/tests.rs +++ b/src/liballoc/collections/linked_list/tests.rs @@ -313,15 +313,18 @@ fn test_cursor_move_peek() { assert_eq!(cursor.current(), Some(&1)); assert_eq!(cursor.peek_next(), Some(&2)); assert_eq!(cursor.peek_prev(), None); + assert_eq!(cursor.index(), Some(0)); cursor.move_prev(); assert_eq!(cursor.current(), None); assert_eq!(cursor.peek_next(), Some(&1)); assert_eq!(cursor.peek_prev(), Some(&6)); + assert_eq!(cursor.index(), None); cursor.move_next(); cursor.move_next(); assert_eq!(cursor.current(), Some(&2)); assert_eq!(cursor.peek_next(), Some(&3)); assert_eq!(cursor.peek_prev(), Some(&1)); + assert_eq!(cursor.index(), Some(1)); let mut m: LinkedList = LinkedList::new(); m.extend(&[1, 2, 3, 4, 5, 6]); @@ -329,20 +332,26 @@ fn test_cursor_move_peek() { assert_eq!(cursor.current(), Some(&mut 1)); assert_eq!(cursor.peek_next(), Some(&mut 2)); assert_eq!(cursor.peek_prev(), None); + assert_eq!(cursor.index(), Some(0)); cursor.move_prev(); assert_eq!(cursor.current(), None); assert_eq!(cursor.peek_next(), Some(&mut 1)); assert_eq!(cursor.peek_prev(), Some(&mut 6)); + assert_eq!(cursor.index(), None); cursor.move_next(); cursor.move_next(); assert_eq!(cursor.current(), Some(&mut 2)); assert_eq!(cursor.peek_next(), Some(&mut 3)); assert_eq!(cursor.peek_prev(), Some(&mut 1)); + assert_eq!(cursor.index(), Some(1)); let mut cursor2 = cursor.as_cursor(); assert_eq!(cursor2.current(), Some(&2)); + assert_eq!(cursor2.index(), Some(1)); cursor2.move_next(); assert_eq!(cursor2.current(), Some(&3)); + assert_eq!(cursor2.index(), Some(2)); assert_eq!(cursor.current(), Some(&mut 2)); + assert_eq!(cursor.index(), Some(1)); } #[test] From 0810210bcb2c1a50d815e8e71d6db3b6cb0aba7f Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 10 Jan 2020 14:13:05 +0000 Subject: [PATCH 020/169] Diagnostics should start lowercase --- src/librustc/traits/error_reporting.rs | 2 +- src/librustc_ast_passes/feature_gate.rs | 2 +- src/librustc_builtin_macros/test.rs | 2 +- src/librustc_lint/builtin.rs | 14 ++--- src/librustc_mir/borrow_check/nll.rs | 4 +- src/librustc_typeck/check/cast.rs | 2 +- src/test/ui/anon-params-deprecated.stderr | 6 +-- .../validate_uninhabited_zsts.stderr | 2 +- .../feature-gate-never_type.stderr | 10 ++-- .../ui/future-incompatible-lint-group.stderr | 2 +- src/test/ui/issues/issue-45730.stderr | 6 +-- src/test/ui/lint/uninitialized-zeroed.stderr | 54 +++++++++---------- .../escape-argument-callee.stderr | 4 +- .../escape-argument.stderr | 4 +- .../escape-upvar-nested.stderr | 6 +-- .../escape-upvar-ref.stderr | 4 +- ...pagate-approximated-fail-no-postdom.stderr | 4 +- .../propagate-approximated-ref.stderr | 4 +- ...er-to-static-comparing-against-free.stderr | 8 +-- ...oximated-shorter-to-static-no-bound.stderr | 4 +- ...mated-shorter-to-static-wrong-bound.stderr | 4 +- .../propagate-approximated-val.stderr | 4 +- .../propagate-despite-same-free-region.stderr | 4 +- ...ail-to-approximate-longer-no-bounds.stderr | 4 +- ...-to-approximate-longer-wrong-bounds.stderr | 4 +- .../propagate-from-trait-match.stderr | 4 +- .../return-wrong-bound-region.stderr | 4 +- .../projection-no-regions-closure.stderr | 16 +++--- .../projection-one-region-closure.stderr | 16 +++--- ...tion-one-region-trait-bound-closure.stderr | 20 +++---- ...e-region-trait-bound-static-closure.stderr | 20 +++---- ...tion-two-region-trait-bound-closure.stderr | 32 +++++------ ...ram-closure-approximate-lower-bound.stderr | 8 +-- ...m-closure-outlives-from-return-type.stderr | 4 +- ...-closure-outlives-from-where-clause.stderr | 16 +++--- .../ui/order-dependent-cast-inference.stderr | 2 +- .../test-attrs/test-should-panic-attr.stderr | 8 +-- .../ui/traits/trait-bounds-same-crate-name.rs | 2 +- .../trait-bounds-same-crate-name.stderr | 4 +- 39 files changed, 160 insertions(+), 160 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 0c9a73d78a5eb..5440cb7bdf4e5 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1156,7 +1156,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { err.span_help(impl_span, "trait impl with same name found"); let trait_crate = self.tcx.crate_name(trait_with_same_path.krate); let crate_msg = format!( - "Perhaps two different versions of crate `{}` are being used?", + "perhaps two different versions of crate `{}` are being used?", trait_crate ); err.note(&crate_msg); diff --git a/src/librustc_ast_passes/feature_gate.rs b/src/librustc_ast_passes/feature_gate.rs index e6f4535a38dba..1e4b1ae077762 100644 --- a/src/librustc_ast_passes/feature_gate.rs +++ b/src/librustc_ast_passes/feature_gate.rs @@ -413,7 +413,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { self.check_extern(bare_fn_ty.ext); } ast::TyKind::Never => { - gate_feature_post!(&self, never_type, ty.span, "The `!` type is experimental"); + gate_feature_post!(&self, never_type, ty.span, "the `!` type is experimental"); } _ => {} } diff --git a/src/librustc_builtin_macros/test.rs b/src/librustc_builtin_macros/test.rs index 0eee212108e85..07715cdbcb5e9 100644 --- a/src/librustc_builtin_macros/test.rs +++ b/src/librustc_builtin_macros/test.rs @@ -325,7 +325,7 @@ fn should_panic(cx: &ExtCtxt<'_>, i: &ast::Item) -> ShouldPanic { `expected = \"error message\"`", ) .note( - "Errors in this attribute were erroneously \ + "errors in this attribute were erroneously \ allowed and will become a hard error in a \ future release.", ) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 15a8332a28492..7f55bcd4017ef 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -657,7 +657,7 @@ impl EarlyLintPass for AnonymousParameters { ) .span_suggestion( arg.pat.span, - "Try naming the parameter or explicitly \ + "try naming the parameter or explicitly \ ignoring it", format!("_: {}", ty_snip), appl, @@ -1934,21 +1934,21 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue { use rustc::ty::TyKind::*; match ty.kind { // Primitive types that don't like 0 as a value. - Ref(..) => Some((format!("References must be non-null"), None)), + Ref(..) => Some((format!("references must be non-null"), None)), Adt(..) if ty.is_box() => Some((format!("`Box` must be non-null"), None)), - FnPtr(..) => Some((format!("Function pointers must be non-null"), None)), - Never => Some((format!("The never type (`!`) has no valid value"), None)), + FnPtr(..) => Some((format!("function pointers must be non-null"), None)), + Never => Some((format!("the `!` type has no valid value"), None)), RawPtr(tm) if matches!(tm.ty.kind, Dynamic(..)) => // raw ptr to dyn Trait { - Some((format!("The vtable of a wide raw pointer must be non-null"), None)) + Some((format!("the vtable of a wide raw pointer must be non-null"), None)) } // Primitive types with other constraints. Bool if init == InitKind::Uninit => { - Some((format!("Booleans must be `true` or `false`"), None)) + Some((format!("booleans must be either `true` or `false`"), None)) } Char if init == InitKind::Uninit => { - Some((format!("Characters must be a valid unicode codepoint"), None)) + Some((format!("characters must be a valid Unicode codepoint"), None)) } // Recurse and checks for some compound types. Adt(adt_def, substs) if !adt_def.is_union() => { diff --git a/src/librustc_mir/borrow_check/nll.rs b/src/librustc_mir/borrow_check/nll.rs index 151a2c4c19a7d..73718d58346f1 100644 --- a/src/librustc_mir/borrow_check/nll.rs +++ b/src/librustc_mir/borrow_check/nll.rs @@ -360,7 +360,7 @@ pub(super) fn dump_annotation<'a, 'tcx>( // better. if let Some(closure_region_requirements) = closure_region_requirements { - let mut err = tcx.sess.diagnostic().span_note_diag(body.span, "External requirements"); + let mut err = tcx.sess.diagnostic().span_note_diag(body.span, "external requirements"); regioncx.annotate(tcx, &mut err); @@ -379,7 +379,7 @@ pub(super) fn dump_annotation<'a, 'tcx>( err.buffer(errors_buffer); } else { - let mut err = tcx.sess.diagnostic().span_note_diag(body.span, "No external requirements"); + let mut err = tcx.sess.diagnostic().span_note_diag(body.span, "no external requirements"); regioncx.annotate(tcx, &mut err); err.buffer(errors_buffer); diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index ba5e5fd8ac188..cbbfe2d627895 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -381,7 +381,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { if unknown_cast_to { "to" } else { "from" } ); err.note( - "The type information given here is insufficient to check whether \ + "the type information given here is insufficient to check whether \ the pointer cast is valid", ); if unknown_cast_to { diff --git a/src/test/ui/anon-params-deprecated.stderr b/src/test/ui/anon-params-deprecated.stderr index e97dbc15f9cde..8e4fa70d342f2 100644 --- a/src/test/ui/anon-params-deprecated.stderr +++ b/src/test/ui/anon-params-deprecated.stderr @@ -2,7 +2,7 @@ warning: anonymous parameters are deprecated and will be removed in the next edi --> $DIR/anon-params-deprecated.rs:9:12 | LL | fn foo(i32); - | ^^^ help: Try naming the parameter or explicitly ignoring it: `_: i32` + | ^^^ help: try naming the parameter or explicitly ignoring it: `_: i32` | note: lint level defined here --> $DIR/anon-params-deprecated.rs:1:9 @@ -16,7 +16,7 @@ warning: anonymous parameters are deprecated and will be removed in the next edi --> $DIR/anon-params-deprecated.rs:12:30 | LL | fn bar_with_default_impl(String, String) {} - | ^^^^^^ help: Try naming the parameter or explicitly ignoring it: `_: String` + | ^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: String` | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! = note: for more information, see issue #41686 @@ -25,7 +25,7 @@ warning: anonymous parameters are deprecated and will be removed in the next edi --> $DIR/anon-params-deprecated.rs:12:38 | LL | fn bar_with_default_impl(String, String) {} - | ^^^^^^ help: Try naming the parameter or explicitly ignoring it: `_: String` + | ^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: String` | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2018 edition! = note: for more information, see issue #41686 diff --git a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr index bde7f2536fac1..040c568beb324 100644 --- a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr +++ b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr @@ -34,7 +34,7 @@ LL | unsafe { std::mem::transmute(()) } | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | = note: `#[warn(invalid_value)]` on by default - = note: The never type (`!`) has no valid value + = note: the `!` type has no valid value warning: the type `Empty` does not permit zero-initialization --> $DIR/validate_uninhabited_zsts.rs:17:35 diff --git a/src/test/ui/feature-gates/feature-gate-never_type.stderr b/src/test/ui/feature-gates/feature-gate-never_type.stderr index d86ab99b82bd5..216615731e56f 100644 --- a/src/test/ui/feature-gates/feature-gate-never_type.stderr +++ b/src/test/ui/feature-gates/feature-gate-never_type.stderr @@ -1,4 +1,4 @@ -error[E0658]: The `!` type is experimental +error[E0658]: the `!` type is experimental --> $DIR/feature-gate-never_type.rs:7:17 | LL | type Ma = (u32, !, i32); @@ -7,7 +7,7 @@ LL | type Ma = (u32, !, i32); = note: for more information, see https://github.com/rust-lang/rust/issues/35121 = help: add `#![feature(never_type)]` to the crate attributes to enable -error[E0658]: The `!` type is experimental +error[E0658]: the `!` type is experimental --> $DIR/feature-gate-never_type.rs:8:20 | LL | type Meeshka = Vec; @@ -16,7 +16,7 @@ LL | type Meeshka = Vec; = note: for more information, see https://github.com/rust-lang/rust/issues/35121 = help: add `#![feature(never_type)]` to the crate attributes to enable -error[E0658]: The `!` type is experimental +error[E0658]: the `!` type is experimental --> $DIR/feature-gate-never_type.rs:9:24 | LL | type Mow = &'static fn(!) -> !; @@ -25,7 +25,7 @@ LL | type Mow = &'static fn(!) -> !; = note: for more information, see https://github.com/rust-lang/rust/issues/35121 = help: add `#![feature(never_type)]` to the crate attributes to enable -error[E0658]: The `!` type is experimental +error[E0658]: the `!` type is experimental --> $DIR/feature-gate-never_type.rs:10:27 | LL | type Skwoz = &'static mut !; @@ -34,7 +34,7 @@ LL | type Skwoz = &'static mut !; = note: for more information, see https://github.com/rust-lang/rust/issues/35121 = help: add `#![feature(never_type)]` to the crate attributes to enable -error[E0658]: The `!` type is experimental +error[E0658]: the `!` type is experimental --> $DIR/feature-gate-never_type.rs:13:16 | LL | type Wub = !; diff --git a/src/test/ui/future-incompatible-lint-group.stderr b/src/test/ui/future-incompatible-lint-group.stderr index 24e3a077ae6e3..1d958e5bfeb40 100644 --- a/src/test/ui/future-incompatible-lint-group.stderr +++ b/src/test/ui/future-incompatible-lint-group.stderr @@ -2,7 +2,7 @@ error: anonymous parameters are deprecated and will be removed in the next editi --> $DIR/future-incompatible-lint-group.rs:4:10 | LL | fn f(u8) {} - | ^^ help: Try naming the parameter or explicitly ignoring it: `_: u8` + | ^^ help: try naming the parameter or explicitly ignoring it: `_: u8` | note: lint level defined here --> $DIR/future-incompatible-lint-group.rs:1:9 diff --git a/src/test/ui/issues/issue-45730.stderr b/src/test/ui/issues/issue-45730.stderr index 3c400d6eefaa8..d4ddba52df14a 100644 --- a/src/test/ui/issues/issue-45730.stderr +++ b/src/test/ui/issues/issue-45730.stderr @@ -6,7 +6,7 @@ LL | let x: *const _ = 0 as _; | | | help: consider giving more type information | - = note: The type information given here is insufficient to check whether the pointer cast is valid + = note: the type information given here is insufficient to check whether the pointer cast is valid error[E0641]: cannot cast to a pointer of an unknown kind --> $DIR/issue-45730.rs:5:23 @@ -16,7 +16,7 @@ LL | let x: *const _ = 0 as *const _; | | | help: consider giving more type information | - = note: The type information given here is insufficient to check whether the pointer cast is valid + = note: the type information given here is insufficient to check whether the pointer cast is valid error[E0641]: cannot cast to a pointer of an unknown kind --> $DIR/issue-45730.rs:8:13 @@ -26,7 +26,7 @@ LL | let x = 0 as *const i32 as *const _ as *mut _; | | | help: consider giving more type information | - = note: The type information given here is insufficient to check whether the pointer cast is valid + = note: the type information given here is insufficient to check whether the pointer cast is valid error: aborting due to 3 previous errors diff --git a/src/test/ui/lint/uninitialized-zeroed.stderr b/src/test/ui/lint/uninitialized-zeroed.stderr index bdb5959953f50..d451b827598f4 100644 --- a/src/test/ui/lint/uninitialized-zeroed.stderr +++ b/src/test/ui/lint/uninitialized-zeroed.stderr @@ -12,7 +12,7 @@ note: lint level defined here | LL | #![deny(invalid_value)] | ^^^^^^^^^^^^^ - = note: References must be non-null + = note: references must be non-null error: the type `&'static T` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:30:32 @@ -23,7 +23,7 @@ LL | let _val: &'static T = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: References must be non-null + = note: references must be non-null error: the type `Wrap<&'static T>` does not permit zero-initialization --> $DIR/uninitialized-zeroed.rs:32:38 @@ -34,7 +34,7 @@ LL | let _val: Wrap<&'static T> = mem::zeroed(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: References must be non-null (in this struct field) +note: references must be non-null (in this struct field) --> $DIR/uninitialized-zeroed.rs:18:18 | LL | struct Wrap { wrapped: T } @@ -49,7 +49,7 @@ LL | let _val: Wrap<&'static T> = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: References must be non-null (in this struct field) +note: references must be non-null (in this struct field) --> $DIR/uninitialized-zeroed.rs:18:18 | LL | struct Wrap { wrapped: T } @@ -64,7 +64,7 @@ LL | let _val: ! = mem::zeroed(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: The never type (`!`) has no valid value + = note: the `!` type has no valid value error: the type `!` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:41:23 @@ -75,7 +75,7 @@ LL | let _val: ! = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: The never type (`!`) has no valid value + = note: the `!` type has no valid value error: the type `(i32, !)` does not permit zero-initialization --> $DIR/uninitialized-zeroed.rs:43:30 @@ -86,7 +86,7 @@ LL | let _val: (i32, !) = mem::zeroed(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: The never type (`!`) has no valid value + = note: the `!` type has no valid value error: the type `(i32, !)` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:44:30 @@ -97,7 +97,7 @@ LL | let _val: (i32, !) = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: The never type (`!`) has no valid value + = note: the `!` type has no valid value error: the type `Void` does not permit zero-initialization --> $DIR/uninitialized-zeroed.rs:46:26 @@ -130,7 +130,7 @@ LL | let _val: &'static i32 = mem::zeroed(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: References must be non-null + = note: references must be non-null error: the type `&'static i32` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:50:34 @@ -141,7 +141,7 @@ LL | let _val: &'static i32 = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: References must be non-null + = note: references must be non-null error: the type `Ref` does not permit zero-initialization --> $DIR/uninitialized-zeroed.rs:52:25 @@ -152,7 +152,7 @@ LL | let _val: Ref = mem::zeroed(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: References must be non-null (in this struct field) +note: references must be non-null (in this struct field) --> $DIR/uninitialized-zeroed.rs:15:12 | LL | struct Ref(&'static i32); @@ -167,7 +167,7 @@ LL | let _val: Ref = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: References must be non-null (in this struct field) +note: references must be non-null (in this struct field) --> $DIR/uninitialized-zeroed.rs:15:12 | LL | struct Ref(&'static i32); @@ -182,7 +182,7 @@ LL | let _val: fn() = mem::zeroed(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: Function pointers must be non-null + = note: function pointers must be non-null error: the type `fn()` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:56:26 @@ -193,7 +193,7 @@ LL | let _val: fn() = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: Function pointers must be non-null + = note: function pointers must be non-null error: the type `Wrap` does not permit zero-initialization --> $DIR/uninitialized-zeroed.rs:58:32 @@ -204,7 +204,7 @@ LL | let _val: Wrap = mem::zeroed(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: Function pointers must be non-null (in this struct field) +note: function pointers must be non-null (in this struct field) --> $DIR/uninitialized-zeroed.rs:18:18 | LL | struct Wrap { wrapped: T } @@ -219,7 +219,7 @@ LL | let _val: Wrap = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: Function pointers must be non-null (in this struct field) +note: function pointers must be non-null (in this struct field) --> $DIR/uninitialized-zeroed.rs:18:18 | LL | struct Wrap { wrapped: T } @@ -234,7 +234,7 @@ LL | let _val: WrapEnum = mem::zeroed(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: Function pointers must be non-null (in this enum field) +note: function pointers must be non-null (in this enum field) --> $DIR/uninitialized-zeroed.rs:19:28 | LL | enum WrapEnum { Wrapped(T) } @@ -249,7 +249,7 @@ LL | let _val: WrapEnum = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: Function pointers must be non-null (in this enum field) +note: function pointers must be non-null (in this enum field) --> $DIR/uninitialized-zeroed.rs:19:28 | LL | enum WrapEnum { Wrapped(T) } @@ -264,7 +264,7 @@ LL | let _val: Wrap<(RefPair, i32)> = mem::zeroed(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: References must be non-null (in this struct field) +note: references must be non-null (in this struct field) --> $DIR/uninitialized-zeroed.rs:16:16 | LL | struct RefPair((&'static i32, i32)); @@ -279,7 +279,7 @@ LL | let _val: Wrap<(RefPair, i32)> = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: References must be non-null (in this struct field) +note: references must be non-null (in this struct field) --> $DIR/uninitialized-zeroed.rs:16:16 | LL | struct RefPair((&'static i32, i32)); @@ -316,7 +316,7 @@ LL | let _val: *const dyn Send = mem::zeroed(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: The vtable of a wide raw pointer must be non-null + = note: the vtable of a wide raw pointer must be non-null error: the type `*const dyn std::marker::Send` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:71:37 @@ -327,7 +327,7 @@ LL | let _val: *const dyn Send = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: The vtable of a wide raw pointer must be non-null + = note: the vtable of a wide raw pointer must be non-null error: the type `bool` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:75:26 @@ -338,7 +338,7 @@ LL | let _val: bool = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: Booleans must be `true` or `false` + = note: booleans must be either `true` or `false` error: the type `Wrap` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:78:32 @@ -349,7 +349,7 @@ LL | let _val: Wrap = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | -note: Characters must be a valid unicode codepoint (in this struct field) +note: characters must be a valid Unicode codepoint (in this struct field) --> $DIR/uninitialized-zeroed.rs:18:18 | LL | struct Wrap { wrapped: T } @@ -375,7 +375,7 @@ LL | let _val: &'static i32 = mem::transmute(0usize); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: References must be non-null + = note: references must be non-null error: the type `&'static [i32]` does not permit zero-initialization --> $DIR/uninitialized-zeroed.rs:85:36 @@ -386,7 +386,7 @@ LL | let _val: &'static [i32] = mem::transmute((0usize, 0usize)); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: References must be non-null + = note: references must be non-null error: the type `std::num::NonZeroU32` does not permit zero-initialization --> $DIR/uninitialized-zeroed.rs:86:32 @@ -430,7 +430,7 @@ LL | let _val: bool = MaybeUninit::uninit().assume_init(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: Booleans must be `true` or `false` + = note: booleans must be either `true` or `false` error: aborting due to 35 previous errors diff --git a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr index 3d79ff0b706f5..b4e18c229fdfd 100644 --- a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr +++ b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr @@ -1,4 +1,4 @@ -note: No external requirements +note: no external requirements --> $DIR/escape-argument-callee.rs:26:38 | LL | let mut closure = expect_sig(|p, y| *p = y); @@ -18,7 +18,7 @@ LL | let mut closure = expect_sig(|p, y| *p = y); | | has type `&'1 i32` | has type `&'_#2r mut &'2 i32` -note: No external requirements +note: no external requirements --> $DIR/escape-argument-callee.rs:20:1 | LL | / fn test() { diff --git a/src/test/ui/nll/closure-requirements/escape-argument.stderr b/src/test/ui/nll/closure-requirements/escape-argument.stderr index 37f04af6378d9..533a17bdd128b 100644 --- a/src/test/ui/nll/closure-requirements/escape-argument.stderr +++ b/src/test/ui/nll/closure-requirements/escape-argument.stderr @@ -1,4 +1,4 @@ -note: No external requirements +note: no external requirements --> $DIR/escape-argument.rs:26:38 | LL | let mut closure = expect_sig(|p, y| *p = y); @@ -9,7 +9,7 @@ LL | let mut closure = expect_sig(|p, y| *p = y); for<'r, 's> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BrNamed('r)) mut &ReLateBound(DebruijnIndex(0), BrNamed('s)) i32, &ReLateBound(DebruijnIndex(0), BrNamed('s)) i32)), ] -note: No external requirements +note: no external requirements --> $DIR/escape-argument.rs:20:1 | LL | / fn test() { diff --git a/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr b/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr index 810c0286cf218..60d02066e2676 100644 --- a/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr +++ b/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr @@ -1,4 +1,4 @@ -note: External requirements +note: external requirements --> $DIR/escape-upvar-nested.rs:21:32 | LL | let mut closure1 = || p = &y; @@ -13,7 +13,7 @@ LL | let mut closure1 = || p = &y; = note: number of external vids: 4 = note: where '_#1r: '_#3r -note: External requirements +note: external requirements --> $DIR/escape-upvar-nested.rs:20:27 | LL | let mut closure = || { @@ -32,7 +32,7 @@ LL | | }; = note: number of external vids: 4 = note: where '_#1r: '_#3r -note: No external requirements +note: no external requirements --> $DIR/escape-upvar-nested.rs:13:1 | LL | / fn test() { diff --git a/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr b/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr index bf042769a00e2..f64ccf14ac482 100644 --- a/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr +++ b/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr @@ -1,4 +1,4 @@ -note: External requirements +note: external requirements --> $DIR/escape-upvar-ref.rs:23:27 | LL | let mut closure = || p = &y; @@ -13,7 +13,7 @@ LL | let mut closure = || p = &y; = note: number of external vids: 4 = note: where '_#1r: '_#3r -note: No external requirements +note: no external requirements --> $DIR/escape-upvar-ref.rs:17:1 | LL | / fn test() { diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr index 4e3aa352fffdb..e1e0cdc153a6c 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr @@ -1,4 +1,4 @@ -note: No external requirements +note: no external requirements --> $DIR/propagate-approximated-fail-no-postdom.rs:43:9 | LL | / |_outlives1, _outlives2, _outlives3, x, y| { @@ -27,7 +27,7 @@ LL | |_outlives1, _outlives2, _outlives3, x, y| { LL | demand_y(x, y, p) | ^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` -note: No external requirements +note: no external requirements --> $DIR/propagate-approximated-fail-no-postdom.rs:38:1 | LL | / fn supply<'a, 'b, 'c>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>, cell_c: Cell<&'c u32>) { diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr index cd61b8b5e555e..b6535024a4a76 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-ref.stderr @@ -1,4 +1,4 @@ -note: External requirements +note: external requirements --> $DIR/propagate-approximated-ref.rs:43:47 | LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { @@ -18,7 +18,7 @@ LL | | }); = note: number of external vids: 5 = note: where '_#1r: '_#2r -note: No external requirements +note: no external requirements --> $DIR/propagate-approximated-ref.rs:42:1 | LL | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr index 259140c2e5a3d..708e50de570db 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr @@ -1,4 +1,4 @@ -note: No external requirements +note: no external requirements --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:21:15 | LL | foo(cell, |cell_a, cell_x| { @@ -23,7 +23,7 @@ LL | foo(cell, |cell_a, cell_x| { LL | cell_a.set(cell_x.get()); // forces 'x: 'a, error in closure | ^^^^^^^^^^^^^^^^^^^^^^^^ `cell_x` escapes the closure body here -note: No external requirements +note: no external requirements --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:18:1 | LL | / fn case1() { @@ -37,7 +37,7 @@ LL | | } | = note: defining type: case1 -note: External requirements +note: external requirements --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:35:15 | LL | foo(cell, |cell_a, cell_x| { @@ -53,7 +53,7 @@ LL | | }) = note: number of external vids: 2 = note: where '_#1r: '_#0r -note: No external requirements +note: no external requirements --> $DIR/propagate-approximated-shorter-to-static-comparing-against-free.rs:28:1 | LL | / fn case2() { diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr index b3dd682e4f0b7..17d33e82ba7e3 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr @@ -1,4 +1,4 @@ -note: External requirements +note: external requirements --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:32:47 | LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { @@ -19,7 +19,7 @@ LL | | }); = note: number of external vids: 4 = note: where '_#1r: '_#0r -note: No external requirements +note: no external requirements --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:31:1 | LL | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr index ab12d08f7b74e..5dce8d087d6cd 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr @@ -1,4 +1,4 @@ -note: External requirements +note: external requirements --> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:35:47 | LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { @@ -19,7 +19,7 @@ LL | | }); = note: number of external vids: 5 = note: where '_#1r: '_#0r -note: No external requirements +note: no external requirements --> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:34:1 | LL | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr index b2209e9cab0c9..5c5d510805bdf 100644 --- a/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-approximated-val.stderr @@ -1,4 +1,4 @@ -note: External requirements +note: external requirements --> $DIR/propagate-approximated-val.rs:36:45 | LL | establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| { @@ -18,7 +18,7 @@ LL | | }); = note: number of external vids: 5 = note: where '_#1r: '_#2r -note: No external requirements +note: no external requirements --> $DIR/propagate-approximated-val.rs:35:1 | LL | / fn test<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { diff --git a/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr b/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr index 55ee515a3a821..c111e651832ba 100644 --- a/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr @@ -1,4 +1,4 @@ -note: External requirements +note: external requirements --> $DIR/propagate-despite-same-free-region.rs:42:9 | LL | / |_outlives1, _outlives2, x, y| { @@ -16,7 +16,7 @@ LL | | }, = note: number of external vids: 4 = note: where '_#1r: '_#2r -note: No external requirements +note: no external requirements --> $DIR/propagate-despite-same-free-region.rs:39:1 | LL | / fn supply<'a>(cell_a: Cell<&'a u32>) { diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr index 1c29af8c42210..52df46ed3453f 100644 --- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr @@ -1,4 +1,4 @@ -note: No external requirements +note: no external requirements --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:35:47 | LL | establish_relationships(&cell_a, &cell_b, |_outlives, x, y| { @@ -27,7 +27,7 @@ LL | // Only works if 'x: 'y: LL | demand_y(x, y, x.get()) | ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` -note: No external requirements +note: no external requirements --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:34:1 | LL | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr index afa0e9f619ddc..0270cc40de6fc 100644 --- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr @@ -1,4 +1,4 @@ -note: No external requirements +note: no external requirements --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:39:47 | LL | establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| { @@ -27,7 +27,7 @@ LL | // Only works if 'x: 'y: LL | demand_y(x, y, x.get()) | ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` -note: No external requirements +note: no external requirements --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:38:1 | LL | / fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) { diff --git a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr index 0dbb530e698bb..5317bb6a1b13e 100644 --- a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr @@ -1,4 +1,4 @@ -note: External requirements +note: external requirements --> $DIR/propagate-from-trait-match.rs:32:36 | LL | establish_relationships(value, |value| { @@ -18,7 +18,7 @@ LL | | }); = note: number of external vids: 2 = note: where T: '_#1r -note: No external requirements +note: no external requirements --> $DIR/propagate-from-trait-match.rs:28:1 | LL | / fn supply<'a, T>(value: T) diff --git a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr index ca794d92666f2..79ed1501524bd 100644 --- a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr +++ b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr @@ -1,4 +1,4 @@ -note: No external requirements +note: no external requirements --> $DIR/return-wrong-bound-region.rs:11:16 | LL | expect_sig(|a, b| b); // ought to return `a` @@ -18,7 +18,7 @@ LL | expect_sig(|a, b| b); // ought to return `a` | | has type `&'1 i32` | has type `&'2 i32` -note: No external requirements +note: no external requirements --> $DIR/return-wrong-bound-region.rs:10:1 | LL | / fn test() { diff --git a/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr index c825227cdad8e..bff8c662d0def 100644 --- a/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr @@ -1,4 +1,4 @@ -note: External requirements +note: external requirements --> $DIR/projection-no-regions-closure.rs:25:23 | LL | with_signature(x, |mut y| Box::new(y.next())) @@ -11,7 +11,7 @@ LL | with_signature(x, |mut y| Box::new(y.next())) = note: number of external vids: 3 = note: where ::Item: '_#2r -note: No external requirements +note: no external requirements --> $DIR/projection-no-regions-closure.rs:21:1 | LL | / fn no_region<'a, T>(x: Box) -> Box @@ -33,7 +33,7 @@ LL | with_signature(x, |mut y| Box::new(y.next())) | = help: consider adding an explicit lifetime bound `::Item: ReEarlyBound(0, 'a)`... -note: External requirements +note: external requirements --> $DIR/projection-no-regions-closure.rs:34:23 | LL | with_signature(x, |mut y| Box::new(y.next())) @@ -46,7 +46,7 @@ LL | with_signature(x, |mut y| Box::new(y.next())) = note: number of external vids: 3 = note: where ::Item: '_#2r -note: No external requirements +note: no external requirements --> $DIR/projection-no-regions-closure.rs:30:1 | LL | / fn correct_region<'a, T>(x: Box) -> Box @@ -59,7 +59,7 @@ LL | | } | = note: defining type: correct_region::<'_#1r, T> -note: External requirements +note: external requirements --> $DIR/projection-no-regions-closure.rs:42:23 | LL | with_signature(x, |mut y| Box::new(y.next())) @@ -72,7 +72,7 @@ LL | with_signature(x, |mut y| Box::new(y.next())) = note: number of external vids: 4 = note: where ::Item: '_#3r -note: No external requirements +note: no external requirements --> $DIR/projection-no-regions-closure.rs:38:1 | LL | / fn wrong_region<'a, 'b, T>(x: Box) -> Box @@ -94,7 +94,7 @@ LL | with_signature(x, |mut y| Box::new(y.next())) | = help: consider adding an explicit lifetime bound `::Item: ReEarlyBound(0, 'a)`... -note: External requirements +note: external requirements --> $DIR/projection-no-regions-closure.rs:52:23 | LL | with_signature(x, |mut y| Box::new(y.next())) @@ -107,7 +107,7 @@ LL | with_signature(x, |mut y| Box::new(y.next())) = note: number of external vids: 4 = note: where ::Item: '_#3r -note: No external requirements +note: no external requirements --> $DIR/projection-no-regions-closure.rs:47:1 | LL | / fn outlives_region<'a, 'b, T>(x: Box) -> Box diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr index 7226c520bf138..6d1fbcb8f5bfd 100644 --- a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr @@ -1,4 +1,4 @@ -note: External requirements +note: external requirements --> $DIR/projection-one-region-closure.rs:45:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -13,7 +13,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: where T: '_#2r = note: where '_#1r: '_#2r -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-closure.rs:41:1 | LL | / fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T) @@ -48,7 +48,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); | = help: consider adding the following bound: `'b: 'a` -note: External requirements +note: external requirements --> $DIR/projection-one-region-closure.rs:56:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -62,7 +62,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: where T: '_#3r = note: where '_#2r: '_#3r -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-closure.rs:51:1 | LL | / fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T) @@ -97,7 +97,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); | = help: consider adding the following bound: `'b: 'a` -note: External requirements +note: external requirements --> $DIR/projection-one-region-closure.rs:70:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -110,7 +110,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: number of external vids: 4 = note: where >::AssocType: '_#3r -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-closure.rs:62:1 | LL | / fn projection_outlives<'a, 'b, T>(cell: Cell<&'a ()>, t: T) @@ -124,7 +124,7 @@ LL | | } | = note: defining type: projection_outlives::<'_#1r, '_#2r, T> -note: External requirements +note: external requirements --> $DIR/projection-one-region-closure.rs:80:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -138,7 +138,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: where T: '_#3r = note: where '_#2r: '_#3r -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-closure.rs:74:1 | LL | / fn elements_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T) diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr index 655995c1b8029..59d8aa484bdac 100644 --- a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-closure.stderr @@ -1,4 +1,4 @@ -note: External requirements +note: external requirements --> $DIR/projection-one-region-trait-bound-closure.rs:37:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -12,7 +12,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: number of external vids: 4 = note: where '_#1r: '_#2r -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-trait-bound-closure.rs:33:1 | LL | / fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T) @@ -39,7 +39,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); | = help: consider adding the following bound: `'b: 'a` -note: External requirements +note: external requirements --> $DIR/projection-one-region-trait-bound-closure.rs:47:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -52,7 +52,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: number of external vids: 4 = note: where '_#2r: '_#3r -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-trait-bound-closure.rs:42:1 | LL | / fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T) @@ -79,7 +79,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); | = help: consider adding the following bound: `'b: 'a` -note: External requirements +note: external requirements --> $DIR/projection-one-region-trait-bound-closure.rs:60:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -92,7 +92,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: number of external vids: 4 = note: where >::AssocType: '_#3r -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-trait-bound-closure.rs:52:1 | LL | / fn projection_outlives<'a, 'b, T>(cell: Cell<&'a ()>, t: T) @@ -106,7 +106,7 @@ LL | | } | = note: defining type: projection_outlives::<'_#1r, '_#2r, T> -note: External requirements +note: external requirements --> $DIR/projection-one-region-trait-bound-closure.rs:69:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -119,7 +119,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: number of external vids: 4 = note: where '_#2r: '_#3r -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-trait-bound-closure.rs:64:1 | LL | / fn elements_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T) @@ -133,7 +133,7 @@ LL | | } | = note: defining type: elements_outlive::<'_#1r, '_#2r, T> -note: External requirements +note: external requirements --> $DIR/projection-one-region-trait-bound-closure.rs:81:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -146,7 +146,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: number of external vids: 3 = note: where '_#1r: '_#2r -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-trait-bound-closure.rs:73:1 | LL | / fn one_region<'a, T>(cell: Cell<&'a ()>, t: T) diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr index 2fb07b9279aa8..c3b924577ab47 100644 --- a/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-one-region-trait-bound-static-closure.stderr @@ -1,4 +1,4 @@ -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-trait-bound-static-closure.rs:36:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -10,7 +10,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); ] = note: late-bound region is '_#3r -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-trait-bound-static-closure.rs:32:1 | LL | / fn no_relationships_late<'a, 'b, T>(cell: Cell<&'a ()>, t: T) @@ -23,7 +23,7 @@ LL | | } | = note: defining type: no_relationships_late::<'_#1r, T> -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-trait-bound-static-closure.rs:45:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -34,7 +34,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)), ] -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-trait-bound-static-closure.rs:40:1 | LL | / fn no_relationships_early<'a, 'b, T>(cell: Cell<&'a ()>, t: T) @@ -48,7 +48,7 @@ LL | | } | = note: defining type: no_relationships_early::<'_#1r, '_#2r, T> -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-trait-bound-static-closure.rs:64:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -59,7 +59,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)), ] -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-trait-bound-static-closure.rs:49:1 | LL | / fn projection_outlives<'a, 'b, T>(cell: Cell<&'a ()>, t: T) @@ -73,7 +73,7 @@ LL | | } | = note: defining type: projection_outlives::<'_#1r, '_#2r, T> -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-trait-bound-static-closure.rs:73:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -84,7 +84,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); extern "rust-call" fn((std::cell::Cell<&'_#3r ()>, T)), ] -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-trait-bound-static-closure.rs:68:1 | LL | / fn elements_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T) @@ -98,7 +98,7 @@ LL | | } | = note: defining type: elements_outlive::<'_#1r, '_#2r, T> -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-trait-bound-static-closure.rs:85:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -109,7 +109,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); extern "rust-call" fn((std::cell::Cell<&'_#2r ()>, T)), ] -note: No external requirements +note: no external requirements --> $DIR/projection-one-region-trait-bound-static-closure.rs:77:1 | LL | / fn one_region<'a, T>(cell: Cell<&'a ()>, t: T) diff --git a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr index 501a55e3105db..1bd97c1caa4ae 100644 --- a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr @@ -1,4 +1,4 @@ -note: External requirements +note: external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:38:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -12,7 +12,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: number of external vids: 5 = note: where >::AssocType: '_#3r -note: No external requirements +note: no external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:34:1 | LL | / fn no_relationships_late<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T) @@ -34,7 +34,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); | = help: consider adding an explicit lifetime bound `>::AssocType: ReFree(DefId(0:17 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_late[0]), BrNamed(DefId(0:18 ~ projection_two_region_trait_bound_closure[317d]::no_relationships_late[0]::'a[0]), 'a))`... -note: External requirements +note: external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:48:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -47,7 +47,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: number of external vids: 5 = note: where >::AssocType: '_#4r -note: No external requirements +note: no external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:43:1 | LL | / fn no_relationships_early<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T) @@ -69,7 +69,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); | = help: consider adding an explicit lifetime bound `>::AssocType: ReEarlyBound(0, 'a)`... -note: External requirements +note: external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:61:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -82,7 +82,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: number of external vids: 5 = note: where >::AssocType: '_#4r -note: No external requirements +note: no external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:53:1 | LL | / fn projection_outlives<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T) @@ -96,7 +96,7 @@ LL | | } | = note: defining type: projection_outlives::<'_#1r, '_#2r, '_#3r, T> -note: External requirements +note: external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:70:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -109,7 +109,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: number of external vids: 5 = note: where >::AssocType: '_#4r -note: No external requirements +note: no external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:65:1 | LL | / fn elements_outlive1<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T) @@ -123,7 +123,7 @@ LL | | } | = note: defining type: elements_outlive1::<'_#1r, '_#2r, '_#3r, T> -note: External requirements +note: external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:79:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -136,7 +136,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: number of external vids: 5 = note: where >::AssocType: '_#4r -note: No external requirements +note: no external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:74:1 | LL | / fn elements_outlive2<'a, 'b, 'c, T>(cell: Cell<&'a ()>, t: T) @@ -150,7 +150,7 @@ LL | | } | = note: defining type: elements_outlive2::<'_#1r, '_#2r, '_#3r, T> -note: External requirements +note: external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:87:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -164,7 +164,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: number of external vids: 4 = note: where >::AssocType: '_#2r -note: No external requirements +note: no external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:83:1 | LL | / fn two_regions<'a, 'b, T>(cell: Cell<&'a ()>, t: T) @@ -191,7 +191,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); | = help: consider adding the following bound: `'b: 'a` -note: External requirements +note: external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:97:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -204,7 +204,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: number of external vids: 4 = note: where >::AssocType: '_#3r -note: No external requirements +note: no external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:92:1 | LL | / fn two_regions_outlive<'a, 'b, T>(cell: Cell<&'a ()>, t: T) @@ -218,7 +218,7 @@ LL | | } | = note: defining type: two_regions_outlive::<'_#1r, '_#2r, T> -note: External requirements +note: external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:109:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); @@ -231,7 +231,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); = note: number of external vids: 3 = note: where >::AssocType: '_#2r -note: No external requirements +note: no external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:101:1 | LL | / fn one_region<'a, T>(cell: Cell<&'a ()>, t: T) diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr index db0bca1dec6f5..a213f423e3c8d 100644 --- a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr +++ b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr @@ -1,4 +1,4 @@ -note: External requirements +note: external requirements --> $DIR/ty-param-closure-approximate-lower-bound.rs:24:24 | LL | twice(cell, value, |a, b| invoke(a, b)); @@ -11,7 +11,7 @@ LL | twice(cell, value, |a, b| invoke(a, b)); = note: number of external vids: 2 = note: where T: '_#1r -note: No external requirements +note: no external requirements --> $DIR/ty-param-closure-approximate-lower-bound.rs:22:1 | LL | / fn generic(value: T) { @@ -22,7 +22,7 @@ LL | | } | = note: defining type: generic:: -note: External requirements +note: external requirements --> $DIR/ty-param-closure-approximate-lower-bound.rs:29:24 | LL | twice(cell, value, |a, b| invoke(a, b)); @@ -36,7 +36,7 @@ LL | twice(cell, value, |a, b| invoke(a, b)); = note: number of external vids: 3 = note: where T: '_#1r -note: No external requirements +note: no external requirements --> $DIR/ty-param-closure-approximate-lower-bound.rs:28:1 | LL | / fn generic_fail<'a, T>(cell: Cell<&'a ()>, value: T) { diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr index 0021d730f85a1..a488637bbc5c2 100644 --- a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr +++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr @@ -1,4 +1,4 @@ -note: External requirements +note: external requirements --> $DIR/ty-param-closure-outlives-from-return-type.rs:26:23 | LL | with_signature(x, |y| y) @@ -11,7 +11,7 @@ LL | with_signature(x, |y| y) = note: number of external vids: 3 = note: where T: '_#2r -note: No external requirements +note: no external requirements --> $DIR/ty-param-closure-outlives-from-return-type.rs:15:1 | LL | / fn no_region<'a, T>(x: Box) -> Box diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr index 46fef8ee5067b..62dfe94e38493 100644 --- a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr +++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr @@ -1,4 +1,4 @@ -note: External requirements +note: external requirements --> $DIR/ty-param-closure-outlives-from-where-clause.rs:27:26 | LL | with_signature(a, b, |x, y| { @@ -19,7 +19,7 @@ LL | | }) = note: number of external vids: 3 = note: where T: '_#1r -note: No external requirements +note: no external requirements --> $DIR/ty-param-closure-outlives-from-where-clause.rs:26:1 | LL | / fn no_region<'a, T>(a: Cell<&'a ()>, b: T) { @@ -48,7 +48,7 @@ LL | | }) | = help: consider adding an explicit lifetime bound `T: ReFree(DefId(0:11 ~ ty_param_closure_outlives_from_where_clause[317d]::no_region[0]), BrNamed(DefId(0:12 ~ ty_param_closure_outlives_from_where_clause[317d]::no_region[0]::'a[0]), 'a))`... -note: External requirements +note: external requirements --> $DIR/ty-param-closure-outlives-from-where-clause.rs:43:26 | LL | with_signature(a, b, |x, y| { @@ -68,7 +68,7 @@ LL | | }) = note: number of external vids: 3 = note: where T: '_#2r -note: No external requirements +note: no external requirements --> $DIR/ty-param-closure-outlives-from-where-clause.rs:39:1 | LL | / fn correct_region<'a, T>(a: Cell<&'a ()>, b: T) @@ -82,7 +82,7 @@ LL | | } | = note: defining type: correct_region::<'_#1r, T> -note: External requirements +note: external requirements --> $DIR/ty-param-closure-outlives-from-where-clause.rs:64:26 | LL | with_signature(a, b, |x, y| { @@ -101,7 +101,7 @@ LL | | }) = note: number of external vids: 4 = note: where T: '_#2r -note: No external requirements +note: no external requirements --> $DIR/ty-param-closure-outlives-from-where-clause.rs:60:1 | LL | / fn wrong_region<'a, 'b, T>(a: Cell<&'a ()>, b: T) @@ -128,7 +128,7 @@ LL | | }) | = help: consider adding an explicit lifetime bound `T: ReFree(DefId(0:19 ~ ty_param_closure_outlives_from_where_clause[317d]::wrong_region[0]), BrNamed(DefId(0:20 ~ ty_param_closure_outlives_from_where_clause[317d]::wrong_region[0]::'a[0]), 'a))`... -note: External requirements +note: external requirements --> $DIR/ty-param-closure-outlives-from-where-clause.rs:77:26 | LL | with_signature(a, b, |x, y| { @@ -145,7 +145,7 @@ LL | | }) = note: number of external vids: 4 = note: where T: '_#3r -note: No external requirements +note: no external requirements --> $DIR/ty-param-closure-outlives-from-where-clause.rs:72:1 | LL | / fn outlives_region<'a, 'b, T>(a: Cell<&'a ()>, b: T) diff --git a/src/test/ui/order-dependent-cast-inference.stderr b/src/test/ui/order-dependent-cast-inference.stderr index 081038c573acf..ad50b415869dd 100644 --- a/src/test/ui/order-dependent-cast-inference.stderr +++ b/src/test/ui/order-dependent-cast-inference.stderr @@ -6,7 +6,7 @@ LL | let mut y = 0 as *const _; | | | help: consider giving more type information | - = note: The type information given here is insufficient to check whether the pointer cast is valid + = note: the type information given here is insufficient to check whether the pointer cast is valid error: aborting due to previous error diff --git a/src/test/ui/test-attrs/test-should-panic-attr.stderr b/src/test/ui/test-attrs/test-should-panic-attr.stderr index 4b032eba5f8d5..d7d0d84432ce6 100644 --- a/src/test/ui/test-attrs/test-should-panic-attr.stderr +++ b/src/test/ui/test-attrs/test-should-panic-attr.stderr @@ -4,7 +4,7 @@ warning: argument must be of the form: `expected = "error message"` LL | #[should_panic(expected)] | ^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: Errors in this attribute were erroneously allowed and will become a hard error in a future release. + = note: errors in this attribute were erroneously allowed and will become a hard error in a future release. warning: argument must be of the form: `expected = "error message"` --> $DIR/test-should-panic-attr.rs:18:1 @@ -12,7 +12,7 @@ warning: argument must be of the form: `expected = "error message"` LL | #[should_panic(expect)] | ^^^^^^^^^^^^^^^^^^^^^^^ | - = note: Errors in this attribute were erroneously allowed and will become a hard error in a future release. + = note: errors in this attribute were erroneously allowed and will become a hard error in a future release. warning: argument must be of the form: `expected = "error message"` --> $DIR/test-should-panic-attr.rs:25:1 @@ -20,7 +20,7 @@ warning: argument must be of the form: `expected = "error message"` LL | #[should_panic(expected(foo, bar))] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: Errors in this attribute were erroneously allowed and will become a hard error in a future release. + = note: errors in this attribute were erroneously allowed and will become a hard error in a future release. warning: argument must be of the form: `expected = "error message"` --> $DIR/test-should-panic-attr.rs:32:1 @@ -28,5 +28,5 @@ warning: argument must be of the form: `expected = "error message"` LL | #[should_panic(expected = "foo", bar)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: Errors in this attribute were erroneously allowed and will become a hard error in a future release. + = note: errors in this attribute were erroneously allowed and will become a hard error in a future release. diff --git a/src/test/ui/traits/trait-bounds-same-crate-name.rs b/src/test/ui/traits/trait-bounds-same-crate-name.rs index af720ecfdc063..1012edb109336 100644 --- a/src/test/ui/traits/trait-bounds-same-crate-name.rs +++ b/src/test/ui/traits/trait-bounds-same-crate-name.rs @@ -31,7 +31,7 @@ fn main() { a::try_foo(foo); //~^ ERROR E0277 //~| trait impl with same name found - //~| Perhaps two different versions of crate `crate_a2` + //~| perhaps two different versions of crate `crate_a2` // We don't want to see the "version mismatch" help message here // because `implements_no_traits` has no impl for `Foo` diff --git a/src/test/ui/traits/trait-bounds-same-crate-name.stderr b/src/test/ui/traits/trait-bounds-same-crate-name.stderr index 8fd0bd13e54b3..8a6e059604d2b 100644 --- a/src/test/ui/traits/trait-bounds-same-crate-name.stderr +++ b/src/test/ui/traits/trait-bounds-same-crate-name.stderr @@ -14,7 +14,7 @@ help: trait impl with same name found | LL | impl Bar for Foo {} | ^^^^^^^^^^^^^^^^^^^ - = note: Perhaps two different versions of crate `crate_a2` are being used? + = note: perhaps two different versions of crate `crate_a2` are being used? error[E0277]: the trait bound `main::a::DoesNotImplementTrait: main::a::Bar` is not satisfied --> $DIR/trait-bounds-same-crate-name.rs:38:20 @@ -43,7 +43,7 @@ help: trait impl with same name found | LL | impl Bar for ImplementsWrongTraitConditionally {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: Perhaps two different versions of crate `crate_a2` are being used? + = note: perhaps two different versions of crate `crate_a2` are being used? error[E0277]: the trait bound `main::a::ImplementsTraitForUsize: main::a::Bar` is not satisfied --> $DIR/trait-bounds-same-crate-name.rs:51:20 From 8461fa51198ad5db1d070620fe4186aaec648438 Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 10 Jan 2020 14:36:22 +0000 Subject: [PATCH 021/169] Diagnostics should not end with a full stop --- src/libcore/lib.rs | 2 +- src/librustc/middle/lang_items.rs | 6 +++--- src/librustc_passes/diagnostic_items.rs | 2 +- src/librustc_resolve/lib.rs | 2 +- src/librustc_typeck/check/mod.rs | 2 +- src/libstd/panicking.rs | 2 +- src/test/compile-fail/panic-handler-twice.rs | 2 +- .../mutually-recursive-async-impl-trait-type.stderr | 4 ++-- .../ui/async-await/recursive-async-impl-trait-type.stderr | 2 +- src/test/ui/consts/miri_unleashed/mutable_const2.stderr | 2 +- .../ui/consts/miri_unleashed/mutable_references_ice.stderr | 2 +- src/test/ui/duplicate_entry_error.rs | 2 +- src/test/ui/duplicate_entry_error.stderr | 4 ++-- src/test/ui/error-codes/E0152.stderr | 4 ++-- src/test/ui/keyword/keyword-super-as-identifier.rs | 2 +- src/test/ui/keyword/keyword-super-as-identifier.stderr | 4 ++-- src/test/ui/keyword/keyword-super.rs | 2 +- src/test/ui/keyword/keyword-super.stderr | 4 ++-- src/test/ui/multi-panic.rs | 2 +- src/test/ui/panic-handler/panic-handler-duplicate.rs | 2 +- src/test/ui/panic-handler/panic-handler-duplicate.stderr | 4 ++-- src/test/ui/panic-handler/panic-handler-std.rs | 2 +- src/test/ui/panic-handler/panic-handler-std.stderr | 4 ++-- src/test/ui/pattern/const-pat-ice.stderr | 2 +- src/test/ui/resolve/impl-items-vis-unresolved.rs | 2 +- src/test/ui/resolve/impl-items-vis-unresolved.stderr | 4 ++-- src/test/ui/super-at-top-level.rs | 2 +- src/test/ui/super-at-top-level.stderr | 4 ++-- src/test/ui/test-panic-abort.run.stdout | 2 +- 29 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 95ffe4f438f5f..15720ddcfc677 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -44,7 +44,7 @@ // Here we explicitly #[cfg]-out this whole crate when testing. If we don't do // this, both the generated test artifact and the linked libtest (which // transitively includes libcore) will both define the same set of lang items, -// and this will cause the E0152 "duplicate lang item found" error. See +// and this will cause the E0152 "found duplicate lang item" error. See // discussion in #50466 for details. // // This cfg won't affect doc tests. diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 42fc3e030e7bb..643359f098b4d 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -184,7 +184,7 @@ impl LanguageItemCollector<'tcx> { self.tcx.sess, span, E0152, - "duplicate lang item found: `{}`.", + "found duplicate lang item `{}`", name ), None => { @@ -206,12 +206,12 @@ impl LanguageItemCollector<'tcx> { }, }; if let Some(span) = self.tcx.hir().span_if_local(original_def_id) { - err.span_note(span, "first defined here."); + err.span_note(span, "first defined here"); } else { match self.tcx.extern_crate(original_def_id) { Some(ExternCrate {dependency_of, ..}) => { err.note(&format!( - "first defined in crate `{}` (which `{}` depends on).", + "first defined in crate `{}` (which `{}` depends on)", self.tcx.crate_name(original_def_id.krate), self.tcx.crate_name(*dependency_of))); }, diff --git a/src/librustc_passes/diagnostic_items.rs b/src/librustc_passes/diagnostic_items.rs index c083830b730cc..8d220a3f695f2 100644 --- a/src/librustc_passes/diagnostic_items.rs +++ b/src/librustc_passes/diagnostic_items.rs @@ -73,7 +73,7 @@ fn collect_item( )), }; if let Some(span) = tcx.hir().span_if_local(original_def_id) { - err.span_note(span, "first defined here."); + err.span_note(span, "first defined here"); } else { err.note(&format!( "first defined in crate `{}`.", diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 8e4630cf7d696..8d5afb194a175 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2006,7 +2006,7 @@ impl<'a> Resolver<'a> { continue; } } - let msg = "there are too many initial `super`s.".to_string(); + let msg = "there are too many leading `super` keywords".to_string(); return PathResult::Failed { span: ident.span, label: msg, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 92a7e18a8600f..baf9ae1ac2911 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1664,7 +1664,7 @@ fn check_opaque_for_cycles<'tcx>( if let hir::OpaqueTyOrigin::AsyncFn = origin { struct_span_err!(tcx.sess, span, E0733, "recursion in an `async fn` requires boxing",) .span_label(span, "recursive `async fn`") - .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`.") + .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`") .emit(); } else { let mut err = diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index 599ccc809be1f..f773a8276e354 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -199,7 +199,7 @@ fn default_hook(info: &PanicInfo<'_>) { let _ = writeln!( err, "note: run with `RUST_BACKTRACE=1` \ - environment variable to display a backtrace." + environment variable to display a backtrace" ); } } diff --git a/src/test/compile-fail/panic-handler-twice.rs b/src/test/compile-fail/panic-handler-twice.rs index c0f2c51397ed9..0c5359b9bd8c6 100644 --- a/src/test/compile-fail/panic-handler-twice.rs +++ b/src/test/compile-fail/panic-handler-twice.rs @@ -10,7 +10,7 @@ use core::panic::PanicInfo; #[panic_handler] fn panic(info: &PanicInfo) -> ! { - //~^ error duplicate lang item found: `panic_impl` + //~^ ERROR found duplicate lang item `panic_impl` loop {} } diff --git a/src/test/ui/async-await/mutually-recursive-async-impl-trait-type.stderr b/src/test/ui/async-await/mutually-recursive-async-impl-trait-type.stderr index 9249308936e54..f6e4c8be29260 100644 --- a/src/test/ui/async-await/mutually-recursive-async-impl-trait-type.stderr +++ b/src/test/ui/async-await/mutually-recursive-async-impl-trait-type.stderr @@ -4,7 +4,7 @@ error[E0733]: recursion in an `async fn` requires boxing LL | async fn rec_1() { | ^ recursive `async fn` | - = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`. + = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future` error[E0733]: recursion in an `async fn` requires boxing --> $DIR/mutually-recursive-async-impl-trait-type.rs:9:18 @@ -12,7 +12,7 @@ error[E0733]: recursion in an `async fn` requires boxing LL | async fn rec_2() { | ^ recursive `async fn` | - = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`. + = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future` error: aborting due to 2 previous errors diff --git a/src/test/ui/async-await/recursive-async-impl-trait-type.stderr b/src/test/ui/async-await/recursive-async-impl-trait-type.stderr index 9ee014021804e..892d91e3a4992 100644 --- a/src/test/ui/async-await/recursive-async-impl-trait-type.stderr +++ b/src/test/ui/async-await/recursive-async-impl-trait-type.stderr @@ -4,7 +4,7 @@ error[E0733]: recursion in an `async fn` requires boxing LL | async fn recursive_async_function() -> () { | ^^ recursive `async fn` | - = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`. + = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future` error: aborting due to previous error diff --git a/src/test/ui/consts/miri_unleashed/mutable_const2.stderr b/src/test/ui/consts/miri_unleashed/mutable_const2.stderr index 88418e57acdda..655c31763ef44 100644 --- a/src/test/ui/consts/miri_unleashed/mutable_const2.stderr +++ b/src/test/ui/consts/miri_unleashed/mutable_const2.stderr @@ -11,7 +11,7 @@ LL | const MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *m | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:346:17 -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace error: internal compiler error: unexpected panic diff --git a/src/test/ui/consts/miri_unleashed/mutable_references_ice.stderr b/src/test/ui/consts/miri_unleashed/mutable_references_ice.stderr index c148842bcbc66..c292fcef7f660 100644 --- a/src/test/ui/consts/miri_unleashed/mutable_references_ice.stderr +++ b/src/test/ui/consts/miri_unleashed/mutable_references_ice.stderr @@ -7,7 +7,7 @@ LL | x: &UnsafeCell::new(42), thread 'rustc' panicked at 'assertion failed: `(left != right)` left: `Const`, right: `Const`: UnsafeCells are not allowed behind references in constants. This should have been prevented statically by const qualification. If this were allowed one would be able to change a constant at one use site and other use sites could observe that mutation.', src/librustc_mir/interpret/intern.rs:LL:CC -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace error: internal compiler error: unexpected panic diff --git a/src/test/ui/duplicate_entry_error.rs b/src/test/ui/duplicate_entry_error.rs index 62df42b1a6890..b8d98a8999b9d 100644 --- a/src/test/ui/duplicate_entry_error.rs +++ b/src/test/ui/duplicate_entry_error.rs @@ -8,7 +8,7 @@ use std::panic::PanicInfo; #[lang = "panic_impl"] fn panic_impl(info: &PanicInfo) -> ! { -//~^ ERROR: duplicate lang item found: `panic_impl`. +//~^ ERROR: found duplicate lang item `panic_impl` loop {} } diff --git a/src/test/ui/duplicate_entry_error.stderr b/src/test/ui/duplicate_entry_error.stderr index 02be11d1fd0e5..46b137b2cf9c0 100644 --- a/src/test/ui/duplicate_entry_error.stderr +++ b/src/test/ui/duplicate_entry_error.stderr @@ -1,4 +1,4 @@ -error[E0152]: duplicate lang item found: `panic_impl`. +error[E0152]: found duplicate lang item `panic_impl` --> $DIR/duplicate_entry_error.rs:10:1 | LL | / fn panic_impl(info: &PanicInfo) -> ! { @@ -7,7 +7,7 @@ LL | | loop {} LL | | } | |_^ | - = note: first defined in crate `std` (which `duplicate_entry_error` depends on). + = note: first defined in crate `std` (which `duplicate_entry_error` depends on) error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0152.stderr b/src/test/ui/error-codes/E0152.stderr index d4b59a1148e60..c41a0430150a4 100644 --- a/src/test/ui/error-codes/E0152.stderr +++ b/src/test/ui/error-codes/E0152.stderr @@ -1,10 +1,10 @@ -error[E0152]: duplicate lang item found: `arc`. +error[E0152]: found duplicate lang item `arc` --> $DIR/E0152.rs:4:1 | LL | struct Foo; | ^^^^^^^^^^^ | - = note: first defined in crate `alloc` (which `std` depends on). + = note: first defined in crate `alloc` (which `std` depends on) error: aborting due to previous error diff --git a/src/test/ui/keyword/keyword-super-as-identifier.rs b/src/test/ui/keyword/keyword-super-as-identifier.rs index d728b4fe3e241..02c1b27b08a96 100644 --- a/src/test/ui/keyword/keyword-super-as-identifier.rs +++ b/src/test/ui/keyword/keyword-super-as-identifier.rs @@ -1,3 +1,3 @@ fn main() { - let super = 22; //~ ERROR failed to resolve: there are too many initial `super`s + let super = 22; //~ ERROR failed to resolve: there are too many leading `super` keywords } diff --git a/src/test/ui/keyword/keyword-super-as-identifier.stderr b/src/test/ui/keyword/keyword-super-as-identifier.stderr index bbeaed9428795..1f64f3b73d6cd 100644 --- a/src/test/ui/keyword/keyword-super-as-identifier.stderr +++ b/src/test/ui/keyword/keyword-super-as-identifier.stderr @@ -1,8 +1,8 @@ -error[E0433]: failed to resolve: there are too many initial `super`s. +error[E0433]: failed to resolve: there are too many leading `super` keywords --> $DIR/keyword-super-as-identifier.rs:2:9 | LL | let super = 22; - | ^^^^^ there are too many initial `super`s. + | ^^^^^ there are too many leading `super` keywords error: aborting due to previous error diff --git a/src/test/ui/keyword/keyword-super.rs b/src/test/ui/keyword/keyword-super.rs index a43e1e39b6797..c121a6c1050ea 100644 --- a/src/test/ui/keyword/keyword-super.rs +++ b/src/test/ui/keyword/keyword-super.rs @@ -1,3 +1,3 @@ fn main() { - let super: isize; //~ ERROR failed to resolve: there are too many initial `super`s + let super: isize; //~ ERROR failed to resolve: there are too many leading `super` keywords } diff --git a/src/test/ui/keyword/keyword-super.stderr b/src/test/ui/keyword/keyword-super.stderr index 63394c7852a5d..0e0d67cb97b1f 100644 --- a/src/test/ui/keyword/keyword-super.stderr +++ b/src/test/ui/keyword/keyword-super.stderr @@ -1,8 +1,8 @@ -error[E0433]: failed to resolve: there are too many initial `super`s. +error[E0433]: failed to resolve: there are too many leading `super` keywords --> $DIR/keyword-super.rs:2:9 | LL | let super: isize; - | ^^^^^ there are too many initial `super`s. + | ^^^^^ there are too many leading `super` keywords error: aborting due to previous error diff --git a/src/test/ui/multi-panic.rs b/src/test/ui/multi-panic.rs index e4b41e4180664..0f8bddf27fe08 100644 --- a/src/test/ui/multi-panic.rs +++ b/src/test/ui/multi-panic.rs @@ -10,7 +10,7 @@ fn check_for_no_backtrace(test: std::process::Output) { assert_eq!(it.next().map(|l| l.starts_with("thread '' panicked at")), Some(true)); assert_eq!(it.next(), Some("note: run with `RUST_BACKTRACE=1` \ - environment variable to display a backtrace.")); + environment variable to display a backtrace")); assert_eq!(it.next().map(|l| l.starts_with("thread 'main' panicked at")), Some(true)); assert_eq!(it.next(), None); } diff --git a/src/test/ui/panic-handler/panic-handler-duplicate.rs b/src/test/ui/panic-handler/panic-handler-duplicate.rs index caa130ef460f1..bd99af999c797 100644 --- a/src/test/ui/panic-handler/panic-handler-duplicate.rs +++ b/src/test/ui/panic-handler/panic-handler-duplicate.rs @@ -12,6 +12,6 @@ fn panic(info: &PanicInfo) -> ! { } #[lang = "panic_impl"] -fn panic2(info: &PanicInfo) -> ! { //~ ERROR duplicate lang item found: `panic_impl`. +fn panic2(info: &PanicInfo) -> ! { //~ ERROR found duplicate lang item `panic_impl` loop {} } diff --git a/src/test/ui/panic-handler/panic-handler-duplicate.stderr b/src/test/ui/panic-handler/panic-handler-duplicate.stderr index e9b1945364372..9999e3276469d 100644 --- a/src/test/ui/panic-handler/panic-handler-duplicate.stderr +++ b/src/test/ui/panic-handler/panic-handler-duplicate.stderr @@ -1,4 +1,4 @@ -error[E0152]: duplicate lang item found: `panic_impl`. +error[E0152]: found duplicate lang item `panic_impl` --> $DIR/panic-handler-duplicate.rs:15:1 | LL | / fn panic2(info: &PanicInfo) -> ! { @@ -6,7 +6,7 @@ LL | | loop {} LL | | } | |_^ | -note: first defined here. +note: first defined here --> $DIR/panic-handler-duplicate.rs:10:1 | LL | / fn panic(info: &PanicInfo) -> ! { diff --git a/src/test/ui/panic-handler/panic-handler-std.rs b/src/test/ui/panic-handler/panic-handler-std.rs index fffb5977871d8..0acc2722cb21f 100644 --- a/src/test/ui/panic-handler/panic-handler-std.rs +++ b/src/test/ui/panic-handler/panic-handler-std.rs @@ -1,4 +1,4 @@ -// error-pattern: duplicate lang item found: `panic_impl`. +// error-pattern: found duplicate lang item `panic_impl` use std::panic::PanicInfo; diff --git a/src/test/ui/panic-handler/panic-handler-std.stderr b/src/test/ui/panic-handler/panic-handler-std.stderr index e6d24348ca825..ac56513fd4706 100644 --- a/src/test/ui/panic-handler/panic-handler-std.stderr +++ b/src/test/ui/panic-handler/panic-handler-std.stderr @@ -1,4 +1,4 @@ -error[E0152]: duplicate lang item found: `panic_impl`. +error[E0152]: found duplicate lang item `panic_impl` --> $DIR/panic-handler-std.rs:7:1 | LL | / fn panic(info: PanicInfo) -> ! { @@ -6,7 +6,7 @@ LL | | loop {} LL | | } | |_^ | - = note: first defined in crate `std` (which `panic_handler_std` depends on). + = note: first defined in crate `std` (which `panic_handler_std` depends on) error: argument should be `&PanicInfo` --> $DIR/panic-handler-std.rs:7:16 diff --git a/src/test/ui/pattern/const-pat-ice.stderr b/src/test/ui/pattern/const-pat-ice.stderr index 7217fe1b02f4e..d0018cef5f033 100644 --- a/src/test/ui/pattern/const-pat-ice.stderr +++ b/src/test/ui/pattern/const-pat-ice.stderr @@ -1,5 +1,5 @@ thread 'rustc' panicked at 'assertion failed: rows.iter().all(|r| r.len() == v.len())', src/librustc_mir_build/hair/pattern/_match.rs:LL:CC -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace error: internal compiler error: unexpected panic diff --git a/src/test/ui/resolve/impl-items-vis-unresolved.rs b/src/test/ui/resolve/impl-items-vis-unresolved.rs index 9b4fe498239b6..a124b4eff8f69 100644 --- a/src/test/ui/resolve/impl-items-vis-unresolved.rs +++ b/src/test/ui/resolve/impl-items-vis-unresolved.rs @@ -18,7 +18,7 @@ mod state { pub struct RawFloatState; impl RawFloatState { perftools_inline! { - pub(super) fn new() {} //~ ERROR failed to resolve: there are too many initial `super`s + pub(super) fn new() {} //~ ERROR failed to resolve: there are too many leading `super` keywords } } diff --git a/src/test/ui/resolve/impl-items-vis-unresolved.stderr b/src/test/ui/resolve/impl-items-vis-unresolved.stderr index 8e285e5312400..62cffe55f9fb6 100644 --- a/src/test/ui/resolve/impl-items-vis-unresolved.stderr +++ b/src/test/ui/resolve/impl-items-vis-unresolved.stderr @@ -1,8 +1,8 @@ -error[E0433]: failed to resolve: there are too many initial `super`s. +error[E0433]: failed to resolve: there are too many leading `super` keywords --> $DIR/impl-items-vis-unresolved.rs:21:13 | LL | pub(super) fn new() {} - | ^^^^^ there are too many initial `super`s. + | ^^^^^ there are too many leading `super` keywords. error: aborting due to previous error diff --git a/src/test/ui/super-at-top-level.rs b/src/test/ui/super-at-top-level.rs index 41360df77994e..e4d587bc9effa 100644 --- a/src/test/ui/super-at-top-level.rs +++ b/src/test/ui/super-at-top-level.rs @@ -1,4 +1,4 @@ -use super::f; //~ ERROR there are too many initial `super`s +use super::f; //~ ERROR there are too many leading `super` keywords fn main() { } diff --git a/src/test/ui/super-at-top-level.stderr b/src/test/ui/super-at-top-level.stderr index d04ce384fe886..23613df6752fb 100644 --- a/src/test/ui/super-at-top-level.stderr +++ b/src/test/ui/super-at-top-level.stderr @@ -1,8 +1,8 @@ -error[E0433]: failed to resolve: there are too many initial `super`s. +error[E0433]: failed to resolve: there are too many leading `super` keywords --> $DIR/super-at-top-level.rs:1:5 | LL | use super::f; - | ^^^^^ there are too many initial `super`s. + | ^^^^^ there are too many leading `super` keywords error: aborting due to previous error diff --git a/src/test/ui/test-panic-abort.run.stdout b/src/test/ui/test-panic-abort.run.stdout index 0c8bc5020871b..46adcfbc2eb4a 100644 --- a/src/test/ui/test-panic-abort.run.stdout +++ b/src/test/ui/test-panic-abort.run.stdout @@ -18,7 +18,7 @@ testing321 thread 'main' panicked at 'assertion failed: `(left == right)` left: `2`, right: `5`', $DIR/test-panic-abort.rs:31:5 -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace failures: From e84248921b44c9fdf3d6638c170ffde733074ff8 Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 10 Jan 2020 14:57:36 +0000 Subject: [PATCH 022/169] Add backticks in appropriate places --- src/librustc_lint/builtin.rs | 9 ++-- src/librustc_parse/parser/attr.rs | 4 +- src/librustc_resolve/build_reduced_graph.rs | 6 +-- src/librustc_typeck/check/method/suggest.rs | 2 +- .../validate_uninhabited_zsts.stderr | 2 +- .../deprecated-macro_escape-inner.rs | 2 +- .../deprecated-macro_escape-inner.stderr | 2 +- .../ui/deprecation/deprecated-macro_escape.rs | 8 ++-- .../deprecated-macro_escape.stderr | 2 +- .../issue-43106-gating-of-builtin-attrs.rs | 4 +- ...issue-43106-gating-of-builtin-attrs.stderr | 4 +- .../issue-43106-gating-of-macro_escape.rs | 2 +- .../issue-43106-gating-of-macro_escape.stderr | 2 +- .../issue-43106-gating-of-macro_use.rs | 6 +-- .../issue-43106-gating-of-macro_use.stderr | 6 +-- .../extern-crate-self-fail.rs | 2 +- .../extern-crate-self-fail.stderr | 2 +- src/test/ui/issues/issue-29124.stderr | 4 +- src/test/ui/issues/issue-57362-1.stderr | 2 +- src/test/ui/lint/uninitialized-zeroed.stderr | 16 +++---- .../malformed/malformed-interpolated.stderr | 2 +- src/test/ui/module-macro_use-arguments.rs | 2 +- src/test/ui/module-macro_use-arguments.stderr | 2 +- src/test/ui/suffixed-literal-meta.stderr | 48 +++++++++---------- ...ed-closures-static-call-wrong-trait.stderr | 2 +- 25 files changed, 72 insertions(+), 71 deletions(-) diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 7f55bcd4017ef..fea0b012f91b3 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -1959,13 +1959,16 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue { // return `Bound::Excluded`. (And we have tests checking that we // handle the attribute correctly.) (Bound::Included(lo), _) if lo > 0 => { - return Some((format!("{} must be non-null", ty), None)); + return Some((format!("`{}` must be non-null", ty), None)); } (Bound::Included(_), _) | (_, Bound::Included(_)) if init == InitKind::Uninit => { return Some(( - format!("{} must be initialized inside its custom valid range", ty), + format!( + "`{}` must be initialized inside its custom valid range", + ty, + ), None, )); } @@ -1973,7 +1976,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidValue { } // Now, recurse. match adt_def.variants.len() { - 0 => Some((format!("0-variant enums have no valid value"), None)), + 0 => Some((format!("enums with no variants have no valid value"), None)), 1 => { // Struct, or enum with exactly one variant. // Proceed recursively, check all fields. diff --git a/src/librustc_parse/parser/attr.rs b/src/librustc_parse/parser/attr.rs index 81f31b2eda1d4..3d40b91a7bdc8 100644 --- a/src/librustc_parse/parser/attr.rs +++ b/src/librustc_parse/parser/attr.rs @@ -236,8 +236,8 @@ impl<'a> Parser<'a> { self.struct_span_err(lit.span, msg) .help( "instead of using a suffixed literal \ - (1u8, 1.0f32, etc.), use an unsuffixed version \ - (1, 1.0, etc.).", + (`1u8`, `1.0f32`, etc.), use an unsuffixed version \ + (`1`, `1.0`, etc.)", ) .emit() } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 291386413d647..9c80df367c09c 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -963,7 +963,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { .session .struct_span_err( attr.span, - "`macro_use` is not supported on `extern crate self`", + "`#[macro_use]` is not supported on `extern crate self`", ) .emit(); } @@ -1054,7 +1054,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { fn contains_macro_use(&mut self, attrs: &[ast::Attribute]) -> bool { for attr in attrs { if attr.check_name(sym::macro_escape) { - let msg = "macro_escape is a deprecated synonym for macro_use"; + let msg = "`#[macro_escape]` is a deprecated synonym for `#[macro_use]`"; let mut err = self.r.session.struct_span_warn(attr.span, msg); if let ast::AttrStyle::Inner = attr.style { err.help("consider an outer attribute, `#[macro_use]` mod ...").emit(); @@ -1066,7 +1066,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { } if !attr.is_word() { - self.r.session.span_err(attr.span, "arguments to macro_use are not allowed here"); + self.r.session.span_err(attr.span, "arguments to `macro_use` are not allowed here"); } return true; } diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index b84e1d37b06ff..d6c0d9c77b495 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -479,7 +479,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { macro_rules! report_function { ($span:expr, $name:expr) => { err.note(&format!( - "{} is a function, perhaps you wish to call it", + "`{}` is a function, perhaps you wish to call it", $name )); }; diff --git a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr index 040c568beb324..51e80bb8b118b 100644 --- a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr +++ b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.stderr @@ -45,7 +45,7 @@ LL | const BAR: [Empty; 3] = [unsafe { std::mem::transmute(()) }; 3]; | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: 0-variant enums have no valid value + = note: enums with no variants have no valid value error: aborting due to previous error diff --git a/src/test/ui/deprecation/deprecated-macro_escape-inner.rs b/src/test/ui/deprecation/deprecated-macro_escape-inner.rs index 957e839013ec7..e2957c422f6d5 100644 --- a/src/test/ui/deprecation/deprecated-macro_escape-inner.rs +++ b/src/test/ui/deprecation/deprecated-macro_escape-inner.rs @@ -1,7 +1,7 @@ // run-pass mod foo { - #![macro_escape] //~ WARNING macro_escape is a deprecated synonym for macro_use + #![macro_escape] //~ WARN `#[macro_escape]` is a deprecated synonym for `#[macro_use]` } fn main() { diff --git a/src/test/ui/deprecation/deprecated-macro_escape-inner.stderr b/src/test/ui/deprecation/deprecated-macro_escape-inner.stderr index 1b69270d624f4..65db62ce26355 100644 --- a/src/test/ui/deprecation/deprecated-macro_escape-inner.stderr +++ b/src/test/ui/deprecation/deprecated-macro_escape-inner.stderr @@ -1,4 +1,4 @@ -warning: macro_escape is a deprecated synonym for macro_use +warning: `#[macro_escape]` is a deprecated synonym for `#[macro_use]` --> $DIR/deprecated-macro_escape-inner.rs:4:5 | LL | #![macro_escape] diff --git a/src/test/ui/deprecation/deprecated-macro_escape.rs b/src/test/ui/deprecation/deprecated-macro_escape.rs index 1b82a99f42eab..4a89b40625e68 100644 --- a/src/test/ui/deprecation/deprecated-macro_escape.rs +++ b/src/test/ui/deprecation/deprecated-macro_escape.rs @@ -1,8 +1,6 @@ // run-pass -#[macro_escape] //~ WARNING macro_escape is a deprecated synonym for macro_use -mod foo { -} +#[macro_escape] //~ WARNING `#[macro_escape]` is a deprecated synonym for `#[macro_use]` +mod foo {} -fn main() { -} +fn main() {} diff --git a/src/test/ui/deprecation/deprecated-macro_escape.stderr b/src/test/ui/deprecation/deprecated-macro_escape.stderr index b76d6d73d972b..70094083d4b34 100644 --- a/src/test/ui/deprecation/deprecated-macro_escape.stderr +++ b/src/test/ui/deprecation/deprecated-macro_escape.stderr @@ -1,4 +1,4 @@ -warning: macro_escape is a deprecated synonym for macro_use +warning: `#[macro_escape]` is a deprecated synonym for `#[macro_use]` --> $DIR/deprecated-macro_escape.rs:3:1 | LL | #[macro_escape] diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs index 0d804f012bcc3..8609108831e7c 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs +++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.rs @@ -464,10 +464,10 @@ mod reexport_test_harness_main { // Cannot feed "2700" to `#[macro_escape]` without signaling an error. #[macro_escape] -//~^ WARN macro_escape is a deprecated synonym for macro_use +//~^ WARN `#[macro_escape]` is a deprecated synonym for `#[macro_use]` mod macro_escape { mod inner { #![macro_escape] } - //~^ WARN macro_escape is a deprecated synonym for macro_use + //~^ WARN `#[macro_escape]` is a deprecated synonym for `#[macro_use]` #[macro_escape] fn f() { } //~^ WARN unused attribute diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr index 9ce90d89d22d2..6063aabd565bc 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr @@ -172,13 +172,13 @@ warning: unknown lint: `x5100` LL | #[deny(x5100)] impl S { } | ^^^^^ -warning: macro_escape is a deprecated synonym for macro_use +warning: `#[macro_escape]` is a deprecated synonym for `#[macro_use]` --> $DIR/issue-43106-gating-of-builtin-attrs.rs:466:1 | LL | #[macro_escape] | ^^^^^^^^^^^^^^^ -warning: macro_escape is a deprecated synonym for macro_use +warning: `#[macro_escape]` is a deprecated synonym for `#[macro_use]` --> $DIR/issue-43106-gating-of-builtin-attrs.rs:469:17 | LL | mod inner { #![macro_escape] } diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.rs b/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.rs index 75a3d9124ebae..de00bc4cbac07 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.rs +++ b/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.rs @@ -6,6 +6,6 @@ // check-pass #![macro_escape] -//~^ WARN macro_escape is a deprecated synonym for macro_use +//~^ WARN `#[macro_escape]` is a deprecated synonym for `#[macro_use]` fn main() {} diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.stderr index 8575c1660c5a1..f2cc2f74e53e4 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.stderr @@ -1,4 +1,4 @@ -warning: macro_escape is a deprecated synonym for macro_use +warning: `#[macro_escape]` is a deprecated synonym for `#[macro_use]` --> $DIR/issue-43106-gating-of-macro_escape.rs:8:1 | LL | #![macro_escape] diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-macro_use.rs b/src/test/ui/feature-gate/issue-43106-gating-of-macro_use.rs index 4ced941aad5d0..6a7ef793924a4 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-macro_use.rs +++ b/src/test/ui/feature-gate/issue-43106-gating-of-macro_use.rs @@ -4,13 +4,13 @@ // get that warning; see issue-43106-gating-of-builtin-attrs.rs #![macro_use(my_macro)] -//~^ ERROR arguments to macro_use are not allowed here +//~^ ERROR arguments to `macro_use` are not allowed here #[macro_use(my_macro)] -//~^ ERROR arguments to macro_use are not allowed here +//~^ ERROR arguments to `macro_use` are not allowed here mod macro_escape { mod inner { #![macro_use(my_macro)] } - //~^ ERROR arguments to macro_use are not allowed here + //~^ ERROR arguments to `macro_use` are not allowed here #[macro_use = "2700"] struct S; //~^ ERROR malformed `macro_use` attribute diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-macro_use.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-macro_use.stderr index 3181d62298cad..52a682e4bfa87 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-macro_use.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-macro_use.stderr @@ -1,16 +1,16 @@ -error: arguments to macro_use are not allowed here +error: arguments to `macro_use` are not allowed here --> $DIR/issue-43106-gating-of-macro_use.rs:6:1 | LL | #![macro_use(my_macro)] | ^^^^^^^^^^^^^^^^^^^^^^^ -error: arguments to macro_use are not allowed here +error: arguments to `macro_use` are not allowed here --> $DIR/issue-43106-gating-of-macro_use.rs:9:1 | LL | #[macro_use(my_macro)] | ^^^^^^^^^^^^^^^^^^^^^^ -error: arguments to macro_use are not allowed here +error: arguments to `macro_use` are not allowed here --> $DIR/issue-43106-gating-of-macro_use.rs:12:17 | LL | mod inner { #![macro_use(my_macro)] } diff --git a/src/test/ui/imports/extern-crate-self/extern-crate-self-fail.rs b/src/test/ui/imports/extern-crate-self/extern-crate-self-fail.rs index defa0e294bd74..1c0d3b4b964d6 100644 --- a/src/test/ui/imports/extern-crate-self/extern-crate-self-fail.rs +++ b/src/test/ui/imports/extern-crate-self/extern-crate-self-fail.rs @@ -1,6 +1,6 @@ extern crate self; //~ ERROR `extern crate self;` requires renaming -#[macro_use] //~ ERROR `macro_use` is not supported on `extern crate self` +#[macro_use] //~ ERROR `#[macro_use]` is not supported on `extern crate self` extern crate self as foo; fn main() {} diff --git a/src/test/ui/imports/extern-crate-self/extern-crate-self-fail.stderr b/src/test/ui/imports/extern-crate-self/extern-crate-self-fail.stderr index f26bb2f5a0ec4..8f369f1b03831 100644 --- a/src/test/ui/imports/extern-crate-self/extern-crate-self-fail.stderr +++ b/src/test/ui/imports/extern-crate-self/extern-crate-self-fail.stderr @@ -4,7 +4,7 @@ error: `extern crate self;` requires renaming LL | extern crate self; | ^^^^^^^^^^^^^^^^^^ help: try: `extern crate self as name;` -error: `macro_use` is not supported on `extern crate self` +error: `#[macro_use]` is not supported on `extern crate self` --> $DIR/extern-crate-self-fail.rs:3:1 | LL | #[macro_use] diff --git a/src/test/ui/issues/issue-29124.stderr b/src/test/ui/issues/issue-29124.stderr index fff20248b70d5..42d89cd01a48e 100644 --- a/src/test/ui/issues/issue-29124.stderr +++ b/src/test/ui/issues/issue-29124.stderr @@ -4,7 +4,7 @@ error[E0599]: no method named `x` found for fn item `fn() -> Ret {Obj::func}` in LL | Obj::func.x(); | ^ method not found in `fn() -> Ret {Obj::func}` | - = note: Obj::func is a function, perhaps you wish to call it + = note: `Obj::func` is a function, perhaps you wish to call it error[E0599]: no method named `x` found for fn item `fn() -> Ret {func}` in the current scope --> $DIR/issue-29124.rs:17:10 @@ -12,7 +12,7 @@ error[E0599]: no method named `x` found for fn item `fn() -> Ret {func}` in the LL | func.x(); | ^ method not found in `fn() -> Ret {func}` | - = note: func is a function, perhaps you wish to call it + = note: `func` is a function, perhaps you wish to call it error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-57362-1.stderr b/src/test/ui/issues/issue-57362-1.stderr index e762b7bc0c899..ad596db13ccfd 100644 --- a/src/test/ui/issues/issue-57362-1.stderr +++ b/src/test/ui/issues/issue-57362-1.stderr @@ -4,7 +4,7 @@ error[E0599]: no method named `f` found for fn pointer `fn(&u8)` in the current LL | a.f(); | ^ method not found in `fn(&u8)` | - = note: a is a function, perhaps you wish to call it + = note: `a` is a function, perhaps you wish to call it = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `f`, perhaps you need to implement it: candidate #1: `Trait` diff --git a/src/test/ui/lint/uninitialized-zeroed.stderr b/src/test/ui/lint/uninitialized-zeroed.stderr index d451b827598f4..169e77c8fa05d 100644 --- a/src/test/ui/lint/uninitialized-zeroed.stderr +++ b/src/test/ui/lint/uninitialized-zeroed.stderr @@ -108,7 +108,7 @@ LL | let _val: Void = mem::zeroed(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: 0-variant enums have no valid value + = note: enums with no variants have no valid value error: the type `Void` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:47:26 @@ -119,7 +119,7 @@ LL | let _val: Void = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: 0-variant enums have no valid value + = note: enums with no variants have no valid value error: the type `&'static i32` does not permit zero-initialization --> $DIR/uninitialized-zeroed.rs:49:34 @@ -294,7 +294,7 @@ LL | let _val: NonNull = mem::zeroed(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: std::ptr::NonNull must be non-null + = note: `std::ptr::NonNull` must be non-null error: the type `std::ptr::NonNull` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:68:34 @@ -305,7 +305,7 @@ LL | let _val: NonNull = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: std::ptr::NonNull must be non-null + = note: `std::ptr::NonNull` must be non-null error: the type `*const dyn std::marker::Send` does not permit zero-initialization --> $DIR/uninitialized-zeroed.rs:70:37 @@ -364,7 +364,7 @@ LL | let _val: NonBig = mem::uninitialized(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: NonBig must be initialized inside its custom valid range + = note: `NonBig` must be initialized inside its custom valid range error: the type `&'static i32` does not permit zero-initialization --> $DIR/uninitialized-zeroed.rs:84:34 @@ -397,7 +397,7 @@ LL | let _val: NonZeroU32 = mem::transmute(0); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: std::num::NonZeroU32 must be non-null + = note: `std::num::NonZeroU32` must be non-null error: the type `std::ptr::NonNull` does not permit zero-initialization --> $DIR/uninitialized-zeroed.rs:89:34 @@ -408,7 +408,7 @@ LL | let _val: NonNull = MaybeUninit::zeroed().assume_init(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: std::ptr::NonNull must be non-null + = note: `std::ptr::NonNull` must be non-null error: the type `std::ptr::NonNull` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:90:34 @@ -419,7 +419,7 @@ LL | let _val: NonNull = MaybeUninit::uninit().assume_init(); | this code causes undefined behavior when executed | help: use `MaybeUninit` instead, and only call `assume_init` after initialization is done | - = note: std::ptr::NonNull must be non-null + = note: `std::ptr::NonNull` must be non-null error: the type `bool` does not permit being left uninitialized --> $DIR/uninitialized-zeroed.rs:91:26 diff --git a/src/test/ui/malformed/malformed-interpolated.stderr b/src/test/ui/malformed/malformed-interpolated.stderr index bcd2ef545d815..6f6ad4508be01 100644 --- a/src/test/ui/malformed/malformed-interpolated.stderr +++ b/src/test/ui/malformed/malformed-interpolated.stderr @@ -4,7 +4,7 @@ error: suffixed literals are not allowed in attributes LL | check!(0u8); | ^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: unexpected token: `-0` --> $DIR/malformed-interpolated.rs:5:25 diff --git a/src/test/ui/module-macro_use-arguments.rs b/src/test/ui/module-macro_use-arguments.rs index 6627b48eb6a2c..121b492e25437 100644 --- a/src/test/ui/module-macro_use-arguments.rs +++ b/src/test/ui/module-macro_use-arguments.rs @@ -1,4 +1,4 @@ -#[macro_use(foo, bar)] //~ ERROR arguments to macro_use are not allowed here +#[macro_use(foo, bar)] //~ ERROR arguments to `macro_use` are not allowed here mod foo { } diff --git a/src/test/ui/module-macro_use-arguments.stderr b/src/test/ui/module-macro_use-arguments.stderr index 2a75736a2c69f..af799cb6ddf3e 100644 --- a/src/test/ui/module-macro_use-arguments.stderr +++ b/src/test/ui/module-macro_use-arguments.stderr @@ -1,4 +1,4 @@ -error: arguments to macro_use are not allowed here +error: arguments to `macro_use` are not allowed here --> $DIR/module-macro_use-arguments.rs:1:1 | LL | #[macro_use(foo, bar)] diff --git a/src/test/ui/suffixed-literal-meta.stderr b/src/test/ui/suffixed-literal-meta.stderr index ee35b53abe111..84fe91d662a8b 100644 --- a/src/test/ui/suffixed-literal-meta.stderr +++ b/src/test/ui/suffixed-literal-meta.stderr @@ -4,7 +4,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1usize] | ^^^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:5:17 @@ -12,7 +12,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1u8] | ^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:7:17 @@ -20,7 +20,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1u16] | ^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:9:17 @@ -28,7 +28,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1u32] | ^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:11:17 @@ -36,7 +36,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1u64] | ^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:13:17 @@ -44,7 +44,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1isize] | ^^^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:15:17 @@ -52,7 +52,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1i8] | ^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:17:17 @@ -60,7 +60,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1i16] | ^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:19:17 @@ -68,7 +68,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1i32] | ^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:21:17 @@ -76,7 +76,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1i64] | ^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:23:17 @@ -84,7 +84,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1.0f32] | ^^^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:25:17 @@ -92,7 +92,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1.0f64] | ^^^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:3:17 @@ -100,7 +100,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1usize] | ^^^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:5:17 @@ -108,7 +108,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1u8] | ^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:7:17 @@ -116,7 +116,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1u16] | ^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:9:17 @@ -124,7 +124,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1u32] | ^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:11:17 @@ -132,7 +132,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1u64] | ^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:13:17 @@ -140,7 +140,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1isize] | ^^^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:15:17 @@ -148,7 +148,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1i8] | ^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:17:17 @@ -156,7 +156,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1i16] | ^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:19:17 @@ -164,7 +164,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1i32] | ^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:21:17 @@ -172,7 +172,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1i64] | ^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:23:17 @@ -180,7 +180,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1.0f32] | ^^^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: suffixed literals are not allowed in attributes --> $DIR/suffixed-literal-meta.rs:25:17 @@ -188,7 +188,7 @@ error: suffixed literals are not allowed in attributes LL | #[rustc_dummy = 1.0f64] | ^^^^^^ | - = help: instead of using a suffixed literal (1u8, 1.0f32, etc.), use an unsuffixed version (1, 1.0, etc.). + = help: instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.) error: aborting due to 24 previous errors diff --git a/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.stderr b/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.stderr index 2d058521e4ef6..0b6d94e71f0c7 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.stderr @@ -4,7 +4,7 @@ error[E0599]: no method named `call` found for closure `[closure@$DIR/unboxed-cl LL | mut_.call((0, )); | ^^^^ method not found in `[closure@$DIR/unboxed-closures-static-call-wrong-trait.rs:6:26: 6:31]` | - = note: mut_ is a function, perhaps you wish to call it + = note: `mut_` is a function, perhaps you wish to call it error: aborting due to previous error From 3de9b8a3b7963b2eb03d570b54055b0a895662f1 Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 10 Jan 2020 15:13:56 +0000 Subject: [PATCH 023/169] Fix formatting ellipses at the end of some diagnostics --- src/librustc_parse/parser/pat.rs | 4 ++-- src/librustc_resolve/build_reduced_graph.rs | 2 +- .../deprecated-macro_escape-inner.stderr | 2 +- ...92-tuple-destructure-missing-parens.stderr | 24 +++++++++---------- ...issue-43106-gating-of-builtin-attrs.stderr | 2 +- .../issue-43106-gating-of-macro_escape.stderr | 2 +- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/librustc_parse/parser/pat.rs b/src/librustc_parse/parser/pat.rs index 0c2cfc20daf0f..549acf67d3824 100644 --- a/src/librustc_parse/parser/pat.rs +++ b/src/librustc_parse/parser/pat.rs @@ -209,13 +209,13 @@ impl<'a> Parser<'a> { if let Ok(seq_snippet) = self.span_to_snippet(seq_span) { err.span_suggestion( seq_span, - "try adding parentheses to match on a tuple..", + "try adding parentheses to match on a tuple...", format!("({})", seq_snippet), Applicability::MachineApplicable, ) .span_suggestion( seq_span, - "..or a vertical bar to match on multiple alternatives", + "...or a vertical bar to match on multiple alternatives", format!("{}", seq_snippet.replace(",", " |")), Applicability::MachineApplicable, ); diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 9c80df367c09c..e8ed64a18702d 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -1057,7 +1057,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { let msg = "`#[macro_escape]` is a deprecated synonym for `#[macro_use]`"; let mut err = self.r.session.struct_span_warn(attr.span, msg); if let ast::AttrStyle::Inner = attr.style { - err.help("consider an outer attribute, `#[macro_use]` mod ...").emit(); + err.help("try an outer attribute: `#[macro_use]`").emit(); } else { err.emit(); } diff --git a/src/test/ui/deprecation/deprecated-macro_escape-inner.stderr b/src/test/ui/deprecation/deprecated-macro_escape-inner.stderr index 65db62ce26355..4b0fc07463a99 100644 --- a/src/test/ui/deprecation/deprecated-macro_escape-inner.stderr +++ b/src/test/ui/deprecation/deprecated-macro_escape-inner.stderr @@ -4,5 +4,5 @@ warning: `#[macro_escape]` is a deprecated synonym for `#[macro_use]` LL | #![macro_escape] | ^^^^^^^^^^^^^^^^ | - = help: consider an outer attribute, `#[macro_use]` mod ... + = help: try an outer attribute: `#[macro_use]` diff --git a/src/test/ui/did_you_mean/issue-48492-tuple-destructure-missing-parens.stderr b/src/test/ui/did_you_mean/issue-48492-tuple-destructure-missing-parens.stderr index 705c90985d547..d05d6d120b084 100644 --- a/src/test/ui/did_you_mean/issue-48492-tuple-destructure-missing-parens.stderr +++ b/src/test/ui/did_you_mean/issue-48492-tuple-destructure-missing-parens.stderr @@ -4,11 +4,11 @@ error: unexpected `,` in pattern LL | while let b1, b2, b3 = reading_frame.next().expect("there should be a start codon") { | ^ | -help: try adding parentheses to match on a tuple.. +help: try adding parentheses to match on a tuple... | LL | while let (b1, b2, b3) = reading_frame.next().expect("there should be a start codon") { | ^^^^^^^^^^^^ -help: ..or a vertical bar to match on multiple alternatives +help: ...or a vertical bar to match on multiple alternatives | LL | while let b1 | b2 | b3 = reading_frame.next().expect("there should be a start codon") { | ^^^^^^^^^^^^ @@ -19,11 +19,11 @@ error: unexpected `,` in pattern LL | if let b1, b2, b3 = reading_frame.next().unwrap() { | ^ | -help: try adding parentheses to match on a tuple.. +help: try adding parentheses to match on a tuple... | LL | if let (b1, b2, b3) = reading_frame.next().unwrap() { | ^^^^^^^^^^^^ -help: ..or a vertical bar to match on multiple alternatives +help: ...or a vertical bar to match on multiple alternatives | LL | if let b1 | b2 | b3 = reading_frame.next().unwrap() { | ^^^^^^^^^^^^ @@ -34,11 +34,11 @@ error: unexpected `,` in pattern LL | Nucleotide::Adenine, Nucleotide::Cytosine, _ => true | ^ | -help: try adding parentheses to match on a tuple.. +help: try adding parentheses to match on a tuple... | LL | (Nucleotide::Adenine, Nucleotide::Cytosine, _) => true | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -help: ..or a vertical bar to match on multiple alternatives +help: ...or a vertical bar to match on multiple alternatives | LL | Nucleotide::Adenine | Nucleotide::Cytosine | _ => true | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -49,11 +49,11 @@ error: unexpected `,` in pattern LL | for x, _barr_body in women.iter().map(|woman| woman.allosomes.clone()) { | ^ | -help: try adding parentheses to match on a tuple.. +help: try adding parentheses to match on a tuple... | LL | for (x, _barr_body) in women.iter().map(|woman| woman.allosomes.clone()) { | ^^^^^^^^^^^^^^^ -help: ..or a vertical bar to match on multiple alternatives +help: ...or a vertical bar to match on multiple alternatives | LL | for x | _barr_body in women.iter().map(|woman| woman.allosomes.clone()) { | ^^^^^^^^^^^^^^ @@ -64,11 +64,11 @@ error: unexpected `,` in pattern LL | for x, y @ Allosome::Y(_) in men.iter().map(|man| man.allosomes.clone()) { | ^ | -help: try adding parentheses to match on a tuple.. +help: try adding parentheses to match on a tuple... | LL | for (x, y @ Allosome::Y(_)) in men.iter().map(|man| man.allosomes.clone()) { | ^^^^^^^^^^^^^^^^^^^^^^^ -help: ..or a vertical bar to match on multiple alternatives +help: ...or a vertical bar to match on multiple alternatives | LL | for x | y @ Allosome::Y(_) in men.iter().map(|man| man.allosomes.clone()) { | ^^^^^^^^^^^^^^^^^^^^^^ @@ -79,11 +79,11 @@ error: unexpected `,` in pattern LL | let women, men: (Vec, Vec) = genomes.iter().cloned() | ^ | -help: try adding parentheses to match on a tuple.. +help: try adding parentheses to match on a tuple... | LL | let (women, men): (Vec, Vec) = genomes.iter().cloned() | ^^^^^^^^^^^^ -help: ..or a vertical bar to match on multiple alternatives +help: ...or a vertical bar to match on multiple alternatives | LL | let women | men: (Vec, Vec) = genomes.iter().cloned() | ^^^^^^^^^^^ diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr index 6063aabd565bc..da7d8f9bee5c5 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-builtin-attrs.stderr @@ -184,7 +184,7 @@ warning: `#[macro_escape]` is a deprecated synonym for `#[macro_use]` LL | mod inner { #![macro_escape] } | ^^^^^^^^^^^^^^^^ | - = help: consider an outer attribute, `#[macro_use]` mod ... + = help: try an outer attribute: `#[macro_use]` warning: use of deprecated attribute `plugin_registrar`: compiler plugins are deprecated. See https://github.com/rust-lang/rust/pull/64675 --> $DIR/issue-43106-gating-of-builtin-attrs.rs:221:17 diff --git a/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.stderr b/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.stderr index f2cc2f74e53e4..402dc4e540925 100644 --- a/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.stderr +++ b/src/test/ui/feature-gate/issue-43106-gating-of-macro_escape.stderr @@ -4,5 +4,5 @@ warning: `#[macro_escape]` is a deprecated synonym for `#[macro_use]` LL | #![macro_escape] | ^^^^^^^^^^^^^^^^ | - = help: consider an outer attribute, `#[macro_use]` mod ... + = help: try an outer attribute: `#[macro_use]` From 117443ec0ad7aefabbc20c3f23f90e14b2b43c05 Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 10 Jan 2020 16:27:37 +0000 Subject: [PATCH 024/169] Appease tidy --- src/test/ui/resolve/impl-items-vis-unresolved.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/ui/resolve/impl-items-vis-unresolved.rs b/src/test/ui/resolve/impl-items-vis-unresolved.rs index a124b4eff8f69..1494c1cf96800 100644 --- a/src/test/ui/resolve/impl-items-vis-unresolved.rs +++ b/src/test/ui/resolve/impl-items-vis-unresolved.rs @@ -18,7 +18,8 @@ mod state { pub struct RawFloatState; impl RawFloatState { perftools_inline! { - pub(super) fn new() {} //~ ERROR failed to resolve: there are too many leading `super` keywords + pub(super) fn new() {} + //~^ ERROR failed to resolve: there are too many leading `super` keywords } } From 1faa05daac8069503a0ffbba735db3b259424296 Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 10 Jan 2020 18:24:34 +0000 Subject: [PATCH 025/169] Update `output-default.json` and rustdoc test --- src/test/run-make-fulldeps/libtest-json/output-default.json | 2 +- .../run-make-fulldeps/libtest-json/output-stdout-success.json | 2 +- src/test/rustdoc-ui/failed-doctest-output.stdout | 2 +- src/test/ui/resolve/impl-items-vis-unresolved.stderr | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/run-make-fulldeps/libtest-json/output-default.json b/src/test/run-make-fulldeps/libtest-json/output-default.json index 8046d72221703..0cd9ab79e32f3 100644 --- a/src/test/run-make-fulldeps/libtest-json/output-default.json +++ b/src/test/run-make-fulldeps/libtest-json/output-default.json @@ -2,7 +2,7 @@ { "type": "test", "event": "started", "name": "a" } { "type": "test", "name": "a", "event": "ok" } { "type": "test", "event": "started", "name": "b" } -{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:9:5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.\n" } +{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:9:5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\n" } { "type": "test", "event": "started", "name": "c" } { "type": "test", "name": "c", "event": "ok" } { "type": "test", "event": "started", "name": "d" } diff --git a/src/test/run-make-fulldeps/libtest-json/output-stdout-success.json b/src/test/run-make-fulldeps/libtest-json/output-stdout-success.json index 303316278d8ab..dfaf005052e55 100644 --- a/src/test/run-make-fulldeps/libtest-json/output-stdout-success.json +++ b/src/test/run-make-fulldeps/libtest-json/output-stdout-success.json @@ -2,7 +2,7 @@ { "type": "test", "event": "started", "name": "a" } { "type": "test", "name": "a", "event": "ok", "stdout": "print from successful test\n" } { "type": "test", "event": "started", "name": "b" } -{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:9:5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.\n" } +{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:9:5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace\n" } { "type": "test", "event": "started", "name": "c" } { "type": "test", "name": "c", "event": "ok", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:15:5\n" } { "type": "test", "event": "started", "name": "d" } diff --git a/src/test/rustdoc-ui/failed-doctest-output.stdout b/src/test/rustdoc-ui/failed-doctest-output.stdout index 9887d07a3eb6e..ee79ae1a690ec 100644 --- a/src/test/rustdoc-ui/failed-doctest-output.stdout +++ b/src/test/rustdoc-ui/failed-doctest-output.stdout @@ -27,7 +27,7 @@ stderr: stderr 1 stderr 2 thread 'main' panicked at 'oh no', $DIR/failed-doctest-output.rs:7:1 -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/src/test/ui/resolve/impl-items-vis-unresolved.stderr b/src/test/ui/resolve/impl-items-vis-unresolved.stderr index 62cffe55f9fb6..f2293d28ea151 100644 --- a/src/test/ui/resolve/impl-items-vis-unresolved.stderr +++ b/src/test/ui/resolve/impl-items-vis-unresolved.stderr @@ -2,7 +2,7 @@ error[E0433]: failed to resolve: there are too many leading `super` keywords --> $DIR/impl-items-vis-unresolved.rs:21:13 | LL | pub(super) fn new() {} - | ^^^^^ there are too many leading `super` keywords. + | ^^^^^ there are too many leading `super` keywords error: aborting due to previous error From 109c30f3d4783f569eb4d9350e6045a1e96af80d Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sat, 28 Dec 2019 19:09:42 -0600 Subject: [PATCH 026/169] More separation of error reporting from region inference --- .../borrow_check/diagnostics/region_errors.rs | 33 +++----- src/librustc_mir/borrow_check/mod.rs | 77 ++++++++++--------- .../borrow_check/region_infer/mod.rs | 64 ++++++--------- .../borrow_check/region_infer/values.rs | 2 +- 4 files changed, 77 insertions(+), 99 deletions(-) diff --git a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs index dc63fa80275e1..bf4a12b12a5c2 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs @@ -1,8 +1,7 @@ //! Error reporting machinery for lifetime errors. use rustc::infer::{ - error_reporting::nice_region_error::NiceRegionError, region_constraints::GenericKind, - InferCtxt, NLLRegionVariableOrigin, + error_reporting::nice_region_error::NiceRegionError, InferCtxt, NLLRegionVariableOrigin, }; use rustc::mir::{Body, ConstraintCategory, Location}; use rustc::ty::{self, RegionVid, Ty}; @@ -16,8 +15,11 @@ use std::collections::VecDeque; use crate::util::borrowck_errors; use crate::borrow_check::{ - constraints::OutlivesConstraint, nll::ConstraintDescription, - region_infer::RegionInferenceContext, type_check::Locations, universal_regions::DefiningTy, + constraints::OutlivesConstraint, + nll::ConstraintDescription, + region_infer::{values::RegionElement, RegionInferenceContext, TypeTest}, + type_check::Locations, + universal_regions::DefiningTy, MirBorrowckCtxt, }; @@ -62,23 +64,8 @@ crate type RegionErrors<'tcx> = Vec>; #[derive(Clone, Debug)] crate enum RegionErrorKind<'tcx> { - /// An error for a type test: `T: 'a` does not live long enough. - TypeTestDoesNotLiveLongEnough { - /// The span of the type test. - span: Span, - /// The generic type of the type test. - generic: GenericKind<'tcx>, - }, - - /// A generic bound failure for a type test. - TypeTestGenericBoundError { - /// The span of the type test. - span: Span, - /// The generic type of the type test. - generic: GenericKind<'tcx>, - /// The lower bound region. - lower_bound_region: ty::Region<'tcx>, - }, + /// A generic bound failure for a type test (`T: 'a`). + TypeTestError { type_test: TypeTest<'tcx> }, /// An unexpected hidden region for an opaque type. UnexpectedHiddenRegion { @@ -94,8 +81,8 @@ crate enum RegionErrorKind<'tcx> { BoundUniversalRegionError { /// The placeholder free region. longer_fr: RegionVid, - /// The region that erroneously must be outlived by `longer_fr`. - error_region: RegionVid, + /// The region element that erroneously must be outlived by `longer_fr`. + error_element: RegionElement, /// The origin of the placeholder region. fr_origin: NLLRegionVariableOrigin, }, diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 7b0a103fd0038..fc1b723c27120 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -631,7 +631,7 @@ impl<'cx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx, 'tcx debug!( "visit_terminator_drop \ - loc: {:?} term: {:?} drop_place: {:?} drop_place_ty: {:?} span: {:?}", + loc: {:?} term: {:?} drop_place: {:?} drop_place_ty: {:?} span: {:?}", loc, term, drop_place, drop_place_ty, span ); @@ -1477,38 +1477,42 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { for nll_error in nll_errors.into_iter() { match nll_error { - RegionErrorKind::TypeTestDoesNotLiveLongEnough { span, generic } => { - // FIXME. We should handle this case better. It - // indicates that we have e.g., some region variable - // whose value is like `'a+'b` where `'a` and `'b` are - // distinct unrelated univesal regions that are not - // known to outlive one another. It'd be nice to have - // some examples where this arises to decide how best - // to report it; we could probably handle it by - // iterating over the universal regions and reporting - // an error that multiple bounds are required. - self.infcx - .tcx - .sess - .struct_span_err(span, &format!("`{}` does not live long enough", generic)) - .buffer(&mut self.errors_buffer); - } - - RegionErrorKind::TypeTestGenericBoundError { - span, - generic, - lower_bound_region, - } => { - let region_scope_tree = &self.infcx.tcx.region_scope_tree(self.mir_def_id); - self.infcx - .construct_generic_bound_failure( - region_scope_tree, - span, - None, - generic, - lower_bound_region, - ) - .buffer(&mut self.errors_buffer); + RegionErrorKind::TypeTestError { type_test } => { + // Try to convert the lower-bound region into something named we can print for the user. + let lower_bound_region = + self.nonlexical_regioncx.to_error_region(type_test.lower_bound); + + // Skip duplicate-ish errors. + let type_test_span = type_test.locations.span(&self.body); + + if let Some(lower_bound_region) = lower_bound_region { + let region_scope_tree = &self.infcx.tcx.region_scope_tree(self.mir_def_id); + self.infcx + .construct_generic_bound_failure( + region_scope_tree, + type_test_span, + None, + type_test.generic_kind, + lower_bound_region, + ) + .buffer(&mut self.errors_buffer); + } else { + // FIXME. We should handle this case better. It indicates that we have + // e.g., some region variable whose value is like `'a+'b` where `'a` and + // `'b` are distinct unrelated univesal regions that are not known to + // outlive one another. It'd be nice to have some examples where this + // arises to decide how best to report it; we could probably handle it by + // iterating over the universal regions and reporting an error that + // multiple bounds are required. + self.infcx + .tcx + .sess + .struct_span_err( + type_test_span, + &format!("`{}` does not live long enough", type_test.generic_kind), + ) + .buffer(&mut self.errors_buffer); + } } RegionErrorKind::UnexpectedHiddenRegion { @@ -1530,8 +1534,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { RegionErrorKind::BoundUniversalRegionError { longer_fr, fr_origin, - error_region, + error_element, } => { + let error_region = + self.nonlexical_regioncx.region_from_element(longer_fr, error_element); + // Find the code to blame for the fact that `longer_fr` outlives `error_fr`. let (_, span) = self.nonlexical_regioncx.find_outlives_blame_span( &self.body, @@ -2225,7 +2232,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let upvar = &self.upvars[field.index()]; debug!( "upvar.mutability={:?} local_mutation_is_allowed={:?} \ - place={:?}", + place={:?}", upvar, is_local_mutation_allowed, place ); match (upvar.mutability, is_local_mutation_allowed) { diff --git a/src/librustc_mir/borrow_check/region_infer/mod.rs b/src/librustc_mir/borrow_check/region_infer/mod.rs index 7d2384f8a7de7..baa1c5b617dca 100644 --- a/src/librustc_mir/borrow_check/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/region_infer/mod.rs @@ -838,39 +838,20 @@ impl<'tcx> RegionInferenceContext<'tcx> { } // Type-test failed. Report the error. - - // Try to convert the lower-bound region into something named we can print for the user. - let lower_bound_region = self.to_error_region(type_test.lower_bound); - - // Skip duplicate-ish errors. - let type_test_span = type_test.locations.span(body); - let erased_generic_kind = tcx.erase_regions(&type_test.generic_kind); - if !deduplicate_errors.insert(( + let erased_generic_kind = infcx.tcx.erase_regions(&type_test.generic_kind); + if deduplicate_errors.insert(( erased_generic_kind, - lower_bound_region, + type_test.lower_bound, type_test.locations, )) { - continue; - } else { debug!( "check_type_test: reporting error for erased_generic_kind={:?}, \ lower_bound_region={:?}, \ type_test.locations={:?}", - erased_generic_kind, lower_bound_region, type_test.locations, + erased_generic_kind, type_test.lower_bound, type_test.locations, ); - } - if let Some(lower_bound_region) = lower_bound_region { - errors_buffer.push(RegionErrorKind::TypeTestGenericBoundError { - span: type_test_span, - generic: type_test.generic_kind, - lower_bound_region, - }); - } else { - errors_buffer.push(RegionErrorKind::TypeTestDoesNotLiveLongEnough { - span: type_test_span, - generic: type_test.generic_kind, - }); + errors_buffer.push(RegionErrorKind::TypeTestError { type_test: type_test.clone() }); } } } @@ -1355,7 +1336,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { for (longer_fr, shorter_fr) in subset_errors.into_iter() { debug!( "check_polonius_subset_errors: subset_error longer_fr={:?},\ - shorter_fr={:?}", + shorter_fr={:?}", longer_fr, shorter_fr ); @@ -1572,23 +1553,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { debug!("check_bound_universal_region: error_element = {:?}", error_element); // Find the region that introduced this `error_element`. - let error_region = match error_element { - RegionElement::Location(l) => self.find_sub_region_live_at(longer_fr, l), - RegionElement::RootUniversalRegion(r) => r, - RegionElement::PlaceholderRegion(error_placeholder) => self - .definitions - .iter_enumerated() - .filter_map(|(r, definition)| match definition.origin { - NLLRegionVariableOrigin::Placeholder(p) if p == error_placeholder => Some(r), - _ => None, - }) - .next() - .unwrap(), - }; - errors_buffer.push(RegionErrorKind::BoundUniversalRegionError { longer_fr, - error_region, + error_element, fr_origin: NLLRegionVariableOrigin::Placeholder(placeholder), }); } @@ -1628,6 +1595,23 @@ impl<'tcx> RegionInferenceContext<'tcx> { }); } } + + /// Get the region outlived by `longer_fr` and live at `element`. + crate fn region_from_element(&self, longer_fr: RegionVid, element: RegionElement) -> RegionVid { + match element { + RegionElement::Location(l) => self.find_sub_region_live_at(longer_fr, l), + RegionElement::RootUniversalRegion(r) => r, + RegionElement::PlaceholderRegion(error_placeholder) => self + .definitions + .iter_enumerated() + .filter_map(|(r, definition)| match definition.origin { + NLLRegionVariableOrigin::Placeholder(p) if p == error_placeholder => Some(r), + _ => None, + }) + .next() + .unwrap(), + } + } } impl<'tcx> RegionDefinition<'tcx> { diff --git a/src/librustc_mir/borrow_check/region_infer/values.rs b/src/librustc_mir/borrow_check/region_infer/values.rs index e17efebfef824..3126d44014b4e 100644 --- a/src/librustc_mir/borrow_check/region_infer/values.rs +++ b/src/librustc_mir/borrow_check/region_infer/values.rs @@ -114,7 +114,7 @@ rustc_index::newtype_index! { /// An individual element in a region value -- the value of a /// particular region variable consists of a set of these elements. -#[derive(Debug)] +#[derive(Debug, Clone)] crate enum RegionElement { /// A point in the control-flow graph. Location(Location), From c3e74f347e44e3a54f6ff094ef8b741589d69ab5 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sat, 28 Dec 2019 19:25:57 -0600 Subject: [PATCH 027/169] Move some methods to region_infer/mod.rs --- .../diagnostics/explain_borrow.rs | 45 +- .../borrow_check/diagnostics/region_errors.rs | 431 +----------------- .../borrow_check/region_infer/mod.rs | 395 ++++++++++++++++ 3 files changed, 440 insertions(+), 431 deletions(-) diff --git a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs b/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs index 9a0c99b07e6f1..afccf8a0922a7 100644 --- a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs +++ b/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs @@ -2,12 +2,13 @@ use std::collections::VecDeque; +use rustc::infer::NLLRegionVariableOrigin; use rustc::mir::{ Body, CastKind, ConstraintCategory, FakeReadCause, Local, Location, Operand, Place, Rvalue, Statement, StatementKind, TerminatorKind, }; use rustc::ty::adjustment::PointerCast; -use rustc::ty::{self, TyCtxt}; +use rustc::ty::{self, RegionVid, TyCtxt}; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_index::vec::IndexVec; @@ -15,8 +16,8 @@ use rustc_span::symbol::Symbol; use rustc_span::Span; use crate::borrow_check::{ - borrow_set::BorrowData, nll::ConstraintDescription, region_infer::Cause, MirBorrowckCtxt, - WriteKind, + borrow_set::BorrowData, diagnostics::RegionErrorNamingCtx, nll::ConstraintDescription, + region_infer::Cause, MirBorrowckCtxt, WriteKind, }; use super::{find_use, RegionName, UseSpans}; @@ -254,6 +255,32 @@ impl BorrowExplanation { } impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { + fn free_region_constraint_info( + &self, + borrow_region: RegionVid, + outlived_region: RegionVid, + ) -> (ConstraintCategory, bool, Span, Option) { + let (category, from_closure, span) = self.nonlexical_regioncx.best_blame_constraint( + &self.body, + borrow_region, + NLLRegionVariableOrigin::FreeRegion, + |r| { + self.nonlexical_regioncx.provides_universal_region( + r, + borrow_region, + outlived_region, + ) + }, + ); + + let mut renctx = RegionErrorNamingCtx::new(); + let outlived_fr_name = + self.nonlexical_regioncx.give_region_a_name(self, &mut renctx, outlived_region); + // TODO(mark-i-m): just return the region and let the caller name it + + (category, from_closure, span, outlived_fr_name) + } + /// Returns structured explanation for *why* the borrow contains the /// point from `location`. This is key for the "3-point errors" /// [described in the NLL RFC][d]. @@ -285,7 +312,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let borrow_region_vid = borrow.region; debug!("explain_why_borrow_contains_point: borrow_region_vid={:?}", borrow_region_vid); - let region_sub = regioncx.find_sub_region_live_at(borrow_region_vid, location); + let region_sub = + self.nonlexical_regioncx.find_sub_region_live_at(borrow_region_vid, location); debug!("explain_why_borrow_contains_point: region_sub={:?}", region_sub); match find_use::find(body, regioncx, tcx, region_sub, location) { @@ -330,9 +358,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { None => { if let Some(region) = regioncx.to_error_region_vid(borrow_region_vid) { - let (category, from_closure, span, region_name) = self - .nonlexical_regioncx - .free_region_constraint_info(self, borrow_region_vid, region); + let (category, from_closure, span, region_name) = + self.free_region_constraint_info(borrow_region_vid, region); if let Some(region_name) = region_name { let opt_place_desc = self.describe_place(borrow.borrowed_place.as_ref()); BorrowExplanation::MustBeValidFor { @@ -345,14 +372,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } else { debug!( "explain_why_borrow_contains_point: \ - Could not generate a region name" + Could not generate a region name" ); BorrowExplanation::Unexplained } } else { debug!( "explain_why_borrow_contains_point: \ - Could not generate an error region vid" + Could not generate an error region vid" ); BorrowExplanation::Unexplained } diff --git a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs index bf4a12b12a5c2..f9ec4ccb52a09 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs @@ -3,22 +3,18 @@ use rustc::infer::{ error_reporting::nice_region_error::NiceRegionError, InferCtxt, NLLRegionVariableOrigin, }; -use rustc::mir::{Body, ConstraintCategory, Location}; +use rustc::mir::ConstraintCategory; use rustc::ty::{self, RegionVid, Ty}; use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_hir::def_id::DefId; -use rustc_index::vec::IndexVec; use rustc_span::symbol::kw; use rustc_span::Span; -use std::collections::VecDeque; use crate::util::borrowck_errors; use crate::borrow_check::{ - constraints::OutlivesConstraint, nll::ConstraintDescription, region_infer::{values::RegionElement, RegionInferenceContext, TypeTest}, - type_check::Locations, universal_regions::DefiningTy, MirBorrowckCtxt, }; @@ -48,13 +44,6 @@ impl ConstraintDescription for ConstraintCategory { } } -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -enum Trace { - StartRegion, - FromOutlivesConstraint(OutlivesConstraint), - NotVisited, -} - /// A collection of errors encountered during region inference. This is needed to efficiently /// report errors after borrow checking. /// @@ -142,270 +131,18 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } - /// Tries to find the best constraint to blame for the fact that - /// `R: from_region`, where `R` is some region that meets - /// `target_test`. This works by following the constraint graph, - /// creating a constraint path that forces `R` to outlive - /// `from_region`, and then finding the best choices within that - /// path to blame. - fn best_blame_constraint( - &self, - body: &Body<'tcx>, - from_region: RegionVid, - from_region_origin: NLLRegionVariableOrigin, - target_test: impl Fn(RegionVid) -> bool, - ) -> (ConstraintCategory, bool, Span) { - debug!( - "best_blame_constraint(from_region={:?}, from_region_origin={:?})", - from_region, from_region_origin - ); - - // Find all paths - let (path, target_region) = - self.find_constraint_paths_between_regions(from_region, target_test).unwrap(); - debug!( - "best_blame_constraint: path={:#?}", - path.iter() - .map(|&c| format!( - "{:?} ({:?}: {:?})", - c, - self.constraint_sccs.scc(c.sup), - self.constraint_sccs.scc(c.sub), - )) - .collect::>() - ); - - // Classify each of the constraints along the path. - let mut categorized_path: Vec<(ConstraintCategory, bool, Span)> = path - .iter() - .map(|constraint| { - if constraint.category == ConstraintCategory::ClosureBounds { - self.retrieve_closure_constraint_info(body, &constraint) - } else { - (constraint.category, false, constraint.locations.span(body)) - } - }) - .collect(); - debug!("best_blame_constraint: categorized_path={:#?}", categorized_path); - - // To find the best span to cite, we first try to look for the - // final constraint that is interesting and where the `sup` is - // not unified with the ultimate target region. The reason - // for this is that we have a chain of constraints that lead - // from the source to the target region, something like: - // - // '0: '1 ('0 is the source) - // '1: '2 - // '2: '3 - // '3: '4 - // '4: '5 - // '5: '6 ('6 is the target) - // - // Some of those regions are unified with `'6` (in the same - // SCC). We want to screen those out. After that point, the - // "closest" constraint we have to the end is going to be the - // most likely to be the point where the value escapes -- but - // we still want to screen for an "interesting" point to - // highlight (e.g., a call site or something). - let target_scc = self.constraint_sccs.scc(target_region); - let mut range = 0..path.len(); - - // As noted above, when reporting an error, there is typically a chain of constraints - // leading from some "source" region which must outlive some "target" region. - // In most cases, we prefer to "blame" the constraints closer to the target -- - // but there is one exception. When constraints arise from higher-ranked subtyping, - // we generally prefer to blame the source value, - // as the "target" in this case tends to be some type annotation that the user gave. - // Therefore, if we find that the region origin is some instantiation - // of a higher-ranked region, we start our search from the "source" point - // rather than the "target", and we also tweak a few other things. - // - // An example might be this bit of Rust code: - // - // ```rust - // let x: fn(&'static ()) = |_| {}; - // let y: for<'a> fn(&'a ()) = x; - // ``` - // - // In MIR, this will be converted into a combination of assignments and type ascriptions. - // In particular, the 'static is imposed through a type ascription: - // - // ```rust - // x = ...; - // AscribeUserType(x, fn(&'static ()) - // y = x; - // ``` - // - // We wind up ultimately with constraints like - // - // ```rust - // !a: 'temp1 // from the `y = x` statement - // 'temp1: 'temp2 - // 'temp2: 'static // from the AscribeUserType - // ``` - // - // and here we prefer to blame the source (the y = x statement). - let blame_source = match from_region_origin { - NLLRegionVariableOrigin::FreeRegion - | NLLRegionVariableOrigin::Existential { from_forall: false } => true, - NLLRegionVariableOrigin::Placeholder(_) - | NLLRegionVariableOrigin::Existential { from_forall: true } => false, - }; - - let find_region = |i: &usize| { - let constraint = path[*i]; - - let constraint_sup_scc = self.constraint_sccs.scc(constraint.sup); - - if blame_source { - match categorized_path[*i].0 { - ConstraintCategory::OpaqueType - | ConstraintCategory::Boring - | ConstraintCategory::BoringNoLocation - | ConstraintCategory::Internal => false, - ConstraintCategory::TypeAnnotation - | ConstraintCategory::Return - | ConstraintCategory::Yield => true, - _ => constraint_sup_scc != target_scc, - } - } else { - match categorized_path[*i].0 { - ConstraintCategory::OpaqueType - | ConstraintCategory::Boring - | ConstraintCategory::BoringNoLocation - | ConstraintCategory::Internal => false, - _ => true, - } - } - }; - - let best_choice = - if blame_source { range.rev().find(find_region) } else { range.find(find_region) }; - - debug!( - "best_blame_constraint: best_choice={:?} blame_source={}", - best_choice, blame_source - ); - - if let Some(i) = best_choice { - if let Some(next) = categorized_path.get(i + 1) { - if categorized_path[i].0 == ConstraintCategory::Return - && next.0 == ConstraintCategory::OpaqueType - { - // The return expression is being influenced by the return type being - // impl Trait, point at the return type and not the return expr. - return *next; - } - } - return categorized_path[i]; - } - - // If that search fails, that is.. unusual. Maybe everything - // is in the same SCC or something. In that case, find what - // appears to be the most interesting point to report to the - // user via an even more ad-hoc guess. - categorized_path.sort_by(|p0, p1| p0.0.cmp(&p1.0)); - debug!("`: sorted_path={:#?}", categorized_path); - - *categorized_path.first().unwrap() - } - - /// Walks the graph of constraints (where `'a: 'b` is considered - /// an edge `'a -> 'b`) to find all paths from `from_region` to - /// `to_region`. The paths are accumulated into the vector - /// `results`. The paths are stored as a series of - /// `ConstraintIndex` values -- in other words, a list of *edges*. - /// - /// Returns: a series of constraints as well as the region `R` - /// that passed the target test. - fn find_constraint_paths_between_regions( - &self, - from_region: RegionVid, - target_test: impl Fn(RegionVid) -> bool, - ) -> Option<(Vec, RegionVid)> { - let mut context = IndexVec::from_elem(Trace::NotVisited, &self.definitions); - context[from_region] = Trace::StartRegion; - - // Use a deque so that we do a breadth-first search. We will - // stop at the first match, which ought to be the shortest - // path (fewest constraints). - let mut deque = VecDeque::new(); - deque.push_back(from_region); - - while let Some(r) = deque.pop_front() { - debug!( - "find_constraint_paths_between_regions: from_region={:?} r={:?} value={}", - from_region, - r, - self.region_value_str(r), - ); - - // Check if we reached the region we were looking for. If so, - // we can reconstruct the path that led to it and return it. - if target_test(r) { - let mut result = vec![]; - let mut p = r; - loop { - match context[p] { - Trace::NotVisited => { - bug!("found unvisited region {:?} on path to {:?}", p, r) - } - - Trace::FromOutlivesConstraint(c) => { - result.push(c); - p = c.sup; - } - - Trace::StartRegion => { - result.reverse(); - return Some((result, r)); - } - } - } - } - - // Otherwise, walk over the outgoing constraints and - // enqueue any regions we find, keeping track of how we - // reached them. - - // A constraint like `'r: 'x` can come from our constraint - // graph. - let fr_static = self.universal_regions.fr_static; - let outgoing_edges_from_graph = - self.constraint_graph.outgoing_edges(r, &self.constraints, fr_static); - - // Always inline this closure because it can be hot. - let mut handle_constraint = #[inline(always)] - |constraint: OutlivesConstraint| { - debug_assert_eq!(constraint.sup, r); - let sub_region = constraint.sub; - if let Trace::NotVisited = context[sub_region] { - context[sub_region] = Trace::FromOutlivesConstraint(constraint); - deque.push_back(sub_region); + /// Returns `true` if a closure is inferred to be an `FnMut` closure. + crate fn is_closure_fn_mut(&self, infcx: &InferCtxt<'_, 'tcx>, fr: RegionVid) -> bool { + if let Some(ty::ReFree(free_region)) = self.to_error_region(fr) { + if let ty::BoundRegion::BrEnv = free_region.bound_region { + if let DefiningTy::Closure(def_id, substs) = self.universal_regions.defining_ty { + let closure_kind_ty = substs.as_closure().kind_ty(def_id, infcx.tcx); + return Some(ty::ClosureKind::FnMut) == closure_kind_ty.to_opt_closure_kind(); } - }; - - // This loop can be hot. - for constraint in outgoing_edges_from_graph { - handle_constraint(constraint); - } - - // Member constraints can also give rise to `'r: 'x` edges that - // were not part of the graph initially, so watch out for those. - // (But they are extremely rare; this loop is very cold.) - for constraint in self.applied_member_constraints(r) { - let p_c = &self.member_constraints[constraint.member_constraint_index]; - let constraint = OutlivesConstraint { - sup: r, - sub: constraint.min_choice, - locations: Locations::All(p_c.definition_span), - category: ConstraintCategory::OpaqueType, - }; - handle_constraint(constraint); } } - None + false } /// Report an error because the universal region `fr` was required to outlive @@ -484,30 +221,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } - /// We have a constraint `fr1: fr2` that is not satisfied, where - /// `fr2` represents some universal region. Here, `r` is some - /// region where we know that `fr1: r` and this function has the - /// job of determining whether `r` is "to blame" for the fact that - /// `fr1: fr2` is required. - /// - /// This is true under two conditions: - /// - /// - `r == fr2` - /// - `fr2` is `'static` and `r` is some placeholder in a universe - /// that cannot be named by `fr1`; in that case, we will require - /// that `fr1: 'static` because it is the only way to `fr1: r` to - /// be satisfied. (See `add_incompatible_universe`.) - fn provides_universal_region(&self, r: RegionVid, fr1: RegionVid, fr2: RegionVid) -> bool { - debug!("provides_universal_region(r={:?}, fr1={:?}, fr2={:?})", r, fr1, fr2); - let result = { - r == fr2 || { - fr2 == self.universal_regions.fr_static && self.cannot_name_placeholder(fr1, r) - } - }; - debug!("provides_universal_region: result = {:?}", result); - result - } - /// Report a specialized error when `FnMut` closures return a reference to a captured variable. /// This function expects `fr` to be local and `outlived_fr` to not be local. /// @@ -817,130 +530,4 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } } - - crate fn free_region_constraint_info( - &self, - mbcx: &MirBorrowckCtxt<'_, 'tcx>, - borrow_region: RegionVid, - outlived_region: RegionVid, - ) -> (ConstraintCategory, bool, Span, Option) { - let (category, from_closure, span) = self.best_blame_constraint( - &mbcx.body, - borrow_region, - NLLRegionVariableOrigin::FreeRegion, - |r| self.provides_universal_region(r, borrow_region, outlived_region), - ); - - let mut renctx = RegionErrorNamingCtx::new(); - let outlived_fr_name = self.give_region_a_name(mbcx, &mut renctx, outlived_region); - - (category, from_closure, span, outlived_fr_name) - } - - // Finds some region R such that `fr1: R` and `R` is live at - // `elem`. - crate fn find_sub_region_live_at(&self, fr1: RegionVid, elem: Location) -> RegionVid { - debug!("find_sub_region_live_at(fr1={:?}, elem={:?})", fr1, elem); - self.find_constraint_paths_between_regions(fr1, |r| { - // First look for some `r` such that `fr1: r` and `r` is live at `elem` - debug!( - "find_sub_region_live_at: liveness_constraints for {:?} are {:?}", - r, - self.liveness_constraints.region_value_str(r), - ); - self.liveness_constraints.contains(r, elem) - }) - .or_else(|| { - // If we fail to find that, we may find some `r` such that - // `fr1: r` and `r` is a placeholder from some universe - // `fr1` cannot name. This would force `fr1` to be - // `'static`. - self.find_constraint_paths_between_regions(fr1, |r| { - self.cannot_name_placeholder(fr1, r) - }) - }) - .or_else(|| { - // If we fail to find THAT, it may be that `fr1` is a - // placeholder that cannot "fit" into its SCC. In that - // case, there should be some `r` where `fr1: r`, both - // `fr1` and `r` are in the same SCC, and `fr1` is a - // placeholder that `r` cannot name. We can blame that - // edge. - self.find_constraint_paths_between_regions(fr1, |r| { - self.constraint_sccs.scc(fr1) == self.constraint_sccs.scc(r) - && self.cannot_name_placeholder(r, fr1) - }) - }) - .map(|(_path, r)| r) - .unwrap() - } - - // Finds a good span to blame for the fact that `fr1` outlives `fr2`. - crate fn find_outlives_blame_span( - &self, - body: &Body<'tcx>, - fr1: RegionVid, - fr1_origin: NLLRegionVariableOrigin, - fr2: RegionVid, - ) -> (ConstraintCategory, Span) { - let (category, _, span) = self.best_blame_constraint(body, fr1, fr1_origin, |r| { - self.provides_universal_region(r, fr1, fr2) - }); - (category, span) - } - - fn retrieve_closure_constraint_info( - &self, - body: &Body<'tcx>, - constraint: &OutlivesConstraint, - ) -> (ConstraintCategory, bool, Span) { - let loc = match constraint.locations { - Locations::All(span) => return (constraint.category, false, span), - Locations::Single(loc) => loc, - }; - - let opt_span_category = - self.closure_bounds_mapping[&loc].get(&(constraint.sup, constraint.sub)); - opt_span_category.map(|&(category, span)| (category, true, span)).unwrap_or(( - constraint.category, - false, - body.source_info(loc).span, - )) - } - - /// Returns `true` if a closure is inferred to be an `FnMut` closure. - crate fn is_closure_fn_mut(&self, infcx: &InferCtxt<'_, 'tcx>, fr: RegionVid) -> bool { - if let Some(ty::ReFree(free_region)) = self.to_error_region(fr) { - if let ty::BoundRegion::BrEnv = free_region.bound_region { - if let DefiningTy::Closure(def_id, substs) = self.universal_regions.defining_ty { - let closure_kind_ty = substs.as_closure().kind_ty(def_id, infcx.tcx); - return Some(ty::ClosureKind::FnMut) == closure_kind_ty.to_opt_closure_kind(); - } - } - } - - false - } - - /// If `r2` represents a placeholder region, then this returns - /// `true` if `r1` cannot name that placeholder in its - /// value; otherwise, returns `false`. - fn cannot_name_placeholder(&self, r1: RegionVid, r2: RegionVid) -> bool { - debug!("cannot_name_value_of(r1={:?}, r2={:?})", r1, r2); - - match self.definitions[r2].origin { - NLLRegionVariableOrigin::Placeholder(placeholder) => { - let universe1 = self.definitions[r1].universe; - debug!( - "cannot_name_value_of: universe1={:?} placeholder={:?}", - universe1, placeholder - ); - universe1.cannot_name(placeholder.universe) - } - - NLLRegionVariableOrigin::FreeRegion | NLLRegionVariableOrigin::Existential { .. } => { - false - } - } - } } diff --git a/src/librustc_mir/borrow_check/region_infer/mod.rs b/src/librustc_mir/borrow_check/region_infer/mod.rs index baa1c5b617dca..406b28e1e3256 100644 --- a/src/librustc_mir/borrow_check/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/region_infer/mod.rs @@ -1,3 +1,4 @@ +use std::collections::VecDeque; use std::rc::Rc; use rustc::infer::canonical::QueryOutlivesConstraint; @@ -225,6 +226,13 @@ enum RegionRelationCheckResult { Error, } +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +enum Trace { + StartRegion, + FromOutlivesConstraint(OutlivesConstraint), + NotVisited, +} + impl<'tcx> RegionInferenceContext<'tcx> { /// Creates a new region inference context with a total of /// `num_region_variables` valid inference variables; the first N @@ -1612,6 +1620,393 @@ impl<'tcx> RegionInferenceContext<'tcx> { .unwrap(), } } + + /// We have a constraint `fr1: fr2` that is not satisfied, where + /// `fr2` represents some universal region. Here, `r` is some + /// region where we know that `fr1: r` and this function has the + /// job of determining whether `r` is "to blame" for the fact that + /// `fr1: fr2` is required. + /// + /// This is true under two conditions: + /// + /// - `r == fr2` + /// - `fr2` is `'static` and `r` is some placeholder in a universe + /// that cannot be named by `fr1`; in that case, we will require + /// that `fr1: 'static` because it is the only way to `fr1: r` to + /// be satisfied. (See `add_incompatible_universe`.) + crate fn provides_universal_region( + &self, + r: RegionVid, + fr1: RegionVid, + fr2: RegionVid, + ) -> bool { + debug!("provides_universal_region(r={:?}, fr1={:?}, fr2={:?})", r, fr1, fr2); + let result = { + r == fr2 || { + fr2 == self.universal_regions.fr_static && self.cannot_name_placeholder(fr1, r) + } + }; + debug!("provides_universal_region: result = {:?}", result); + result + } + + /// If `r2` represents a placeholder region, then this returns + /// `true` if `r1` cannot name that placeholder in its + /// value; otherwise, returns `false`. + crate fn cannot_name_placeholder(&self, r1: RegionVid, r2: RegionVid) -> bool { + debug!("cannot_name_value_of(r1={:?}, r2={:?})", r1, r2); + + match self.definitions[r2].origin { + NLLRegionVariableOrigin::Placeholder(placeholder) => { + let universe1 = self.definitions[r1].universe; + debug!( + "cannot_name_value_of: universe1={:?} placeholder={:?}", + universe1, placeholder + ); + universe1.cannot_name(placeholder.universe) + } + + NLLRegionVariableOrigin::FreeRegion | NLLRegionVariableOrigin::Existential { .. } => { + false + } + } + } + + crate fn retrieve_closure_constraint_info( + &self, + body: &Body<'tcx>, + constraint: &OutlivesConstraint, + ) -> (ConstraintCategory, bool, Span) { + let loc = match constraint.locations { + Locations::All(span) => return (constraint.category, false, span), + Locations::Single(loc) => loc, + }; + + let opt_span_category = + self.closure_bounds_mapping[&loc].get(&(constraint.sup, constraint.sub)); + opt_span_category.map(|&(category, span)| (category, true, span)).unwrap_or(( + constraint.category, + false, + body.source_info(loc).span, + )) + } + + /// Finds a good span to blame for the fact that `fr1` outlives `fr2`. + crate fn find_outlives_blame_span( + &self, + body: &Body<'tcx>, + fr1: RegionVid, + fr1_origin: NLLRegionVariableOrigin, + fr2: RegionVid, + ) -> (ConstraintCategory, Span) { + let (category, _, span) = self.best_blame_constraint(body, fr1, fr1_origin, |r| { + self.provides_universal_region(r, fr1, fr2) + }); + (category, span) + } + + /// Walks the graph of constraints (where `'a: 'b` is considered + /// an edge `'a -> 'b`) to find all paths from `from_region` to + /// `to_region`. The paths are accumulated into the vector + /// `results`. The paths are stored as a series of + /// `ConstraintIndex` values -- in other words, a list of *edges*. + /// + /// Returns: a series of constraints as well as the region `R` + /// that passed the target test. + crate fn find_constraint_paths_between_regions( + &self, + from_region: RegionVid, + target_test: impl Fn(RegionVid) -> bool, + ) -> Option<(Vec, RegionVid)> { + let mut context = IndexVec::from_elem(Trace::NotVisited, &self.definitions); + context[from_region] = Trace::StartRegion; + + // Use a deque so that we do a breadth-first search. We will + // stop at the first match, which ought to be the shortest + // path (fewest constraints). + let mut deque = VecDeque::new(); + deque.push_back(from_region); + + while let Some(r) = deque.pop_front() { + debug!( + "find_constraint_paths_between_regions: from_region={:?} r={:?} value={}", + from_region, + r, + self.region_value_str(r), + ); + + // Check if we reached the region we were looking for. If so, + // we can reconstruct the path that led to it and return it. + if target_test(r) { + let mut result = vec![]; + let mut p = r; + loop { + match context[p] { + Trace::NotVisited => { + bug!("found unvisited region {:?} on path to {:?}", p, r) + } + + Trace::FromOutlivesConstraint(c) => { + result.push(c); + p = c.sup; + } + + Trace::StartRegion => { + result.reverse(); + return Some((result, r)); + } + } + } + } + + // Otherwise, walk over the outgoing constraints and + // enqueue any regions we find, keeping track of how we + // reached them. + + // A constraint like `'r: 'x` can come from our constraint + // graph. + let fr_static = self.universal_regions.fr_static; + let outgoing_edges_from_graph = + self.constraint_graph.outgoing_edges(r, &self.constraints, fr_static); + + // Always inline this closure because it can be hot. + let mut handle_constraint = #[inline(always)] + |constraint: OutlivesConstraint| { + debug_assert_eq!(constraint.sup, r); + let sub_region = constraint.sub; + if let Trace::NotVisited = context[sub_region] { + context[sub_region] = Trace::FromOutlivesConstraint(constraint); + deque.push_back(sub_region); + } + }; + + // This loop can be hot. + for constraint in outgoing_edges_from_graph { + handle_constraint(constraint); + } + + // Member constraints can also give rise to `'r: 'x` edges that + // were not part of the graph initially, so watch out for those. + // (But they are extremely rare; this loop is very cold.) + for constraint in self.applied_member_constraints(r) { + let p_c = &self.member_constraints[constraint.member_constraint_index]; + let constraint = OutlivesConstraint { + sup: r, + sub: constraint.min_choice, + locations: Locations::All(p_c.definition_span), + category: ConstraintCategory::OpaqueType, + }; + handle_constraint(constraint); + } + } + + None + } + + /// Finds some region R such that `fr1: R` and `R` is live at `elem`. + crate fn find_sub_region_live_at(&self, fr1: RegionVid, elem: Location) -> RegionVid { + debug!("find_sub_region_live_at(fr1={:?}, elem={:?})", fr1, elem); + self.find_constraint_paths_between_regions(fr1, |r| { + // First look for some `r` such that `fr1: r` and `r` is live at `elem` + debug!( + "find_sub_region_live_at: liveness_constraints for {:?} are {:?}", + r, + self.liveness_constraints.region_value_str(r), + ); + self.liveness_constraints.contains(r, elem) + }) + .or_else(|| { + // If we fail to find that, we may find some `r` such that + // `fr1: r` and `r` is a placeholder from some universe + // `fr1` cannot name. This would force `fr1` to be + // `'static`. + self.find_constraint_paths_between_regions(fr1, |r| { + self.cannot_name_placeholder(fr1, r) + }) + }) + .or_else(|| { + // If we fail to find THAT, it may be that `fr1` is a + // placeholder that cannot "fit" into its SCC. In that + // case, there should be some `r` where `fr1: r`, both + // `fr1` and `r` are in the same SCC, and `fr1` is a + // placeholder that `r` cannot name. We can blame that + // edge. + self.find_constraint_paths_between_regions(fr1, |r| { + self.constraint_sccs.scc(fr1) == self.constraint_sccs.scc(r) + && self.cannot_name_placeholder(r, fr1) + }) + }) + .map(|(_path, r)| r) + .unwrap() + } + + /// Tries to find the best constraint to blame for the fact that + /// `R: from_region`, where `R` is some region that meets + /// `target_test`. This works by following the constraint graph, + /// creating a constraint path that forces `R` to outlive + /// `from_region`, and then finding the best choices within that + /// path to blame. + crate fn best_blame_constraint( + &self, + body: &Body<'tcx>, + from_region: RegionVid, + from_region_origin: NLLRegionVariableOrigin, + target_test: impl Fn(RegionVid) -> bool, + ) -> (ConstraintCategory, bool, Span) { + debug!( + "best_blame_constraint(from_region={:?}, from_region_origin={:?})", + from_region, from_region_origin + ); + + // Find all paths + let (path, target_region) = + self.find_constraint_paths_between_regions(from_region, target_test).unwrap(); + debug!( + "best_blame_constraint: path={:#?}", + path.iter() + .map(|&c| format!( + "{:?} ({:?}: {:?})", + c, + self.constraint_sccs.scc(c.sup), + self.constraint_sccs.scc(c.sub), + )) + .collect::>() + ); + + // Classify each of the constraints along the path. + let mut categorized_path: Vec<(ConstraintCategory, bool, Span)> = path + .iter() + .map(|constraint| { + if constraint.category == ConstraintCategory::ClosureBounds { + self.retrieve_closure_constraint_info(body, &constraint) + } else { + (constraint.category, false, constraint.locations.span(body)) + } + }) + .collect(); + debug!("best_blame_constraint: categorized_path={:#?}", categorized_path); + + // To find the best span to cite, we first try to look for the + // final constraint that is interesting and where the `sup` is + // not unified with the ultimate target region. The reason + // for this is that we have a chain of constraints that lead + // from the source to the target region, something like: + // + // '0: '1 ('0 is the source) + // '1: '2 + // '2: '3 + // '3: '4 + // '4: '5 + // '5: '6 ('6 is the target) + // + // Some of those regions are unified with `'6` (in the same + // SCC). We want to screen those out. After that point, the + // "closest" constraint we have to the end is going to be the + // most likely to be the point where the value escapes -- but + // we still want to screen for an "interesting" point to + // highlight (e.g., a call site or something). + let target_scc = self.constraint_sccs.scc(target_region); + let mut range = 0..path.len(); + + // As noted above, when reporting an error, there is typically a chain of constraints + // leading from some "source" region which must outlive some "target" region. + // In most cases, we prefer to "blame" the constraints closer to the target -- + // but there is one exception. When constraints arise from higher-ranked subtyping, + // we generally prefer to blame the source value, + // as the "target" in this case tends to be some type annotation that the user gave. + // Therefore, if we find that the region origin is some instantiation + // of a higher-ranked region, we start our search from the "source" point + // rather than the "target", and we also tweak a few other things. + // + // An example might be this bit of Rust code: + // + // ```rust + // let x: fn(&'static ()) = |_| {}; + // let y: for<'a> fn(&'a ()) = x; + // ``` + // + // In MIR, this will be converted into a combination of assignments and type ascriptions. + // In particular, the 'static is imposed through a type ascription: + // + // ```rust + // x = ...; + // AscribeUserType(x, fn(&'static ()) + // y = x; + // ``` + // + // We wind up ultimately with constraints like + // + // ```rust + // !a: 'temp1 // from the `y = x` statement + // 'temp1: 'temp2 + // 'temp2: 'static // from the AscribeUserType + // ``` + // + // and here we prefer to blame the source (the y = x statement). + let blame_source = match from_region_origin { + NLLRegionVariableOrigin::FreeRegion + | NLLRegionVariableOrigin::Existential { from_forall: false } => true, + NLLRegionVariableOrigin::Placeholder(_) + | NLLRegionVariableOrigin::Existential { from_forall: true } => false, + }; + + let find_region = |i: &usize| { + let constraint = path[*i]; + + let constraint_sup_scc = self.constraint_sccs.scc(constraint.sup); + + if blame_source { + match categorized_path[*i].0 { + ConstraintCategory::OpaqueType + | ConstraintCategory::Boring + | ConstraintCategory::BoringNoLocation + | ConstraintCategory::Internal => false, + ConstraintCategory::TypeAnnotation + | ConstraintCategory::Return + | ConstraintCategory::Yield => true, + _ => constraint_sup_scc != target_scc, + } + } else { + match categorized_path[*i].0 { + ConstraintCategory::OpaqueType + | ConstraintCategory::Boring + | ConstraintCategory::BoringNoLocation + | ConstraintCategory::Internal => false, + _ => true, + } + } + }; + + let best_choice = + if blame_source { range.rev().find(find_region) } else { range.find(find_region) }; + + debug!( + "best_blame_constraint: best_choice={:?} blame_source={}", + best_choice, blame_source + ); + + if let Some(i) = best_choice { + if let Some(next) = categorized_path.get(i + 1) { + if categorized_path[i].0 == ConstraintCategory::Return + && next.0 == ConstraintCategory::OpaqueType + { + // The return expression is being influenced by the return type being + // impl Trait, point at the return type and not the return expr. + return *next; + } + } + return categorized_path[i]; + } + + // If that search fails, that is.. unusual. Maybe everything + // is in the same SCC or something. In that case, find what + // appears to be the most interesting point to report to the + // user via an even more ad-hoc guess. + categorized_path.sort_by(|p0, p1| p0.0.cmp(&p1.0)); + debug!("`: sorted_path={:#?}", categorized_path); + + *categorized_path.first().unwrap() + } } impl<'tcx> RegionDefinition<'tcx> { From 736348ac41b00657bd8d5d6b8acae1eeef9985c7 Mon Sep 17 00:00:00 2001 From: mark Date: Fri, 20 Dec 2019 23:59:31 -0600 Subject: [PATCH 028/169] Move a bunch of methods to inherent impl MirBorrowckCtxt --- .../diagnostics/explain_borrow.rs | 6 +- .../diagnostics/outlives_suggestion.rs | 4 +- .../borrow_check/diagnostics/region_errors.rs | 144 +++++++++--------- .../borrow_check/diagnostics/region_name.rs | 111 +++++++------- src/librustc_mir/borrow_check/mod.rs | 10 +- 5 files changed, 130 insertions(+), 145 deletions(-) diff --git a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs b/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs index afccf8a0922a7..45c6c845cd156 100644 --- a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs +++ b/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs @@ -274,9 +274,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { ); let mut renctx = RegionErrorNamingCtx::new(); - let outlived_fr_name = - self.nonlexical_regioncx.give_region_a_name(self, &mut renctx, outlived_region); - // TODO(mark-i-m): just return the region and let the caller name it + let outlived_fr_name = self.give_region_a_name(&mut renctx, outlived_region); (category, from_closure, span, outlived_fr_name) } @@ -357,7 +355,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } None => { - if let Some(region) = regioncx.to_error_region_vid(borrow_region_vid) { + if let Some(region) = self.to_error_region_vid(borrow_region_vid) { let (category, from_closure, span, region_name) = self.free_region_constraint_info(borrow_region_vid, region); if let Some(region_name) = region_name { diff --git a/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs b/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs index 1425c22e461cf..be067fcf4f261 100644 --- a/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs +++ b/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs @@ -80,9 +80,7 @@ impl OutlivesSuggestionBuilder { renctx: &mut RegionErrorNamingCtx, region: RegionVid, ) -> Option { - mbcx.nonlexical_regioncx - .give_region_a_name(mbcx, renctx, region) - .filter(Self::region_name_is_suggestable) + mbcx.give_region_a_name(renctx, region).filter(Self::region_name_is_suggestable) } /// Compiles a list of all suggestions to be printed in the final big suggestion. diff --git a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs index f9ec4ccb52a09..b0be82164d876 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs @@ -1,8 +1,6 @@ //! Error reporting machinery for lifetime errors. -use rustc::infer::{ - error_reporting::nice_region_error::NiceRegionError, InferCtxt, NLLRegionVariableOrigin, -}; +use rustc::infer::{error_reporting::nice_region_error::NiceRegionError, NLLRegionVariableOrigin}; use rustc::mir::ConstraintCategory; use rustc::ty::{self, RegionVid, Ty}; use rustc_errors::{Applicability, DiagnosticBuilder}; @@ -14,7 +12,7 @@ use crate::util::borrowck_errors; use crate::borrow_check::{ nll::ConstraintDescription, - region_infer::{values::RegionElement, RegionInferenceContext, TypeTest}, + region_infer::{values::RegionElement, TypeTest}, universal_regions::DefiningTy, MirBorrowckCtxt, }; @@ -104,26 +102,28 @@ pub struct ErrorConstraintInfo { pub(super) span: Span, } -impl<'tcx> RegionInferenceContext<'tcx> { +impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { /// Converts a region inference variable into a `ty::Region` that /// we can use for error reporting. If `r` is universally bound, /// then we use the name that we have on record for it. If `r` is /// existentially bound, then we check its inferred value and try /// to find a good name from that. Returns `None` if we can't find /// one (e.g., this is just some random part of the CFG). - pub fn to_error_region(&self, r: RegionVid) -> Option> { - self.to_error_region_vid(r).and_then(|r| self.definitions[r].external_name) + // TODO(mark-i-m): make this private when we move report_region_errors here... + crate fn to_error_region(&self, r: RegionVid) -> Option> { + self.to_error_region_vid(r) + .and_then(|r| self.nonlexical_regioncx.definitions[r].external_name) } - /// Returns the [RegionVid] corresponding to the region returned by + /// Returns the `RegionVid` corresponding to the region returned by /// `to_error_region`. - pub fn to_error_region_vid(&self, r: RegionVid) -> Option { - if self.universal_regions.is_universal_region(r) { + pub(super) fn to_error_region_vid(&self, r: RegionVid) -> Option { + if self.nonlexical_regioncx.universal_regions.is_universal_region(r) { Some(r) } else { - let r_scc = self.constraint_sccs.scc(r); - let upper_bound = self.universal_upper_bound(r); - if self.scc_values.contains(r_scc, upper_bound) { + let r_scc = self.nonlexical_regioncx.constraint_sccs.scc(r); + let upper_bound = self.nonlexical_regioncx.universal_upper_bound(r); + if self.nonlexical_regioncx.scc_values.contains(r_scc, upper_bound) { self.to_error_region_vid(upper_bound) } else { None @@ -132,11 +132,13 @@ impl<'tcx> RegionInferenceContext<'tcx> { } /// Returns `true` if a closure is inferred to be an `FnMut` closure. - crate fn is_closure_fn_mut(&self, infcx: &InferCtxt<'_, 'tcx>, fr: RegionVid) -> bool { + fn is_closure_fn_mut(&self, fr: RegionVid) -> bool { if let Some(ty::ReFree(free_region)) = self.to_error_region(fr) { if let ty::BoundRegion::BrEnv = free_region.bound_region { - if let DefiningTy::Closure(def_id, substs) = self.universal_regions.defining_ty { - let closure_kind_ty = substs.as_closure().kind_ty(def_id, infcx.tcx); + if let DefiningTy::Closure(def_id, substs) = + self.nonlexical_regioncx.universal_regions.defining_ty + { + let closure_kind_ty = substs.as_closure().kind_ty(def_id, self.infcx.tcx); return Some(ty::ClosureKind::FnMut) == closure_kind_ty.to_opt_closure_kind(); } } @@ -153,34 +155,35 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// ``` /// /// Here we would be invoked with `fr = 'a` and `outlived_fr = `'b`. - pub(in crate::borrow_check) fn report_error<'a>( - &'a self, - mbcx: &MirBorrowckCtxt<'a, 'tcx>, + pub(in crate::borrow_check) fn report_error( + &mut self, fr: RegionVid, fr_origin: NLLRegionVariableOrigin, outlived_fr: RegionVid, outlives_suggestion: &mut OutlivesSuggestionBuilder, renctx: &mut RegionErrorNamingCtx, - ) -> DiagnosticBuilder<'a> { + ) { debug!("report_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr); - let (category, _, span) = self.best_blame_constraint(&mbcx.body, fr, fr_origin, |r| { - self.provides_universal_region(r, fr, outlived_fr) - }); + let (category, _, span) = + self.nonlexical_regioncx.best_blame_constraint(&self.body, fr, fr_origin, |r| { + self.nonlexical_regioncx.provides_universal_region(r, fr, outlived_fr) + }); debug!("report_error: category={:?} {:?}", category, span); // Check if we can use one of the "nice region errors". if let (Some(f), Some(o)) = (self.to_error_region(fr), self.to_error_region(outlived_fr)) { - let tables = mbcx.infcx.tcx.typeck_tables_of(mbcx.mir_def_id); - let nice = NiceRegionError::new_from_span(mbcx.infcx, span, o, f, Some(tables)); + let tables = self.infcx.tcx.typeck_tables_of(self.mir_def_id); + let nice = NiceRegionError::new_from_span(self.infcx, span, o, f, Some(tables)); if let Some(diag) = nice.try_report_from_nll() { - return diag; + diag.buffer(&mut self.errors_buffer); + return; } } let (fr_is_local, outlived_fr_is_local): (bool, bool) = ( - self.universal_regions.is_local_free_region(fr), - self.universal_regions.is_local_free_region(outlived_fr), + self.nonlexical_regioncx.universal_regions.is_local_free_region(fr), + self.nonlexical_regioncx.universal_regions.is_local_free_region(outlived_fr), ); debug!( @@ -197,28 +200,30 @@ impl<'tcx> RegionInferenceContext<'tcx> { span, }; - match (category, fr_is_local, outlived_fr_is_local) { - (ConstraintCategory::Return, true, false) if self.is_closure_fn_mut(mbcx.infcx, fr) => { - self.report_fnmut_error(mbcx, &errci, renctx) + let diag = match (category, fr_is_local, outlived_fr_is_local) { + (ConstraintCategory::Return, true, false) if self.is_closure_fn_mut(fr) => { + self.report_fnmut_error(&errci, renctx) } (ConstraintCategory::Assignment, true, false) | (ConstraintCategory::CallArgument, true, false) => { - let mut db = self.report_escaping_data_error(mbcx, &errci, renctx); + let mut db = self.report_escaping_data_error(&errci, renctx); - outlives_suggestion.intermediate_suggestion(mbcx, &errci, renctx, &mut db); + outlives_suggestion.intermediate_suggestion(self, &errci, renctx, &mut db); outlives_suggestion.collect_constraint(fr, outlived_fr); db } _ => { - let mut db = self.report_general_error(mbcx, &errci, renctx); + let mut db = self.report_general_error(&errci, renctx); - outlives_suggestion.intermediate_suggestion(mbcx, &errci, renctx, &mut db); + outlives_suggestion.intermediate_suggestion(self, &errci, renctx, &mut db); outlives_suggestion.collect_constraint(fr, outlived_fr); db } - } + }; + + diag.buffer(&mut self.errors_buffer); } /// Report a specialized error when `FnMut` closures return a reference to a captured variable. @@ -239,13 +244,12 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// ``` fn report_fnmut_error( &self, - mbcx: &MirBorrowckCtxt<'_, 'tcx>, errci: &ErrorConstraintInfo, renctx: &mut RegionErrorNamingCtx, - ) -> DiagnosticBuilder<'_> { + ) -> DiagnosticBuilder<'tcx> { let ErrorConstraintInfo { outlived_fr, span, .. } = errci; - let mut diag = mbcx + let mut diag = self .infcx .tcx .sess @@ -253,7 +257,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { // We should check if the return type of this closure is in fact a closure - in that // case, we can special case the error further. - let return_type_is_closure = self.universal_regions.unnormalized_output_ty.is_closure(); + let return_type_is_closure = + self.nonlexical_regioncx.universal_regions.unnormalized_output_ty.is_closure(); let message = if return_type_is_closure { "returns a closure that contains a reference to a captured variable, which then \ escapes the closure body" @@ -263,7 +268,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { diag.span_label(*span, message); - match self.give_region_a_name(mbcx, renctx, *outlived_fr).unwrap().source { + match self.give_region_a_name(renctx, *outlived_fr).unwrap().source { RegionNameSource::NamedEarlyBoundRegion(fr_span) | RegionNameSource::NamedFreeRegion(fr_span) | RegionNameSource::SynthesizedFreeEnvRegion(fr_span, _) @@ -300,28 +305,27 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// ``` fn report_escaping_data_error( &self, - mbcx: &MirBorrowckCtxt<'_, 'tcx>, errci: &ErrorConstraintInfo, renctx: &mut RegionErrorNamingCtx, - ) -> DiagnosticBuilder<'_> { + ) -> DiagnosticBuilder<'tcx> { let ErrorConstraintInfo { span, category, .. } = errci; - let fr_name_and_span = self.get_var_name_and_span_for_region( - mbcx.infcx.tcx, - &mbcx.body, - &mbcx.local_names, - &mbcx.upvars, + let fr_name_and_span = self.nonlexical_regioncx.get_var_name_and_span_for_region( + self.infcx.tcx, + &self.body, + &self.local_names, + &self.upvars, errci.fr, ); - let outlived_fr_name_and_span = self.get_var_name_and_span_for_region( - mbcx.infcx.tcx, - &mbcx.body, - &mbcx.local_names, - &mbcx.upvars, + let outlived_fr_name_and_span = self.nonlexical_regioncx.get_var_name_and_span_for_region( + self.infcx.tcx, + &self.body, + &self.local_names, + &self.upvars, errci.outlived_fr, ); - let escapes_from = match self.universal_regions.defining_ty { + let escapes_from = match self.nonlexical_regioncx.universal_regions.defining_ty { DefiningTy::Closure(..) => "closure", DefiningTy::Generator(..) => "generator", DefiningTy::FnDef(..) => "function", @@ -335,14 +339,13 @@ impl<'tcx> RegionInferenceContext<'tcx> { || escapes_from == "const" { return self.report_general_error( - mbcx, &ErrorConstraintInfo { fr_is_local: true, outlived_fr_is_local: false, ..*errci }, renctx, ); } let mut diag = - borrowck_errors::borrowed_data_escapes_closure(mbcx.infcx.tcx, *span, escapes_from); + borrowck_errors::borrowed_data_escapes_closure(self.infcx.tcx, *span, escapes_from); if let Some((Some(outlived_fr_name), outlived_fr_span)) = outlived_fr_name_and_span { diag.span_label( @@ -386,10 +389,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// ``` fn report_general_error( &self, - mbcx: &MirBorrowckCtxt<'_, 'tcx>, errci: &ErrorConstraintInfo, renctx: &mut RegionErrorNamingCtx, - ) -> DiagnosticBuilder<'_> { + ) -> DiagnosticBuilder<'tcx> { let ErrorConstraintInfo { fr, fr_is_local, @@ -401,14 +403,14 @@ impl<'tcx> RegionInferenceContext<'tcx> { } = errci; let mut diag = - mbcx.infcx.tcx.sess.struct_span_err(*span, "lifetime may not live long enough"); + self.infcx.tcx.sess.struct_span_err(*span, "lifetime may not live long enough"); let mir_def_name = - if mbcx.infcx.tcx.is_closure(mbcx.mir_def_id) { "closure" } else { "function" }; + if self.infcx.tcx.is_closure(self.mir_def_id) { "closure" } else { "function" }; - let fr_name = self.give_region_a_name(mbcx, renctx, *fr).unwrap(); + let fr_name = self.give_region_a_name(renctx, *fr).unwrap(); fr_name.highlight_region_name(&mut diag); - let outlived_fr_name = self.give_region_a_name(mbcx, renctx, *outlived_fr).unwrap(); + let outlived_fr_name = self.give_region_a_name(renctx, *outlived_fr).unwrap(); outlived_fr_name.highlight_region_name(&mut diag); match (category, outlived_fr_is_local, fr_is_local) { @@ -435,7 +437,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } - self.add_static_impl_trait_suggestion(mbcx.infcx, &mut diag, *fr, fr_name, *outlived_fr); + self.add_static_impl_trait_suggestion(&mut diag, *fr, fr_name, *outlived_fr); diag } @@ -451,8 +453,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// ``` fn add_static_impl_trait_suggestion( &self, - infcx: &InferCtxt<'_, 'tcx>, - diag: &mut DiagnosticBuilder<'_>, + diag: &mut DiagnosticBuilder<'tcx>, fr: RegionVid, // We need to pass `fr_name` - computing it again will label it twice. fr_name: RegionName, @@ -461,11 +462,12 @@ impl<'tcx> RegionInferenceContext<'tcx> { if let (Some(f), Some(ty::RegionKind::ReStatic)) = (self.to_error_region(fr), self.to_error_region(outlived_fr)) { - if let Some((ty::TyS { kind: ty::Opaque(did, substs), .. }, _)) = infcx + if let Some((ty::TyS { kind: ty::Opaque(did, substs), .. }, _)) = self + .infcx .tcx .is_suitable_region(f) .map(|r| r.def_id) - .map(|id| infcx.tcx.return_type_impl_trait(id)) + .map(|id| self.infcx.tcx.return_type_impl_trait(id)) .unwrap_or(None) { // Check whether or not the impl trait return type is intended to capture @@ -473,8 +475,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { // // eg. check for `impl Trait + 'static` instead of `impl Trait`. let has_static_predicate = { - let predicates_of = infcx.tcx.predicates_of(*did); - let bounds = predicates_of.instantiate(infcx.tcx, substs); + let predicates_of = self.infcx.tcx.predicates_of(*did); + let bounds = predicates_of.instantiate(self.infcx.tcx, substs); let mut found = false; for predicate in bounds.predicates { @@ -502,8 +504,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { diag.help(&format!("consider replacing `{}` with `{}`", fr_name, static_str)); } else { // Otherwise, we should suggest adding a constraint on the return type. - let span = infcx.tcx.def_span(*did); - if let Ok(snippet) = infcx.tcx.sess.source_map().span_to_snippet(span) { + let span = self.infcx.tcx.def_span(*did); + if let Ok(snippet) = self.infcx.tcx.sess.source_map().span_to_snippet(span) { let suggestable_fr_name = if fr_name.was_named() { fr_name.to_string() } else { diff --git a/src/librustc_mir/borrow_check/diagnostics/region_name.rs b/src/librustc_mir/borrow_check/diagnostics/region_name.rs index 734e3861c62de..e5dfb0f70eee2 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_name.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_name.rs @@ -2,7 +2,7 @@ use std::fmt::{self, Display}; use rustc::ty::print::RegionHighlightMode; use rustc::ty::subst::{GenericArgKind, SubstsRef}; -use rustc::ty::{self, RegionVid, Ty, TyCtxt}; +use rustc::ty::{self, RegionVid, Ty}; use rustc_data_structures::fx::FxHashMap; use rustc_errors::DiagnosticBuilder; use rustc_hir as hir; @@ -10,10 +10,7 @@ use rustc_hir::def::{DefKind, Res}; use rustc_span::symbol::kw; use rustc_span::{symbol::Symbol, Span, DUMMY_SP}; -use crate::borrow_check::{ - nll::ToRegionVid, region_infer::RegionInferenceContext, universal_regions::DefiningTy, - MirBorrowckCtxt, -}; +use crate::borrow_check::{nll::ToRegionVid, universal_regions::DefiningTy, MirBorrowckCtxt}; /// A name for a particular region used in emitting diagnostics. This name could be a generated /// name like `'1`, a name used by the user like `'a`, or a name like `'static`. @@ -161,7 +158,7 @@ impl Display for RegionName { } } -impl<'tcx> RegionInferenceContext<'tcx> { +impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { /// Maps from an internal MIR region vid to something that we can /// report to the user. In some cases, the region vids will map /// directly to lifetimes that the user has a name for (e.g., @@ -189,24 +186,23 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// and then return the name `'1` for us to use. crate fn give_region_a_name( &self, - mbcx: &MirBorrowckCtxt<'_, 'tcx>, renctx: &mut RegionErrorNamingCtx, fr: RegionVid, ) -> Option { debug!("give_region_a_name(fr={:?}, counter={:?})", fr, renctx.counter); - assert!(self.universal_regions.is_universal_region(fr)); + assert!(self.nonlexical_regioncx.universal_regions.is_universal_region(fr)); if let Some(value) = renctx.get(&fr) { return Some(value.clone()); } let value = self - .give_name_from_error_region(mbcx, fr, renctx) - .or_else(|| self.give_name_if_anonymous_region_appears_in_arguments(mbcx, fr, renctx)) - .or_else(|| self.give_name_if_anonymous_region_appears_in_upvars(mbcx, fr, renctx)) - .or_else(|| self.give_name_if_anonymous_region_appears_in_output(mbcx, fr, renctx)) - .or_else(|| self.give_name_if_anonymous_region_appears_in_yield_ty(mbcx, fr, renctx)); + .give_name_from_error_region(fr, renctx) + .or_else(|| self.give_name_if_anonymous_region_appears_in_arguments(fr, renctx)) + .or_else(|| self.give_name_if_anonymous_region_appears_in_upvars(fr, renctx)) + .or_else(|| self.give_name_if_anonymous_region_appears_in_output(fr, renctx)) + .or_else(|| self.give_name_if_anonymous_region_appears_in_yield_ty(fr, renctx)); if let Some(ref value) = value { renctx.insert(fr, value.clone()); @@ -222,13 +218,12 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// named variants. fn give_name_from_error_region( &self, - mbcx: &MirBorrowckCtxt<'_, 'tcx>, fr: RegionVid, renctx: &mut RegionErrorNamingCtx, ) -> Option { let error_region = self.to_error_region(fr)?; - let tcx = mbcx.infcx.tcx; + let tcx = self.infcx.tcx; debug!("give_region_a_name: error_region = {:?}", error_region); match error_region { @@ -276,13 +271,13 @@ impl<'tcx> RegionInferenceContext<'tcx> { } ty::BoundRegion::BrEnv => { - let mir_hir_id = mbcx + let mir_hir_id = self .infcx .tcx .hir() - .as_local_hir_id(mbcx.mir_def_id) + .as_local_hir_id(self.mir_def_id) .expect("non-local mir"); - let def_ty = self.universal_regions.defining_ty; + let def_ty = self.nonlexical_regioncx.universal_regions.defining_ty; if let DefiningTy::Closure(def_id, substs) = def_ty { let args_span = if let hir::ExprKind::Closure(_, _, _, span, _) = @@ -346,38 +341,34 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// ``` fn give_name_if_anonymous_region_appears_in_arguments( &self, - mbcx: &MirBorrowckCtxt<'_, 'tcx>, fr: RegionVid, renctx: &mut RegionErrorNamingCtx, ) -> Option { - let implicit_inputs = self.universal_regions.defining_ty.implicit_inputs(); - let argument_index = self.get_argument_index_for_region(mbcx.infcx.tcx, fr)?; - - let arg_ty = - self.universal_regions.unnormalized_input_tys[implicit_inputs + argument_index]; - if let Some(region_name) = self.give_name_if_we_can_match_hir_ty_from_argument( - mbcx, - fr, - arg_ty, - argument_index, - renctx, - ) { + let implicit_inputs = + self.nonlexical_regioncx.universal_regions.defining_ty.implicit_inputs(); + let argument_index = + self.nonlexical_regioncx.get_argument_index_for_region(self.infcx.tcx, fr)?; + + let arg_ty = self.nonlexical_regioncx.universal_regions.unnormalized_input_tys + [implicit_inputs + argument_index]; + if let Some(region_name) = + self.give_name_if_we_can_match_hir_ty_from_argument(fr, arg_ty, argument_index, renctx) + { return Some(region_name); } - self.give_name_if_we_cannot_match_hir_ty(mbcx, fr, arg_ty, renctx) + self.give_name_if_we_cannot_match_hir_ty(fr, arg_ty, renctx) } fn give_name_if_we_can_match_hir_ty_from_argument( &self, - mbcx: &MirBorrowckCtxt<'_, 'tcx>, needle_fr: RegionVid, argument_ty: Ty<'tcx>, argument_index: usize, renctx: &mut RegionErrorNamingCtx, ) -> Option { - let mir_hir_id = mbcx.infcx.tcx.hir().as_local_hir_id(mbcx.mir_def_id)?; - let fn_decl = mbcx.infcx.tcx.hir().fn_decl_by_hir_id(mir_hir_id)?; + let mir_hir_id = self.infcx.tcx.hir().as_local_hir_id(self.mir_def_id)?; + let fn_decl = self.infcx.tcx.hir().fn_decl_by_hir_id(mir_hir_id)?; let argument_hir_ty: &hir::Ty<'_> = fn_decl.inputs.get(argument_index)?; match argument_hir_ty.kind { // This indicates a variable with no type annotation, like @@ -388,7 +379,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { hir::TyKind::Infer => None, _ => self.give_name_if_we_can_match_hir_ty( - mbcx.infcx.tcx, needle_fr, argument_ty, argument_hir_ty, @@ -410,7 +400,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// ``` fn give_name_if_we_cannot_match_hir_ty( &self, - mbcx: &MirBorrowckCtxt<'_, 'tcx>, needle_fr: RegionVid, argument_ty: Ty<'tcx>, renctx: &mut RegionErrorNamingCtx, @@ -418,7 +407,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let counter = renctx.counter; let mut highlight = RegionHighlightMode::default(); highlight.highlighting_region_vid(needle_fr, counter); - let type_name = mbcx.infcx.extract_type_name(&argument_ty, Some(highlight)).0; + let type_name = self.infcx.extract_type_name(&argument_ty, Some(highlight)).0; debug!( "give_name_if_we_cannot_match_hir_ty: type_name={:?} needle_fr={:?}", @@ -426,10 +415,12 @@ impl<'tcx> RegionInferenceContext<'tcx> { ); let assigned_region_name = if type_name.find(&format!("'{}", counter)).is_some() { // Only add a label if we can confirm that a region was labelled. - let argument_index = self.get_argument_index_for_region(mbcx.infcx.tcx, needle_fr)?; - let (_, span) = self.get_argument_name_and_span_for_region( - &mbcx.body, - &mbcx.local_names, + let argument_index = self + .nonlexical_regioncx + .get_argument_index_for_region(self.infcx.tcx, needle_fr)?; + let (_, span) = self.nonlexical_regioncx.get_argument_name_and_span_for_region( + &self.body, + &self.local_names, argument_index, ); @@ -470,7 +461,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// to highlighting that closest type instead. fn give_name_if_we_can_match_hir_ty( &self, - tcx: TyCtxt<'tcx>, needle_fr: RegionVid, argument_ty: Ty<'tcx>, argument_hir_ty: &hir::Ty<'_>, @@ -495,7 +485,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { let region_name = renctx.synthesize_region_name(); // Just grab the first character, the `&`. - let source_map = tcx.sess.source_map(); + let source_map = self.infcx.tcx.sess.source_map(); let ampersand_span = source_map.start_point(hir_ty.span); return Some(RegionName { @@ -665,13 +655,16 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// ``` fn give_name_if_anonymous_region_appears_in_upvars( &self, - mbcx: &MirBorrowckCtxt<'_, 'tcx>, fr: RegionVid, renctx: &mut RegionErrorNamingCtx, ) -> Option { - let upvar_index = self.get_upvar_index_for_region(mbcx.infcx.tcx, fr)?; - let (upvar_name, upvar_span) = - self.get_upvar_name_and_span_for_region(mbcx.infcx.tcx, &mbcx.upvars, upvar_index); + let upvar_index = + self.nonlexical_regioncx.get_upvar_index_for_region(self.infcx.tcx, fr)?; + let (upvar_name, upvar_span) = self.nonlexical_regioncx.get_upvar_name_and_span_for_region( + self.infcx.tcx, + &self.upvars, + upvar_index, + ); let region_name = renctx.synthesize_region_name(); Some(RegionName { @@ -686,13 +679,12 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// or be early bound (named, not in argument). fn give_name_if_anonymous_region_appears_in_output( &self, - mbcx: &MirBorrowckCtxt<'_, 'tcx>, fr: RegionVid, renctx: &mut RegionErrorNamingCtx, ) -> Option { - let tcx = mbcx.infcx.tcx; + let tcx = self.infcx.tcx; - let return_ty = self.universal_regions.unnormalized_output_ty; + let return_ty = self.nonlexical_regioncx.universal_regions.unnormalized_output_ty; debug!("give_name_if_anonymous_region_appears_in_output: return_ty = {:?}", return_ty); if !tcx.any_free_region_meets(&return_ty, |r| r.to_region_vid() == fr) { return None; @@ -700,9 +692,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { let mut highlight = RegionHighlightMode::default(); highlight.highlighting_region_vid(fr, renctx.counter); - let type_name = mbcx.infcx.extract_type_name(&return_ty, Some(highlight)).0; + let type_name = self.infcx.extract_type_name(&return_ty, Some(highlight)).0; - let mir_hir_id = tcx.hir().as_local_hir_id(mbcx.mir_def_id).expect("non-local mir"); + let mir_hir_id = tcx.hir().as_local_hir_id(self.mir_def_id).expect("non-local mir"); let (return_span, mir_description) = match tcx.hir().get(mir_hir_id) { hir::Node::Expr(hir::Expr { @@ -719,7 +711,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { kind: hir::ImplItemKind::Method(method_sig, _), .. }) => (method_sig.decl.output.span(), ""), - _ => (mbcx.body.span, ""), + _ => (self.body.span, ""), }; Some(RegionName { @@ -737,16 +729,15 @@ impl<'tcx> RegionInferenceContext<'tcx> { fn give_name_if_anonymous_region_appears_in_yield_ty( &self, - mbcx: &MirBorrowckCtxt<'_, 'tcx>, fr: RegionVid, renctx: &mut RegionErrorNamingCtx, ) -> Option { // Note: generators from `async fn` yield `()`, so we don't have to // worry about them here. - let yield_ty = self.universal_regions.yield_ty?; + let yield_ty = self.nonlexical_regioncx.universal_regions.yield_ty?; debug!("give_name_if_anonymous_region_appears_in_yield_ty: yield_ty = {:?}", yield_ty,); - let tcx = mbcx.infcx.tcx; + let tcx = self.infcx.tcx; if !tcx.any_free_region_meets(&yield_ty, |r| r.to_region_vid() == fr) { return None; @@ -754,15 +745,15 @@ impl<'tcx> RegionInferenceContext<'tcx> { let mut highlight = RegionHighlightMode::default(); highlight.highlighting_region_vid(fr, renctx.counter); - let type_name = mbcx.infcx.extract_type_name(&yield_ty, Some(highlight)).0; + let type_name = self.infcx.extract_type_name(&yield_ty, Some(highlight)).0; - let mir_hir_id = tcx.hir().as_local_hir_id(mbcx.mir_def_id).expect("non-local mir"); + let mir_hir_id = tcx.hir().as_local_hir_id(self.mir_def_id).expect("non-local mir"); let yield_span = match tcx.hir().get(mir_hir_id) { hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(_, _, _, span, _), .. }) => (tcx.sess.source_map().end_point(*span)), - _ => mbcx.body.span, + _ => self.body.span, }; debug!( diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index fc1b723c27120..209df021ba0d1 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -1471,7 +1471,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // Iterate through all the errors, producing a diagnostic for each one. The diagnostics are // buffered in the `MirBorrowckCtxt`. - // FIXME(mark-i-m): Would be great to get rid of the naming context. + // TODO(mark-i-m): Would be great to get rid of the naming context. let mut region_naming = RegionErrorNamingCtx::new(); let mut outlives_suggestion = OutlivesSuggestionBuilder::default(); @@ -1479,8 +1479,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { match nll_error { RegionErrorKind::TypeTestError { type_test } => { // Try to convert the lower-bound region into something named we can print for the user. - let lower_bound_region = - self.nonlexical_regioncx.to_error_region(type_test.lower_bound); + let lower_bound_region = self.to_error_region(type_test.lower_bound); // Skip duplicate-ish errors. let type_test_span = type_test.locations.span(&self.body); @@ -1557,16 +1556,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { RegionErrorKind::RegionError { fr_origin, longer_fr, shorter_fr, is_reported } => { if is_reported { - let db = self.nonlexical_regioncx.report_error( - self, + self.report_error( longer_fr, fr_origin, shorter_fr, &mut outlives_suggestion, &mut region_naming, ); - - db.buffer(&mut self.errors_buffer); } else { // We only report the first error, so as not to overwhelm the user. See // `RegRegionErrorKind` docs. From 786db7399fa8214aa2412fbeb18033524bfa8b34 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sat, 28 Dec 2019 19:28:50 -0600 Subject: [PATCH 029/169] Move report_region_errors to region_errors.rs --- .../borrow_check/diagnostics/region_errors.rs | 126 +++++++++++++++++- src/librustc_mir/borrow_check/mod.rs | 123 +---------------- 2 files changed, 125 insertions(+), 124 deletions(-) diff --git a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs index b0be82164d876..5980ff0073253 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs @@ -1,6 +1,8 @@ //! Error reporting machinery for lifetime errors. -use rustc::infer::{error_reporting::nice_region_error::NiceRegionError, NLLRegionVariableOrigin}; +use rustc::infer::{ + error_reporting::nice_region_error::NiceRegionError, opaque_types, NLLRegionVariableOrigin, +}; use rustc::mir::ConstraintCategory; use rustc::ty::{self, RegionVid, Ty}; use rustc_errors::{Applicability, DiagnosticBuilder}; @@ -109,8 +111,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { /// existentially bound, then we check its inferred value and try /// to find a good name from that. Returns `None` if we can't find /// one (e.g., this is just some random part of the CFG). - // TODO(mark-i-m): make this private when we move report_region_errors here... - crate fn to_error_region(&self, r: RegionVid) -> Option> { + pub(super) fn to_error_region(&self, r: RegionVid) -> Option> { self.to_error_region_vid(r) .and_then(|r| self.nonlexical_regioncx.definitions[r].external_name) } @@ -147,6 +148,125 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { false } + /// Produces nice borrowck error diagnostics for all the errors collected in `nll_errors`. + pub(in crate::borrow_check) fn report_region_errors(&mut self, nll_errors: RegionErrors<'tcx>) { + // Iterate through all the errors, producing a diagnostic for each one. The diagnostics are + // buffered in the `MirBorrowckCtxt`. + + // TODO(mark-i-m): Would be great to get rid of the naming context. + let mut region_naming = RegionErrorNamingCtx::new(); + let mut outlives_suggestion = OutlivesSuggestionBuilder::default(); + + for nll_error in nll_errors.into_iter() { + match nll_error { + RegionErrorKind::TypeTestError { type_test } => { + // Try to convert the lower-bound region into something named we can print for the user. + let lower_bound_region = self.to_error_region(type_test.lower_bound); + + // Skip duplicate-ish errors. + let type_test_span = type_test.locations.span(&self.body); + + if let Some(lower_bound_region) = lower_bound_region { + let region_scope_tree = &self.infcx.tcx.region_scope_tree(self.mir_def_id); + self.infcx + .construct_generic_bound_failure( + region_scope_tree, + type_test_span, + None, + type_test.generic_kind, + lower_bound_region, + ) + .buffer(&mut self.errors_buffer); + } else { + // FIXME. We should handle this case better. It + // indicates that we have e.g., some region variable + // whose value is like `'a+'b` where `'a` and `'b` are + // distinct unrelated univesal regions that are not + // known to outlive one another. It'd be nice to have + // some examples where this arises to decide how best + // to report it; we could probably handle it by + // iterating over the universal regions and reporting + // an error that multiple bounds are required. + self.infcx + .tcx + .sess + .struct_span_err( + type_test_span, + &format!("`{}` does not live long enough", type_test.generic_kind), + ) + .buffer(&mut self.errors_buffer); + } + } + + RegionErrorKind::UnexpectedHiddenRegion { + opaque_type_def_id, + hidden_ty, + member_region, + } => { + let region_scope_tree = &self.infcx.tcx.region_scope_tree(self.mir_def_id); + opaque_types::unexpected_hidden_region_diagnostic( + self.infcx.tcx, + Some(region_scope_tree), + opaque_type_def_id, + hidden_ty, + member_region, + ) + .buffer(&mut self.errors_buffer); + } + + RegionErrorKind::BoundUniversalRegionError { + longer_fr, + fr_origin, + error_element, + } => { + let error_region = + self.nonlexical_regioncx.region_from_element(longer_fr, error_element); + + // Find the code to blame for the fact that `longer_fr` outlives `error_fr`. + let (_, span) = self.nonlexical_regioncx.find_outlives_blame_span( + &self.body, + longer_fr, + fr_origin, + error_region, + ); + + // FIXME: improve this error message + self.infcx + .tcx + .sess + .struct_span_err(span, "higher-ranked subtype error") + .buffer(&mut self.errors_buffer); + } + + RegionErrorKind::RegionError { fr_origin, longer_fr, shorter_fr, is_reported } => { + if is_reported { + self.report_error( + longer_fr, + fr_origin, + shorter_fr, + &mut outlives_suggestion, + &mut region_naming, + ); + } else { + // We only report the first error, so as not to overwhelm the user. See + // `RegRegionErrorKind` docs. + // + // FIXME: currently we do nothing with these, but perhaps we can do better? + // FIXME: try collecting these constraints on the outlives suggestion + // builder. Does it make the suggestions any better? + debug!( + "Unreported region error: can't prove that {:?}: {:?}", + longer_fr, shorter_fr + ); + } + } + } + } + + // Emit one outlives suggestions for each MIR def we borrowck + outlives_suggestion.add_suggestion(self, &mut region_naming); + } + /// Report an error because the universal region `fr` was required to outlive /// `outlived_fr` but it is not known to do so. For example: /// diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 209df021ba0d1..22037ac6c81b2 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -1,6 +1,6 @@ //! This query borrow-checks the MIR to (further) ensure it is not broken. -use rustc::infer::{opaque_types, InferCtxt}; +use rustc::infer::InferCtxt; use rustc::lint::builtin::MUTABLE_BORROW_RESERVATION_CONFLICT; use rustc::lint::builtin::UNUSED_MUT; use rustc::mir::{ @@ -39,9 +39,7 @@ use crate::dataflow::{do_dataflow, DebugFormatted}; use crate::dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces}; use crate::transform::MirSource; -use self::diagnostics::{ - AccessKind, OutlivesSuggestionBuilder, RegionErrorKind, RegionErrorNamingCtx, RegionErrors, -}; +use self::diagnostics::AccessKind; use self::flows::Flows; use self::location::LocationTable; use self::prefixes::PrefixSet; @@ -1465,123 +1463,6 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // initial reservation. } } - - /// Produces nice borrowck error diagnostics for all the errors collected in `nll_errors`. - fn report_region_errors(&mut self, nll_errors: RegionErrors<'tcx>) { - // Iterate through all the errors, producing a diagnostic for each one. The diagnostics are - // buffered in the `MirBorrowckCtxt`. - - // TODO(mark-i-m): Would be great to get rid of the naming context. - let mut region_naming = RegionErrorNamingCtx::new(); - let mut outlives_suggestion = OutlivesSuggestionBuilder::default(); - - for nll_error in nll_errors.into_iter() { - match nll_error { - RegionErrorKind::TypeTestError { type_test } => { - // Try to convert the lower-bound region into something named we can print for the user. - let lower_bound_region = self.to_error_region(type_test.lower_bound); - - // Skip duplicate-ish errors. - let type_test_span = type_test.locations.span(&self.body); - - if let Some(lower_bound_region) = lower_bound_region { - let region_scope_tree = &self.infcx.tcx.region_scope_tree(self.mir_def_id); - self.infcx - .construct_generic_bound_failure( - region_scope_tree, - type_test_span, - None, - type_test.generic_kind, - lower_bound_region, - ) - .buffer(&mut self.errors_buffer); - } else { - // FIXME. We should handle this case better. It indicates that we have - // e.g., some region variable whose value is like `'a+'b` where `'a` and - // `'b` are distinct unrelated univesal regions that are not known to - // outlive one another. It'd be nice to have some examples where this - // arises to decide how best to report it; we could probably handle it by - // iterating over the universal regions and reporting an error that - // multiple bounds are required. - self.infcx - .tcx - .sess - .struct_span_err( - type_test_span, - &format!("`{}` does not live long enough", type_test.generic_kind), - ) - .buffer(&mut self.errors_buffer); - } - } - - RegionErrorKind::UnexpectedHiddenRegion { - opaque_type_def_id, - hidden_ty, - member_region, - } => { - let region_scope_tree = &self.infcx.tcx.region_scope_tree(self.mir_def_id); - opaque_types::unexpected_hidden_region_diagnostic( - self.infcx.tcx, - Some(region_scope_tree), - opaque_type_def_id, - hidden_ty, - member_region, - ) - .buffer(&mut self.errors_buffer); - } - - RegionErrorKind::BoundUniversalRegionError { - longer_fr, - fr_origin, - error_element, - } => { - let error_region = - self.nonlexical_regioncx.region_from_element(longer_fr, error_element); - - // Find the code to blame for the fact that `longer_fr` outlives `error_fr`. - let (_, span) = self.nonlexical_regioncx.find_outlives_blame_span( - &self.body, - longer_fr, - fr_origin, - error_region, - ); - - // FIXME: improve this error message - self.infcx - .tcx - .sess - .struct_span_err(span, "higher-ranked subtype error") - .buffer(&mut self.errors_buffer); - } - - RegionErrorKind::RegionError { fr_origin, longer_fr, shorter_fr, is_reported } => { - if is_reported { - self.report_error( - longer_fr, - fr_origin, - shorter_fr, - &mut outlives_suggestion, - &mut region_naming, - ); - } else { - // We only report the first error, so as not to overwhelm the user. See - // `RegRegionErrorKind` docs. - // - // FIXME: currently we do nothing with these, but perhaps we can do better? - // FIXME: try collecting these constraints on the outlives suggestion - // builder. Does it make the suggestions any better? - debug!( - "Unreported region error: can't prove that {:?}: {:?}", - longer_fr, shorter_fr - ); - } - } - } - } - - // Emit one outlives suggestions for each MIR def we borrowck - outlives_suggestion.add_suggestion(self, &mut region_naming); - } } impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { From 66c5d5b70697dd98468a88b455dc99681c810db1 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sat, 28 Dec 2019 19:35:18 -0600 Subject: [PATCH 030/169] Privatize the fields of RegionInferenceContext --- .../borrow_check/diagnostics/region_errors.rs | 18 +++--- .../borrow_check/diagnostics/region_name.rs | 12 ++-- .../borrow_check/diagnostics/var_name.rs | 16 ++--- .../borrow_check/region_infer/mod.rs | 63 ++++++++++++++----- 4 files changed, 71 insertions(+), 38 deletions(-) diff --git a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs index 5980ff0073253..dcba790ad7e48 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs @@ -113,18 +113,18 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { /// one (e.g., this is just some random part of the CFG). pub(super) fn to_error_region(&self, r: RegionVid) -> Option> { self.to_error_region_vid(r) - .and_then(|r| self.nonlexical_regioncx.definitions[r].external_name) + .and_then(|r| self.nonlexical_regioncx.region_definition(r).external_name) } /// Returns the `RegionVid` corresponding to the region returned by /// `to_error_region`. pub(super) fn to_error_region_vid(&self, r: RegionVid) -> Option { - if self.nonlexical_regioncx.universal_regions.is_universal_region(r) { + if self.nonlexical_regioncx.universal_regions().is_universal_region(r) { Some(r) } else { - let r_scc = self.nonlexical_regioncx.constraint_sccs.scc(r); let upper_bound = self.nonlexical_regioncx.universal_upper_bound(r); - if self.nonlexical_regioncx.scc_values.contains(r_scc, upper_bound) { + + if self.nonlexical_regioncx.upper_bound_in_region_scc(r, upper_bound) { self.to_error_region_vid(upper_bound) } else { None @@ -137,7 +137,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { if let Some(ty::ReFree(free_region)) = self.to_error_region(fr) { if let ty::BoundRegion::BrEnv = free_region.bound_region { if let DefiningTy::Closure(def_id, substs) = - self.nonlexical_regioncx.universal_regions.defining_ty + self.nonlexical_regioncx.universal_regions().defining_ty { let closure_kind_ty = substs.as_closure().kind_ty(def_id, self.infcx.tcx); return Some(ty::ClosureKind::FnMut) == closure_kind_ty.to_opt_closure_kind(); @@ -302,8 +302,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } let (fr_is_local, outlived_fr_is_local): (bool, bool) = ( - self.nonlexical_regioncx.universal_regions.is_local_free_region(fr), - self.nonlexical_regioncx.universal_regions.is_local_free_region(outlived_fr), + self.nonlexical_regioncx.universal_regions().is_local_free_region(fr), + self.nonlexical_regioncx.universal_regions().is_local_free_region(outlived_fr), ); debug!( @@ -378,7 +378,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // We should check if the return type of this closure is in fact a closure - in that // case, we can special case the error further. let return_type_is_closure = - self.nonlexical_regioncx.universal_regions.unnormalized_output_ty.is_closure(); + self.nonlexical_regioncx.universal_regions().unnormalized_output_ty.is_closure(); let message = if return_type_is_closure { "returns a closure that contains a reference to a captured variable, which then \ escapes the closure body" @@ -445,7 +445,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { errci.outlived_fr, ); - let escapes_from = match self.nonlexical_regioncx.universal_regions.defining_ty { + let escapes_from = match self.nonlexical_regioncx.universal_regions().defining_ty { DefiningTy::Closure(..) => "closure", DefiningTy::Generator(..) => "generator", DefiningTy::FnDef(..) => "function", diff --git a/src/librustc_mir/borrow_check/diagnostics/region_name.rs b/src/librustc_mir/borrow_check/diagnostics/region_name.rs index e5dfb0f70eee2..b6bfa30b4dcdf 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_name.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_name.rs @@ -191,7 +191,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { ) -> Option { debug!("give_region_a_name(fr={:?}, counter={:?})", fr, renctx.counter); - assert!(self.nonlexical_regioncx.universal_regions.is_universal_region(fr)); + assert!(self.nonlexical_regioncx.universal_regions().is_universal_region(fr)); if let Some(value) = renctx.get(&fr) { return Some(value.clone()); @@ -277,7 +277,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { .hir() .as_local_hir_id(self.mir_def_id) .expect("non-local mir"); - let def_ty = self.nonlexical_regioncx.universal_regions.defining_ty; + let def_ty = self.nonlexical_regioncx.universal_regions().defining_ty; if let DefiningTy::Closure(def_id, substs) = def_ty { let args_span = if let hir::ExprKind::Closure(_, _, _, span, _) = @@ -345,11 +345,11 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { renctx: &mut RegionErrorNamingCtx, ) -> Option { let implicit_inputs = - self.nonlexical_regioncx.universal_regions.defining_ty.implicit_inputs(); + self.nonlexical_regioncx.universal_regions().defining_ty.implicit_inputs(); let argument_index = self.nonlexical_regioncx.get_argument_index_for_region(self.infcx.tcx, fr)?; - let arg_ty = self.nonlexical_regioncx.universal_regions.unnormalized_input_tys + let arg_ty = self.nonlexical_regioncx.universal_regions().unnormalized_input_tys [implicit_inputs + argument_index]; if let Some(region_name) = self.give_name_if_we_can_match_hir_ty_from_argument(fr, arg_ty, argument_index, renctx) @@ -684,7 +684,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { ) -> Option { let tcx = self.infcx.tcx; - let return_ty = self.nonlexical_regioncx.universal_regions.unnormalized_output_ty; + let return_ty = self.nonlexical_regioncx.universal_regions().unnormalized_output_ty; debug!("give_name_if_anonymous_region_appears_in_output: return_ty = {:?}", return_ty); if !tcx.any_free_region_meets(&return_ty, |r| r.to_region_vid() == fr) { return None; @@ -734,7 +734,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { ) -> Option { // Note: generators from `async fn` yield `()`, so we don't have to // worry about them here. - let yield_ty = self.nonlexical_regioncx.universal_regions.yield_ty?; + let yield_ty = self.nonlexical_regioncx.universal_regions().yield_ty?; debug!("give_name_if_anonymous_region_appears_in_yield_ty: yield_ty = {:?}", yield_ty,); let tcx = self.infcx.tcx; diff --git a/src/librustc_mir/borrow_check/diagnostics/var_name.rs b/src/librustc_mir/borrow_check/diagnostics/var_name.rs index 9e3d2a7d5f63c..5f3585ce8b119 100644 --- a/src/librustc_mir/borrow_check/diagnostics/var_name.rs +++ b/src/librustc_mir/borrow_check/diagnostics/var_name.rs @@ -16,7 +16,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { fr: RegionVid, ) -> Option<(Option, Span)> { debug!("get_var_name_and_span_for_region(fr={:?})", fr); - assert!(self.universal_regions.is_universal_region(fr)); + assert!(self.universal_regions().is_universal_region(fr)); debug!("get_var_name_and_span_for_region: attempting upvar"); self.get_upvar_index_for_region(tcx, fr) @@ -35,7 +35,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// Search the upvars (if any) to find one that references fr. Return its index. crate fn get_upvar_index_for_region(&self, tcx: TyCtxt<'tcx>, fr: RegionVid) -> Option { let upvar_index = - self.universal_regions.defining_ty.upvar_tys(tcx).position(|upvar_ty| { + self.universal_regions().defining_ty.upvar_tys(tcx).position(|upvar_ty| { debug!("get_upvar_index_for_region: upvar_ty={:?}", upvar_ty); tcx.any_free_region_meets(&upvar_ty, |r| { let r = r.to_region_vid(); @@ -44,7 +44,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { }) })?; - let upvar_ty = self.universal_regions.defining_ty.upvar_tys(tcx).nth(upvar_index); + let upvar_ty = self.universal_regions().defining_ty.upvar_tys(tcx).nth(upvar_index); debug!( "get_upvar_index_for_region: found {:?} in upvar {} which has type {:?}", @@ -85,9 +85,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { tcx: TyCtxt<'tcx>, fr: RegionVid, ) -> Option { - let implicit_inputs = self.universal_regions.defining_ty.implicit_inputs(); + let implicit_inputs = self.universal_regions().defining_ty.implicit_inputs(); let argument_index = - self.universal_regions.unnormalized_input_tys.iter().skip(implicit_inputs).position( + self.universal_regions().unnormalized_input_tys.iter().skip(implicit_inputs).position( |arg_ty| { debug!("get_argument_index_for_region: arg_ty = {:?}", arg_ty); tcx.any_free_region_meets(arg_ty, |r| r.to_region_vid() == fr) @@ -96,7 +96,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { debug!( "get_argument_index_for_region: found {:?} in argument {} which has type {:?}", - fr, argument_index, self.universal_regions.unnormalized_input_tys[argument_index], + fr, + argument_index, + self.universal_regions().unnormalized_input_tys[argument_index], ); Some(argument_index) @@ -110,7 +112,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { local_names: &IndexVec>, argument_index: usize, ) -> (Option, Span) { - let implicit_inputs = self.universal_regions.defining_ty.implicit_inputs(); + let implicit_inputs = self.universal_regions().defining_ty.implicit_inputs(); let argument_local = Local::new(implicit_inputs + argument_index + 1); debug!("get_argument_name_and_span_for_region: argument_local={:?}", argument_local); diff --git a/src/librustc_mir/borrow_check/region_infer/mod.rs b/src/librustc_mir/borrow_check/region_infer/mod.rs index 406b28e1e3256..359f75cac8376 100644 --- a/src/librustc_mir/borrow_check/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/region_infer/mod.rs @@ -44,49 +44,48 @@ pub struct RegionInferenceContext<'tcx> { /// variables are identified by their index (`RegionVid`). The /// definition contains information about where the region came /// from as well as its final inferred value. - pub(in crate::borrow_check) definitions: IndexVec>, + definitions: IndexVec>, /// The liveness constraints added to each region. For most /// regions, these start out empty and steadily grow, though for /// each universally quantified region R they start out containing /// the entire CFG and `end(R)`. - pub(in crate::borrow_check) liveness_constraints: LivenessValues, + liveness_constraints: LivenessValues, /// The outlives constraints computed by the type-check. - pub(in crate::borrow_check) constraints: Rc, + constraints: Rc, /// The constraint-set, but in graph form, making it easy to traverse /// the constraints adjacent to a particular region. Used to construct /// the SCC (see `constraint_sccs`) and for error reporting. - pub(in crate::borrow_check) constraint_graph: Rc, + constraint_graph: Rc, /// The SCC computed from `constraints` and the constraint /// graph. We have an edge from SCC A to SCC B if `A: B`. Used to /// compute the values of each region. - pub(in crate::borrow_check) constraint_sccs: Rc>, + constraint_sccs: Rc>, /// Reverse of the SCC constraint graph -- i.e., an edge `A -> B` /// exists if `B: A`. Computed lazilly. - pub(in crate::borrow_check) rev_constraint_graph: Option>>, + rev_constraint_graph: Option>>, /// The "R0 member of [R1..Rn]" constraints, indexed by SCC. - pub(in crate::borrow_check) member_constraints: - Rc>, + member_constraints: Rc>, /// Records the member constraints that we applied to each scc. /// This is useful for error reporting. Once constraint /// propagation is done, this vector is sorted according to /// `member_region_scc`. - pub(in crate::borrow_check) member_constraints_applied: Vec, + member_constraints_applied: Vec, /// Map closure bounds to a `Span` that should be used for error reporting. - pub(in crate::borrow_check) closure_bounds_mapping: + closure_bounds_mapping: FxHashMap>, /// Contains the minimum universe of any variable within the same /// SCC. We will ensure that no SCC contains values that are not /// visible from this index. - pub(in crate::borrow_check) scc_universes: IndexVec, + scc_universes: IndexVec, /// Contains a "representative" from each SCC. This will be the /// minimal RegionVid belonging to that universe. It is used as a @@ -95,23 +94,23 @@ pub struct RegionInferenceContext<'tcx> { /// of its SCC and be sure that -- if they have the same repr -- /// they *must* be equal (though not having the same repr does not /// mean they are unequal). - pub(in crate::borrow_check) scc_representatives: IndexVec, + scc_representatives: IndexVec, /// The final inferred values of the region variables; we compute /// one value per SCC. To get the value for any given *region*, /// you first find which scc it is a part of. - pub(in crate::borrow_check) scc_values: RegionValues, + scc_values: RegionValues, /// Type constraints that we check after solving. - pub(in crate::borrow_check) type_tests: Vec>, + type_tests: Vec>, /// Information about the universally quantified regions in scope /// on this function. - pub(in crate::borrow_check) universal_regions: Rc>, + universal_regions: Rc>, /// Information about how the universally quantified regions in /// scope on this function relate to one another. - pub(in crate::borrow_check) universal_region_relations: Rc>, + universal_region_relations: Rc>, } /// Each time that `apply_member_constraint` is successful, it appends @@ -1840,6 +1839,38 @@ impl<'tcx> RegionInferenceContext<'tcx> { .unwrap() } + /// Get the region outlived by `longer_fr` and live at `element`. + crate fn region_from_element(&self, longer_fr: RegionVid, element: RegionElement) -> RegionVid { + match element { + RegionElement::Location(l) => self.find_sub_region_live_at(longer_fr, l), + RegionElement::RootUniversalRegion(r) => r, + RegionElement::PlaceholderRegion(error_placeholder) => self + .definitions + .iter_enumerated() + .filter_map(|(r, definition)| match definition.origin { + NLLRegionVariableOrigin::Placeholder(p) if p == error_placeholder => Some(r), + _ => None, + }) + .next() + .unwrap(), + } + } + + /// Get the region definition of `r`. + crate fn region_definition(&self, r: RegionVid) -> &RegionDefinition<'tcx> { + &self.definitions[r] + } + + /// Check if the SCC of `r` contains `upper`. + crate fn upper_bound_in_region_scc(&self, r: RegionVid, upper: RegionVid) -> bool { + let r_scc = self.constraint_sccs.scc(r); + self.scc_values.contains(r_scc, upper) + } + + crate fn universal_regions(&self) -> Rc> { + self.universal_regions.clone() + } + /// Tries to find the best constraint to blame for the fact that /// `R: from_region`, where `R` is some region that meets /// `target_test`. This works by following the constraint graph, From 234b9301087ac21dd1dec5e6cad59cb76346ee6c Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sat, 28 Dec 2019 20:02:20 -0600 Subject: [PATCH 031/169] rename nonlexical_regioncx -> regioncx --- .../diagnostics/explain_borrow.rs | 15 +++------ .../borrow_check/diagnostics/region_errors.rs | 32 +++++++++---------- .../borrow_check/diagnostics/region_name.rs | 28 +++++++--------- src/librustc_mir/borrow_check/mod.rs | 7 ++-- 4 files changed, 34 insertions(+), 48 deletions(-) diff --git a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs b/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs index 45c6c845cd156..ca5cf5bc741a0 100644 --- a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs +++ b/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs @@ -260,17 +260,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { borrow_region: RegionVid, outlived_region: RegionVid, ) -> (ConstraintCategory, bool, Span, Option) { - let (category, from_closure, span) = self.nonlexical_regioncx.best_blame_constraint( + let (category, from_closure, span) = self.regioncx.best_blame_constraint( &self.body, borrow_region, NLLRegionVariableOrigin::FreeRegion, - |r| { - self.nonlexical_regioncx.provides_universal_region( - r, - borrow_region, - outlived_region, - ) - }, + |r| self.regioncx.provides_universal_region(r, borrow_region, outlived_region), ); let mut renctx = RegionErrorNamingCtx::new(); @@ -303,15 +297,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { location, borrow, kind_place ); - let regioncx = &self.nonlexical_regioncx; + let regioncx = &self.regioncx; let body: &Body<'_> = &self.body; let tcx = self.infcx.tcx; let borrow_region_vid = borrow.region; debug!("explain_why_borrow_contains_point: borrow_region_vid={:?}", borrow_region_vid); - let region_sub = - self.nonlexical_regioncx.find_sub_region_live_at(borrow_region_vid, location); + let region_sub = self.regioncx.find_sub_region_live_at(borrow_region_vid, location); debug!("explain_why_borrow_contains_point: region_sub={:?}", region_sub); match find_use::find(body, regioncx, tcx, region_sub, location) { diff --git a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs index dcba790ad7e48..f3dc8e72e3016 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs @@ -112,19 +112,18 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { /// to find a good name from that. Returns `None` if we can't find /// one (e.g., this is just some random part of the CFG). pub(super) fn to_error_region(&self, r: RegionVid) -> Option> { - self.to_error_region_vid(r) - .and_then(|r| self.nonlexical_regioncx.region_definition(r).external_name) + self.to_error_region_vid(r).and_then(|r| self.regioncx.region_definition(r).external_name) } /// Returns the `RegionVid` corresponding to the region returned by /// `to_error_region`. pub(super) fn to_error_region_vid(&self, r: RegionVid) -> Option { - if self.nonlexical_regioncx.universal_regions().is_universal_region(r) { + if self.regioncx.universal_regions().is_universal_region(r) { Some(r) } else { - let upper_bound = self.nonlexical_regioncx.universal_upper_bound(r); + let upper_bound = self.regioncx.universal_upper_bound(r); - if self.nonlexical_regioncx.upper_bound_in_region_scc(r, upper_bound) { + if self.regioncx.upper_bound_in_region_scc(r, upper_bound) { self.to_error_region_vid(upper_bound) } else { None @@ -137,7 +136,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { if let Some(ty::ReFree(free_region)) = self.to_error_region(fr) { if let ty::BoundRegion::BrEnv = free_region.bound_region { if let DefiningTy::Closure(def_id, substs) = - self.nonlexical_regioncx.universal_regions().defining_ty + self.regioncx.universal_regions().defining_ty { let closure_kind_ty = substs.as_closure().kind_ty(def_id, self.infcx.tcx); return Some(ty::ClosureKind::FnMut) == closure_kind_ty.to_opt_closure_kind(); @@ -219,11 +218,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { fr_origin, error_element, } => { - let error_region = - self.nonlexical_regioncx.region_from_element(longer_fr, error_element); + let error_region = self.regioncx.region_from_element(longer_fr, error_element); // Find the code to blame for the fact that `longer_fr` outlives `error_fr`. - let (_, span) = self.nonlexical_regioncx.find_outlives_blame_span( + let (_, span) = self.regioncx.find_outlives_blame_span( &self.body, longer_fr, fr_origin, @@ -286,8 +284,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { debug!("report_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr); let (category, _, span) = - self.nonlexical_regioncx.best_blame_constraint(&self.body, fr, fr_origin, |r| { - self.nonlexical_regioncx.provides_universal_region(r, fr, outlived_fr) + self.regioncx.best_blame_constraint(&self.body, fr, fr_origin, |r| { + self.regioncx.provides_universal_region(r, fr, outlived_fr) }); debug!("report_error: category={:?} {:?}", category, span); @@ -302,8 +300,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } let (fr_is_local, outlived_fr_is_local): (bool, bool) = ( - self.nonlexical_regioncx.universal_regions().is_local_free_region(fr), - self.nonlexical_regioncx.universal_regions().is_local_free_region(outlived_fr), + self.regioncx.universal_regions().is_local_free_region(fr), + self.regioncx.universal_regions().is_local_free_region(outlived_fr), ); debug!( @@ -378,7 +376,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // We should check if the return type of this closure is in fact a closure - in that // case, we can special case the error further. let return_type_is_closure = - self.nonlexical_regioncx.universal_regions().unnormalized_output_ty.is_closure(); + self.regioncx.universal_regions().unnormalized_output_ty.is_closure(); let message = if return_type_is_closure { "returns a closure that contains a reference to a captured variable, which then \ escapes the closure body" @@ -430,14 +428,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ) -> DiagnosticBuilder<'tcx> { let ErrorConstraintInfo { span, category, .. } = errci; - let fr_name_and_span = self.nonlexical_regioncx.get_var_name_and_span_for_region( + let fr_name_and_span = self.regioncx.get_var_name_and_span_for_region( self.infcx.tcx, &self.body, &self.local_names, &self.upvars, errci.fr, ); - let outlived_fr_name_and_span = self.nonlexical_regioncx.get_var_name_and_span_for_region( + let outlived_fr_name_and_span = self.regioncx.get_var_name_and_span_for_region( self.infcx.tcx, &self.body, &self.local_names, @@ -445,7 +443,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { errci.outlived_fr, ); - let escapes_from = match self.nonlexical_regioncx.universal_regions().defining_ty { + let escapes_from = match self.regioncx.universal_regions().defining_ty { DefiningTy::Closure(..) => "closure", DefiningTy::Generator(..) => "generator", DefiningTy::FnDef(..) => "function", diff --git a/src/librustc_mir/borrow_check/diagnostics/region_name.rs b/src/librustc_mir/borrow_check/diagnostics/region_name.rs index b6bfa30b4dcdf..7ce29713240ce 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_name.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_name.rs @@ -191,7 +191,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { ) -> Option { debug!("give_region_a_name(fr={:?}, counter={:?})", fr, renctx.counter); - assert!(self.nonlexical_regioncx.universal_regions().is_universal_region(fr)); + assert!(self.regioncx.universal_regions().is_universal_region(fr)); if let Some(value) = renctx.get(&fr) { return Some(value.clone()); @@ -277,7 +277,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { .hir() .as_local_hir_id(self.mir_def_id) .expect("non-local mir"); - let def_ty = self.nonlexical_regioncx.universal_regions().defining_ty; + let def_ty = self.regioncx.universal_regions().defining_ty; if let DefiningTy::Closure(def_id, substs) = def_ty { let args_span = if let hir::ExprKind::Closure(_, _, _, span, _) = @@ -344,12 +344,10 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { fr: RegionVid, renctx: &mut RegionErrorNamingCtx, ) -> Option { - let implicit_inputs = - self.nonlexical_regioncx.universal_regions().defining_ty.implicit_inputs(); - let argument_index = - self.nonlexical_regioncx.get_argument_index_for_region(self.infcx.tcx, fr)?; + let implicit_inputs = self.regioncx.universal_regions().defining_ty.implicit_inputs(); + let argument_index = self.regioncx.get_argument_index_for_region(self.infcx.tcx, fr)?; - let arg_ty = self.nonlexical_regioncx.universal_regions().unnormalized_input_tys + let arg_ty = self.regioncx.universal_regions().unnormalized_input_tys [implicit_inputs + argument_index]; if let Some(region_name) = self.give_name_if_we_can_match_hir_ty_from_argument(fr, arg_ty, argument_index, renctx) @@ -415,10 +413,9 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { ); let assigned_region_name = if type_name.find(&format!("'{}", counter)).is_some() { // Only add a label if we can confirm that a region was labelled. - let argument_index = self - .nonlexical_regioncx - .get_argument_index_for_region(self.infcx.tcx, needle_fr)?; - let (_, span) = self.nonlexical_regioncx.get_argument_name_and_span_for_region( + let argument_index = + self.regioncx.get_argument_index_for_region(self.infcx.tcx, needle_fr)?; + let (_, span) = self.regioncx.get_argument_name_and_span_for_region( &self.body, &self.local_names, argument_index, @@ -658,9 +655,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { fr: RegionVid, renctx: &mut RegionErrorNamingCtx, ) -> Option { - let upvar_index = - self.nonlexical_regioncx.get_upvar_index_for_region(self.infcx.tcx, fr)?; - let (upvar_name, upvar_span) = self.nonlexical_regioncx.get_upvar_name_and_span_for_region( + let upvar_index = self.regioncx.get_upvar_index_for_region(self.infcx.tcx, fr)?; + let (upvar_name, upvar_span) = self.regioncx.get_upvar_name_and_span_for_region( self.infcx.tcx, &self.upvars, upvar_index, @@ -684,7 +680,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { ) -> Option { let tcx = self.infcx.tcx; - let return_ty = self.nonlexical_regioncx.universal_regions().unnormalized_output_ty; + let return_ty = self.regioncx.universal_regions().unnormalized_output_ty; debug!("give_name_if_anonymous_region_appears_in_output: return_ty = {:?}", return_ty); if !tcx.any_free_region_meets(&return_ty, |r| r.to_region_vid() == fr) { return None; @@ -734,7 +730,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { ) -> Option { // Note: generators from `async fn` yield `()`, so we don't have to // worry about them here. - let yield_ty = self.nonlexical_regioncx.universal_regions().yield_ty?; + let yield_ty = self.regioncx.universal_regions().yield_ty?; debug!("give_name_if_anonymous_region_appears_in_yield_ty: yield_ty = {:?}", yield_ty,); let tcx = self.infcx.tcx; diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 22037ac6c81b2..0ad9d4492b208 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -283,7 +283,7 @@ fn do_mir_borrowck<'a, 'tcx>( move_error_reported: BTreeMap::new(), uninitialized_error_reported: Default::default(), errors_buffer, - nonlexical_regioncx: regioncx, + regioncx, used_mut: Default::default(), used_mut_upvars: SmallVec::new(), borrow_set, @@ -474,10 +474,9 @@ crate struct MirBorrowckCtxt<'cx, 'tcx> { /// If the function we're checking is a closure, then we'll need to report back the list of /// mutable upvars that have been used. This field keeps track of them. used_mut_upvars: SmallVec<[Field; 8]>, - /// Non-lexical region inference context, if NLL is enabled. This - /// contains the results from region inference and lets us e.g. + /// Region inference context. This contains the results from region inference and lets us e.g. /// find out which CFG points are contained in each borrow region. - nonlexical_regioncx: Rc>, + regioncx: Rc>, /// The set of borrows extracted from the MIR borrow_set: Rc>, From a804868bbf578dada5249ac3c79b7b524684c78e Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Sat, 28 Dec 2019 20:36:42 -0600 Subject: [PATCH 032/169] Get rid of RegionErrorNamingContext --- .../diagnostics/explain_borrow.rs | 7 +- .../borrow_check/diagnostics/mod.rs | 2 +- .../diagnostics/outlives_suggestion.rs | 25 +--- .../borrow_check/diagnostics/region_errors.rs | 51 +++---- .../borrow_check/diagnostics/region_name.rs | 138 ++++++------------ src/librustc_mir/borrow_check/mod.rs | 15 +- .../borrow_check/region_infer/mod.rs | 17 --- .../ui/c-variadic/variadic-ffi-4.nll.stderr | 4 +- 8 files changed, 88 insertions(+), 171 deletions(-) diff --git a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs b/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs index ca5cf5bc741a0..01b7c5645fe8b 100644 --- a/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs +++ b/src/librustc_mir/borrow_check/diagnostics/explain_borrow.rs @@ -16,8 +16,8 @@ use rustc_span::symbol::Symbol; use rustc_span::Span; use crate::borrow_check::{ - borrow_set::BorrowData, diagnostics::RegionErrorNamingCtx, nll::ConstraintDescription, - region_infer::Cause, MirBorrowckCtxt, WriteKind, + borrow_set::BorrowData, nll::ConstraintDescription, region_infer::Cause, MirBorrowckCtxt, + WriteKind, }; use super::{find_use, RegionName, UseSpans}; @@ -267,8 +267,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { |r| self.regioncx.provides_universal_region(r, borrow_region, outlived_region), ); - let mut renctx = RegionErrorNamingCtx::new(); - let outlived_fr_name = self.give_region_a_name(&mut renctx, outlived_region); + let outlived_fr_name = self.give_region_a_name(outlived_region); (category, from_closure, span, outlived_fr_name) } diff --git a/src/librustc_mir/borrow_check/diagnostics/mod.rs b/src/librustc_mir/borrow_check/diagnostics/mod.rs index 3f3bdb9d36c76..0fc73d33f9001 100644 --- a/src/librustc_mir/borrow_check/diagnostics/mod.rs +++ b/src/librustc_mir/borrow_check/diagnostics/mod.rs @@ -32,7 +32,7 @@ mod region_errors; crate use mutability_errors::AccessKind; crate use outlives_suggestion::OutlivesSuggestionBuilder; crate use region_errors::{ErrorConstraintInfo, RegionErrorKind, RegionErrors}; -crate use region_name::{RegionErrorNamingCtx, RegionName, RegionNameSource}; +crate use region_name::{RegionName, RegionNameSource}; pub(super) struct IncludingDowncast(pub(super) bool); diff --git a/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs b/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs index be067fcf4f261..ee9489078bdb9 100644 --- a/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs +++ b/src/librustc_mir/borrow_check/diagnostics/outlives_suggestion.rs @@ -12,7 +12,7 @@ use smallvec::SmallVec; use crate::borrow_check::MirBorrowckCtxt; -use super::{ErrorConstraintInfo, RegionErrorNamingCtx, RegionName, RegionNameSource}; +use super::{ErrorConstraintInfo, RegionName, RegionNameSource}; /// The different things we could suggest. enum SuggestedConstraint { @@ -77,17 +77,15 @@ impl OutlivesSuggestionBuilder { fn region_vid_to_name( &self, mbcx: &MirBorrowckCtxt<'_, '_>, - renctx: &mut RegionErrorNamingCtx, region: RegionVid, ) -> Option { - mbcx.give_region_a_name(renctx, region).filter(Self::region_name_is_suggestable) + mbcx.give_region_a_name(region).filter(Self::region_name_is_suggestable) } /// Compiles a list of all suggestions to be printed in the final big suggestion. fn compile_all_suggestions( &self, mbcx: &MirBorrowckCtxt<'_, '_>, - renctx: &mut RegionErrorNamingCtx, ) -> SmallVec<[SuggestedConstraint; 2]> { let mut suggested = SmallVec::new(); @@ -96,7 +94,7 @@ impl OutlivesSuggestionBuilder { let mut unified_already = FxHashSet::default(); for (fr, outlived) in &self.constraints_to_add { - let fr_name = if let Some(fr_name) = self.region_vid_to_name(mbcx, renctx, *fr) { + let fr_name = if let Some(fr_name) = self.region_vid_to_name(mbcx, *fr) { fr_name } else { continue; @@ -105,9 +103,7 @@ impl OutlivesSuggestionBuilder { let outlived = outlived .iter() // if there is a `None`, we will just omit that constraint - .filter_map(|fr| { - self.region_vid_to_name(mbcx, renctx, *fr).map(|rname| (fr, rname)) - }) + .filter_map(|fr| self.region_vid_to_name(mbcx, *fr).map(|rname| (fr, rname))) .collect::>(); // No suggestable outlived lifetimes. @@ -171,12 +167,11 @@ impl OutlivesSuggestionBuilder { &mut self, mbcx: &MirBorrowckCtxt<'_, '_>, errci: &ErrorConstraintInfo, - renctx: &mut RegionErrorNamingCtx, diag: &mut DiagnosticBuilder<'_>, ) { // Emit an intermediate note. - let fr_name = self.region_vid_to_name(mbcx, renctx, errci.fr); - let outlived_fr_name = self.region_vid_to_name(mbcx, renctx, errci.outlived_fr); + let fr_name = self.region_vid_to_name(mbcx, errci.fr); + let outlived_fr_name = self.region_vid_to_name(mbcx, errci.outlived_fr); if let (Some(fr_name), Some(outlived_fr_name)) = (fr_name, outlived_fr_name) { if let RegionNameSource::Static = outlived_fr_name.source { @@ -192,11 +187,7 @@ impl OutlivesSuggestionBuilder { /// If there is a suggestion to emit, add a diagnostic to the buffer. This is the final /// suggestion including all collected constraints. - crate fn add_suggestion( - &self, - mbcx: &mut MirBorrowckCtxt<'_, '_>, - renctx: &mut RegionErrorNamingCtx, - ) { + crate fn add_suggestion(&self, mbcx: &mut MirBorrowckCtxt<'_, '_>) { // No constraints to add? Done. if self.constraints_to_add.is_empty() { debug!("No constraints to suggest."); @@ -213,7 +204,7 @@ impl OutlivesSuggestionBuilder { } // Get all suggestable constraints. - let suggested = self.compile_all_suggestions(mbcx, renctx); + let suggested = self.compile_all_suggestions(mbcx); // If there are no suggestable constraints... if suggested.is_empty() { diff --git a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs index f3dc8e72e3016..729a679e92a32 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs @@ -19,7 +19,7 @@ use crate::borrow_check::{ MirBorrowckCtxt, }; -use super::{OutlivesSuggestionBuilder, RegionErrorNamingCtx, RegionName, RegionNameSource}; +use super::{OutlivesSuggestionBuilder, RegionName, RegionNameSource}; impl ConstraintDescription for ConstraintCategory { fn description(&self) -> &'static str { @@ -152,8 +152,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // Iterate through all the errors, producing a diagnostic for each one. The diagnostics are // buffered in the `MirBorrowckCtxt`. - // TODO(mark-i-m): Would be great to get rid of the naming context. - let mut region_naming = RegionErrorNamingCtx::new(); let mut outlives_suggestion = OutlivesSuggestionBuilder::default(); for nll_error in nll_errors.into_iter() { @@ -243,7 +241,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { fr_origin, shorter_fr, &mut outlives_suggestion, - &mut region_naming, ); } else { // We only report the first error, so as not to overwhelm the user. See @@ -262,7 +259,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { } // Emit one outlives suggestions for each MIR def we borrowck - outlives_suggestion.add_suggestion(self, &mut region_naming); + outlives_suggestion.add_suggestion(self); } /// Report an error because the universal region `fr` was required to outlive @@ -279,7 +276,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { fr_origin: NLLRegionVariableOrigin, outlived_fr: RegionVid, outlives_suggestion: &mut OutlivesSuggestionBuilder, - renctx: &mut RegionErrorNamingCtx, ) { debug!("report_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr); @@ -320,21 +316,21 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let diag = match (category, fr_is_local, outlived_fr_is_local) { (ConstraintCategory::Return, true, false) if self.is_closure_fn_mut(fr) => { - self.report_fnmut_error(&errci, renctx) + self.report_fnmut_error(&errci) } (ConstraintCategory::Assignment, true, false) | (ConstraintCategory::CallArgument, true, false) => { - let mut db = self.report_escaping_data_error(&errci, renctx); + let mut db = self.report_escaping_data_error(&errci); - outlives_suggestion.intermediate_suggestion(self, &errci, renctx, &mut db); + outlives_suggestion.intermediate_suggestion(self, &errci, &mut db); outlives_suggestion.collect_constraint(fr, outlived_fr); db } _ => { - let mut db = self.report_general_error(&errci, renctx); + let mut db = self.report_general_error(&errci); - outlives_suggestion.intermediate_suggestion(self, &errci, renctx, &mut db); + outlives_suggestion.intermediate_suggestion(self, &errci, &mut db); outlives_suggestion.collect_constraint(fr, outlived_fr); db @@ -360,11 +356,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { /// executing... /// = note: ...therefore, returned references to captured variables will escape the closure /// ``` - fn report_fnmut_error( - &self, - errci: &ErrorConstraintInfo, - renctx: &mut RegionErrorNamingCtx, - ) -> DiagnosticBuilder<'tcx> { + fn report_fnmut_error(&self, errci: &ErrorConstraintInfo) -> DiagnosticBuilder<'tcx> { let ErrorConstraintInfo { outlived_fr, span, .. } = errci; let mut diag = self @@ -386,7 +378,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { diag.span_label(*span, message); - match self.give_region_a_name(renctx, *outlived_fr).unwrap().source { + match self.give_region_a_name(*outlived_fr).unwrap().source { RegionNameSource::NamedEarlyBoundRegion(fr_span) | RegionNameSource::NamedFreeRegion(fr_span) | RegionNameSource::SynthesizedFreeEnvRegion(fr_span, _) @@ -421,11 +413,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { /// LL | ref_obj(x) /// | ^^^^^^^^^^ `x` escapes the function body here /// ``` - fn report_escaping_data_error( - &self, - errci: &ErrorConstraintInfo, - renctx: &mut RegionErrorNamingCtx, - ) -> DiagnosticBuilder<'tcx> { + fn report_escaping_data_error(&self, errci: &ErrorConstraintInfo) -> DiagnosticBuilder<'tcx> { let ErrorConstraintInfo { span, category, .. } = errci; let fr_name_and_span = self.regioncx.get_var_name_and_span_for_region( @@ -456,10 +444,11 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { || (*category == ConstraintCategory::Assignment && escapes_from == "function") || escapes_from == "const" { - return self.report_general_error( - &ErrorConstraintInfo { fr_is_local: true, outlived_fr_is_local: false, ..*errci }, - renctx, - ); + return self.report_general_error(&ErrorConstraintInfo { + fr_is_local: true, + outlived_fr_is_local: false, + ..*errci + }); } let mut diag = @@ -505,11 +494,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { /// | ^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'a` but it /// | is returning data with lifetime `'b` /// ``` - fn report_general_error( - &self, - errci: &ErrorConstraintInfo, - renctx: &mut RegionErrorNamingCtx, - ) -> DiagnosticBuilder<'tcx> { + fn report_general_error(&self, errci: &ErrorConstraintInfo) -> DiagnosticBuilder<'tcx> { let ErrorConstraintInfo { fr, fr_is_local, @@ -526,9 +511,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { let mir_def_name = if self.infcx.tcx.is_closure(self.mir_def_id) { "closure" } else { "function" }; - let fr_name = self.give_region_a_name(renctx, *fr).unwrap(); + let fr_name = self.give_region_a_name(*fr).unwrap(); fr_name.highlight_region_name(&mut diag); - let outlived_fr_name = self.give_region_a_name(renctx, *outlived_fr).unwrap(); + let outlived_fr_name = self.give_region_a_name(*outlived_fr).unwrap(); outlived_fr_name.highlight_region_name(&mut diag); match (category, outlived_fr_is_local, fr_is_local) { diff --git a/src/librustc_mir/borrow_check/diagnostics/region_name.rs b/src/librustc_mir/borrow_check/diagnostics/region_name.rs index 7ce29713240ce..f7aeec5e76ee9 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_name.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_name.rs @@ -3,7 +3,6 @@ use std::fmt::{self, Display}; use rustc::ty::print::RegionHighlightMode; use rustc::ty::subst::{GenericArgKind, SubstsRef}; use rustc::ty::{self, RegionVid, Ty}; -use rustc_data_structures::fx::FxHashMap; use rustc_errors::DiagnosticBuilder; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; @@ -52,46 +51,6 @@ crate enum RegionNameSource { AnonRegionFromAsyncFn(Span), } -/// Records region names that have been assigned before so that we can use the same ones in later -/// diagnostics. -#[derive(Debug, Clone)] -crate struct RegionErrorNamingCtx { - /// Record the region names generated for each region in the given - /// MIR def so that we can reuse them later in help/error messages. - renctx: FxHashMap, - - /// The counter for generating new region names. - counter: usize, -} - -impl RegionErrorNamingCtx { - crate fn new() -> Self { - Self { counter: 1, renctx: FxHashMap::default() } - } - - /// Get the name of `region` if it has previously been named. - crate fn get(&self, region: &RegionVid) -> Option<&RegionName> { - self.renctx.get(region) - } - - /// Give `region` the name `name`. - crate fn insert(&mut self, region: RegionVid, name: RegionName) { - self.renctx.insert(region, name); - } - - /// Creates a synthetic region named `'N`, where `N` is the next value of the counter. Then, - /// increment the counter. - /// - /// The name is not memoized. A separate call to `insert` should be made later. (Currently, - /// this happens at the end of `give_region_a_name`). - crate fn synthesize_region_name(&mut self) -> Symbol { - let c = self.counter; - self.counter += 1; - - Symbol::intern(&format!("'{:?}", c)) - } -} - impl RegionName { crate fn was_named(&self) -> bool { match self.source { @@ -159,6 +118,17 @@ impl Display for RegionName { } impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { + /// Generate a synthetic region named `'N`, where `N` is the next value of the counter. Then, + /// increment the counter. + /// + /// This is _not_ idempotent. Call `give_region_a_name` when possible. + fn synthesize_region_name(&self) -> Symbol { + let mut counter = self.next_region_name.try_borrow_mut().unwrap(); + let c = *counter; + *counter += 1; + Symbol::intern(&format!("'{:?}", c)) + } + /// Maps from an internal MIR region vid to something that we can /// report to the user. In some cases, the region vids will map /// directly to lifetimes that the user has a name for (e.g., @@ -167,6 +137,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { /// that end, this function takes a "diagnostic" so that it can /// create auxiliary notes as needed. /// + /// The names are memoized, so this is both cheap to recompute and idempotent. + /// /// Example (function arguments): /// /// Suppose we are trying to give a name to the lifetime of the @@ -184,28 +156,28 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { /// ``` /// /// and then return the name `'1` for us to use. - crate fn give_region_a_name( - &self, - renctx: &mut RegionErrorNamingCtx, - fr: RegionVid, - ) -> Option { - debug!("give_region_a_name(fr={:?}, counter={:?})", fr, renctx.counter); + crate fn give_region_a_name(&self, fr: RegionVid) -> Option { + debug!( + "give_region_a_name(fr={:?}, counter={:?})", + fr, + self.next_region_name.try_borrow().unwrap() + ); assert!(self.regioncx.universal_regions().is_universal_region(fr)); - if let Some(value) = renctx.get(&fr) { + if let Some(value) = self.region_names.try_borrow_mut().unwrap().get(&fr) { return Some(value.clone()); } let value = self - .give_name_from_error_region(fr, renctx) - .or_else(|| self.give_name_if_anonymous_region_appears_in_arguments(fr, renctx)) - .or_else(|| self.give_name_if_anonymous_region_appears_in_upvars(fr, renctx)) - .or_else(|| self.give_name_if_anonymous_region_appears_in_output(fr, renctx)) - .or_else(|| self.give_name_if_anonymous_region_appears_in_yield_ty(fr, renctx)); + .give_name_from_error_region(fr) + .or_else(|| self.give_name_if_anonymous_region_appears_in_arguments(fr)) + .or_else(|| self.give_name_if_anonymous_region_appears_in_upvars(fr)) + .or_else(|| self.give_name_if_anonymous_region_appears_in_output(fr)) + .or_else(|| self.give_name_if_anonymous_region_appears_in_yield_ty(fr)); if let Some(ref value) = value { - renctx.insert(fr, value.clone()); + self.region_names.try_borrow_mut().unwrap().insert(fr, value.clone()); } debug!("give_region_a_name: gave name {:?}", value); @@ -216,11 +188,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { /// *user* has a name for. In that case, we'll be able to map /// `fr` to a `Region<'tcx>`, and that region will be one of /// named variants. - fn give_name_from_error_region( - &self, - fr: RegionVid, - renctx: &mut RegionErrorNamingCtx, - ) -> Option { + fn give_name_from_error_region(&self, fr: RegionVid) -> Option { let error_region = self.to_error_region(fr)?; let tcx = self.infcx.tcx; @@ -262,7 +230,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { // happen if we have an elided name in an async fn for example: the // compiler will generate a region named `'_`, but reporting such a name is // not actually useful, so we synthesize a name for it instead. - let name = renctx.synthesize_region_name(); + let name = self.synthesize_region_name(); Some(RegionName { name, source: RegionNameSource::AnonRegionFromAsyncFn(span), @@ -287,7 +255,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { } else { bug!("Closure is not defined by a closure expr"); }; - let region_name = renctx.synthesize_region_name(); + let region_name = self.synthesize_region_name(); let closure_kind_ty = substs.as_closure().kind_ty(def_id, tcx); let note = match closure_kind_ty.to_opt_closure_kind() { @@ -342,7 +310,6 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { fn give_name_if_anonymous_region_appears_in_arguments( &self, fr: RegionVid, - renctx: &mut RegionErrorNamingCtx, ) -> Option { let implicit_inputs = self.regioncx.universal_regions().defining_ty.implicit_inputs(); let argument_index = self.regioncx.get_argument_index_for_region(self.infcx.tcx, fr)?; @@ -350,12 +317,12 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { let arg_ty = self.regioncx.universal_regions().unnormalized_input_tys [implicit_inputs + argument_index]; if let Some(region_name) = - self.give_name_if_we_can_match_hir_ty_from_argument(fr, arg_ty, argument_index, renctx) + self.give_name_if_we_can_match_hir_ty_from_argument(fr, arg_ty, argument_index) { return Some(region_name); } - self.give_name_if_we_cannot_match_hir_ty(fr, arg_ty, renctx) + self.give_name_if_we_cannot_match_hir_ty(fr, arg_ty) } fn give_name_if_we_can_match_hir_ty_from_argument( @@ -363,7 +330,6 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { needle_fr: RegionVid, argument_ty: Ty<'tcx>, argument_index: usize, - renctx: &mut RegionErrorNamingCtx, ) -> Option { let mir_hir_id = self.infcx.tcx.hir().as_local_hir_id(self.mir_def_id)?; let fn_decl = self.infcx.tcx.hir().fn_decl_by_hir_id(mir_hir_id)?; @@ -376,12 +342,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { // (`give_name_if_anonymous_region_appears_in_arguments`). hir::TyKind::Infer => None, - _ => self.give_name_if_we_can_match_hir_ty( - needle_fr, - argument_ty, - argument_hir_ty, - renctx, - ), + _ => self.give_name_if_we_can_match_hir_ty(needle_fr, argument_ty, argument_hir_ty), } } @@ -400,9 +361,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { &self, needle_fr: RegionVid, argument_ty: Ty<'tcx>, - renctx: &mut RegionErrorNamingCtx, ) -> Option { - let counter = renctx.counter; + let counter = *self.next_region_name.try_borrow().unwrap(); let mut highlight = RegionHighlightMode::default(); highlight.highlighting_region_vid(needle_fr, counter); let type_name = self.infcx.extract_type_name(&argument_ty, Some(highlight)).0; @@ -425,7 +385,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { // This counter value will already have been used, so this function will increment // it so the next value will be used next and return the region name that would // have been used. - name: renctx.synthesize_region_name(), + name: self.synthesize_region_name(), source: RegionNameSource::CannotMatchHirTy(span, type_name), }) } else { @@ -461,7 +421,6 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { needle_fr: RegionVid, argument_ty: Ty<'tcx>, argument_hir_ty: &hir::Ty<'_>, - renctx: &mut RegionErrorNamingCtx, ) -> Option { let search_stack: &mut Vec<(Ty<'tcx>, &hir::Ty<'_>)> = &mut vec![(argument_ty, argument_hir_ty)]; @@ -479,7 +438,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { hir::TyKind::Rptr(_lifetime, referent_hir_ty), ) => { if region.to_region_vid() == needle_fr { - let region_name = renctx.synthesize_region_name(); + let region_name = self.synthesize_region_name(); // Just grab the first character, the `&`. let source_map = self.infcx.tcx.sess.source_map(); @@ -512,7 +471,6 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { substs, needle_fr, last_segment, - renctx, search_stack, ) { return Some(name); @@ -557,7 +515,6 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { substs: SubstsRef<'tcx>, needle_fr: RegionVid, last_segment: &'hir hir::PathSegment<'hir>, - renctx: &mut RegionErrorNamingCtx, search_stack: &mut Vec<(Ty<'tcx>, &'hir hir::Ty<'hir>)>, ) -> Option { // Did the user give explicit arguments? (e.g., `Foo<..>`) @@ -569,7 +526,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { | hir::LifetimeName::Error | hir::LifetimeName::Static | hir::LifetimeName::Underscore => { - let region_name = renctx.synthesize_region_name(); + let region_name = self.synthesize_region_name(); let ampersand_span = lifetime.span; Some(RegionName { name: region_name, @@ -650,18 +607,14 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { /// | let x = Some(&22); /// - fully elaborated type of `x` is `Option<&'1 u32>` /// ``` - fn give_name_if_anonymous_region_appears_in_upvars( - &self, - fr: RegionVid, - renctx: &mut RegionErrorNamingCtx, - ) -> Option { + fn give_name_if_anonymous_region_appears_in_upvars(&self, fr: RegionVid) -> Option { let upvar_index = self.regioncx.get_upvar_index_for_region(self.infcx.tcx, fr)?; let (upvar_name, upvar_span) = self.regioncx.get_upvar_name_and_span_for_region( self.infcx.tcx, &self.upvars, upvar_index, ); - let region_name = renctx.synthesize_region_name(); + let region_name = self.synthesize_region_name(); Some(RegionName { name: region_name, @@ -673,11 +626,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { /// must be a closure since, in a free fn, such an argument would /// have to either also appear in an argument (if using elision) /// or be early bound (named, not in argument). - fn give_name_if_anonymous_region_appears_in_output( - &self, - fr: RegionVid, - renctx: &mut RegionErrorNamingCtx, - ) -> Option { + fn give_name_if_anonymous_region_appears_in_output(&self, fr: RegionVid) -> Option { let tcx = self.infcx.tcx; let return_ty = self.regioncx.universal_regions().unnormalized_output_ty; @@ -687,7 +636,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { } let mut highlight = RegionHighlightMode::default(); - highlight.highlighting_region_vid(fr, renctx.counter); + highlight.highlighting_region_vid(fr, *self.next_region_name.try_borrow().unwrap()); let type_name = self.infcx.extract_type_name(&return_ty, Some(highlight)).0; let mir_hir_id = tcx.hir().as_local_hir_id(self.mir_def_id).expect("non-local mir"); @@ -714,7 +663,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { // This counter value will already have been used, so this function will increment it // so the next value will be used next and return the region name that would have been // used. - name: renctx.synthesize_region_name(), + name: self.synthesize_region_name(), source: RegionNameSource::AnonRegionFromOutput( return_span, mir_description.to_string(), @@ -726,7 +675,6 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { fn give_name_if_anonymous_region_appears_in_yield_ty( &self, fr: RegionVid, - renctx: &mut RegionErrorNamingCtx, ) -> Option { // Note: generators from `async fn` yield `()`, so we don't have to // worry about them here. @@ -740,7 +688,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { } let mut highlight = RegionHighlightMode::default(); - highlight.highlighting_region_vid(fr, renctx.counter); + highlight.highlighting_region_vid(fr, *self.next_region_name.try_borrow().unwrap()); let type_name = self.infcx.extract_type_name(&yield_ty, Some(highlight)).0; let mir_hir_id = tcx.hir().as_local_hir_id(self.mir_def_id).expect("non-local mir"); @@ -759,7 +707,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { ); Some(RegionName { - name: renctx.synthesize_region_name(), + name: self.synthesize_region_name(), source: RegionNameSource::AnonRegionFromYieldTy(yield_span, type_name), }) } diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 0ad9d4492b208..90927069242b1 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -11,7 +11,8 @@ use rustc::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind}; use rustc::mir::{Field, ProjectionElem, Promoted, Rvalue, Statement, StatementKind}; use rustc::mir::{Terminator, TerminatorKind}; use rustc::ty::query::Providers; -use rustc::ty::{self, TyCtxt}; +use rustc::ty::{self, RegionVid, TyCtxt}; + use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_data_structures::graph::dominators::Dominators; use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder}; @@ -21,6 +22,7 @@ use rustc_index::bit_set::BitSet; use rustc_index::vec::IndexVec; use smallvec::SmallVec; +use std::cell::RefCell; use std::collections::BTreeMap; use std::mem; use std::rc::Rc; @@ -39,7 +41,7 @@ use crate::dataflow::{do_dataflow, DebugFormatted}; use crate::dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces}; use crate::transform::MirSource; -use self::diagnostics::AccessKind; +use self::diagnostics::{AccessKind, RegionName}; use self::flows::Flows; use self::location::LocationTable; use self::prefixes::PrefixSet; @@ -290,6 +292,8 @@ fn do_mir_borrowck<'a, 'tcx>( dominators, upvars, local_names, + region_names: RefCell::default(), + next_region_name: RefCell::new(1), }; // Compute and report region errors, if any. @@ -489,6 +493,13 @@ crate struct MirBorrowckCtxt<'cx, 'tcx> { /// Names of local (user) variables (extracted from `var_debug_info`). local_names: IndexVec>, + + /// Record the region names generated for each region in the given + /// MIR def so that we can reuse them later in help/error messages. + region_names: RefCell>, + + /// The counter for generating new region names. + next_region_name: RefCell, } // Check that: diff --git a/src/librustc_mir/borrow_check/region_infer/mod.rs b/src/librustc_mir/borrow_check/region_infer/mod.rs index 359f75cac8376..180bb95cab9f4 100644 --- a/src/librustc_mir/borrow_check/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/region_infer/mod.rs @@ -1603,23 +1603,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { } } - /// Get the region outlived by `longer_fr` and live at `element`. - crate fn region_from_element(&self, longer_fr: RegionVid, element: RegionElement) -> RegionVid { - match element { - RegionElement::Location(l) => self.find_sub_region_live_at(longer_fr, l), - RegionElement::RootUniversalRegion(r) => r, - RegionElement::PlaceholderRegion(error_placeholder) => self - .definitions - .iter_enumerated() - .filter_map(|(r, definition)| match definition.origin { - NLLRegionVariableOrigin::Placeholder(p) if p == error_placeholder => Some(r), - _ => None, - }) - .next() - .unwrap(), - } - } - /// We have a constraint `fr1: fr2` that is not satisfied, where /// `fr2` represents some universal region. Here, `r` is some /// region where we know that `fr1: r` and this function has the diff --git a/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr b/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr index 8b70b15fa6e50..89107e799bd22 100644 --- a/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr +++ b/src/test/ui/c-variadic/variadic-ffi-4.nll.stderr @@ -87,12 +87,12 @@ error[E0597]: `ap1` does not live long enough --> $DIR/variadic-ffi-4.rs:24:11 | LL | pub unsafe extern "C" fn no_escape4(_: usize, ap0: &mut VaListImpl, mut ap1: ...) { - | - let's call the lifetime of this reference `'1` + | - let's call the lifetime of this reference `'3` LL | ap0 = &mut ap1; | ------^^^^^^^^ | | | | | borrowed value does not live long enough - | assignment requires that `ap1` is borrowed for `'1` + | assignment requires that `ap1` is borrowed for `'3` ... LL | } | - `ap1` dropped here while still borrowed From f05e40eb992fce44db348cfb1e8ecb4699e9cdd6 Mon Sep 17 00:00:00 2001 From: Mark Mansi Date: Wed, 1 Jan 2020 14:35:08 -0600 Subject: [PATCH 033/169] address review comments --- .../borrow_check/diagnostics/region_errors.rs | 15 +++++++-------- .../borrow_check/diagnostics/region_name.rs | 4 +--- src/librustc_mir/borrow_check/region_infer/mod.rs | 6 ++++-- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs index 729a679e92a32..b999dfa303103 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs @@ -138,8 +138,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { if let DefiningTy::Closure(def_id, substs) = self.regioncx.universal_regions().defining_ty { - let closure_kind_ty = substs.as_closure().kind_ty(def_id, self.infcx.tcx); - return Some(ty::ClosureKind::FnMut) == closure_kind_ty.to_opt_closure_kind(); + return substs.as_closure().kind(def_id, self.infcx.tcx) + == ty::ClosureKind::FnMut; } } } @@ -160,7 +160,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { // Try to convert the lower-bound region into something named we can print for the user. let lower_bound_region = self.to_error_region(type_test.lower_bound); - // Skip duplicate-ish errors. let type_test_span = type_test.locations.span(&self.body); if let Some(lower_bound_region) = lower_bound_region { @@ -236,7 +235,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { RegionErrorKind::RegionError { fr_origin, longer_fr, shorter_fr, is_reported } => { if is_reported { - self.report_error( + self.report_region_error( longer_fr, fr_origin, shorter_fr, @@ -270,21 +269,21 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { /// ``` /// /// Here we would be invoked with `fr = 'a` and `outlived_fr = `'b`. - pub(in crate::borrow_check) fn report_error( + pub(in crate::borrow_check) fn report_region_error( &mut self, fr: RegionVid, fr_origin: NLLRegionVariableOrigin, outlived_fr: RegionVid, outlives_suggestion: &mut OutlivesSuggestionBuilder, ) { - debug!("report_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr); + debug!("report_region_error(fr={:?}, outlived_fr={:?})", fr, outlived_fr); let (category, _, span) = self.regioncx.best_blame_constraint(&self.body, fr, fr_origin, |r| { self.regioncx.provides_universal_region(r, fr, outlived_fr) }); - debug!("report_error: category={:?} {:?}", category, span); + debug!("report_region_error: category={:?} {:?}", category, span); // Check if we can use one of the "nice region errors". if let (Some(f), Some(o)) = (self.to_error_region(fr), self.to_error_region(outlived_fr)) { let tables = self.infcx.tcx.typeck_tables_of(self.mir_def_id); @@ -301,7 +300,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { ); debug!( - "report_error: fr_is_local={:?} outlived_fr_is_local={:?} category={:?}", + "report_region_error: fr_is_local={:?} outlived_fr_is_local={:?} category={:?}", fr_is_local, outlived_fr_is_local, category ); diff --git a/src/librustc_mir/borrow_check/diagnostics/region_name.rs b/src/librustc_mir/borrow_check/diagnostics/region_name.rs index f7aeec5e76ee9..47eb2d8940af4 100644 --- a/src/librustc_mir/borrow_check/diagnostics/region_name.rs +++ b/src/librustc_mir/borrow_check/diagnostics/region_name.rs @@ -123,9 +123,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> { /// /// This is _not_ idempotent. Call `give_region_a_name` when possible. fn synthesize_region_name(&self) -> Symbol { - let mut counter = self.next_region_name.try_borrow_mut().unwrap(); - let c = *counter; - *counter += 1; + let c = self.next_region_name.replace_with(|counter| *counter + 1); Symbol::intern(&format!("'{:?}", c)) } diff --git a/src/librustc_mir/borrow_check/region_infer/mod.rs b/src/librustc_mir/borrow_check/region_infer/mod.rs index 180bb95cab9f4..26d9cf2e0450f 100644 --- a/src/librustc_mir/borrow_check/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/region_infer/mod.rs @@ -846,6 +846,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { // Type-test failed. Report the error. let erased_generic_kind = infcx.tcx.erase_regions(&type_test.generic_kind); + + // Skip duplicate-ish errors. if deduplicate_errors.insert(( erased_generic_kind, type_test.lower_bound, @@ -1850,8 +1852,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { self.scc_values.contains(r_scc, upper) } - crate fn universal_regions(&self) -> Rc> { - self.universal_regions.clone() + crate fn universal_regions(&self) -> &UniversalRegions<'tcx> { + self.universal_regions.as_ref() } /// Tries to find the best constraint to blame for the fact that From 7f65475d00c9a3048d0d664a80314734a8c6989e Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Sun, 12 Jan 2020 21:19:44 -0500 Subject: [PATCH 034/169] Turn off const propagation of ref taking Fixes #67529 Fixes #67640 Fixes #67641 Fixes #67862 --- src/librustc_mir/transform/const_prop.rs | 23 +++--------------- .../mir-opt/const_prop/ref_deref_project.rs | 4 ++-- src/test/ui/consts/issue-67529.rs | 11 +++++++++ src/test/ui/consts/issue-67640.rs | 24 +++++++++++++++++++ src/test/ui/consts/issue-67641.rs | 24 +++++++++++++++++++ src/test/ui/consts/issue-67862.rs | 18 ++++++++++++++ 6 files changed, 82 insertions(+), 22 deletions(-) create mode 100644 src/test/ui/consts/issue-67529.rs create mode 100644 src/test/ui/consts/issue-67640.rs create mode 100644 src/test/ui/consts/issue-67641.rs create mode 100644 src/test/ui/consts/issue-67862.rs diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 1d5a643484a73..75efe84c32eee 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -595,28 +595,11 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { self.check_binary_op(*op, left, right, source_info, place_layout, overflow_check)?; } - // Work around: avoid ICE in miri. FIXME(wesleywiser) - // The Miri engine ICEs when taking a reference to an uninitialized unsized - // local. There's nothing it can do here: taking a reference needs an allocation - // which needs to know the size. Normally that's okay as during execution - // (e.g. for CTFE) it can never happen. But here in const_prop - // unknown data is uninitialized, so if e.g. a function argument is unsized - // and has a reference taken, we get an ICE. + // Do not try creating references (#67862) Rvalue::Ref(_, _, place_ref) => { - trace!("checking Ref({:?})", place_ref); + trace!("skipping Ref({:?})", place_ref); - if let Some(local) = place_ref.as_local() { - let alive = if let LocalValue::Live(_) = self.ecx.frame().locals[local].value { - true - } else { - false - }; - - if !alive { - trace!("skipping Ref({:?}) to uninitialized local", place); - return None; - } - } + return None; } _ => {} diff --git a/src/test/mir-opt/const_prop/ref_deref_project.rs b/src/test/mir-opt/const_prop/ref_deref_project.rs index 5808a8be176d4..ca539fb7462a5 100644 --- a/src/test/mir-opt/const_prop/ref_deref_project.rs +++ b/src/test/mir-opt/const_prop/ref_deref_project.rs @@ -1,5 +1,5 @@ fn main() { - *(&(4, 5).1); + *(&(4, 5).1); // This does not currently propagate (#67862) } // END RUST SOURCE @@ -35,7 +35,7 @@ fn main() { // ... // _4 = const main::promoted[0]; // _2 = &((*_4).1: i32); -// _1 = const 5i32; +// _1 = (*_2); // ... // } // END rustc.main.ConstProp.after.mir diff --git a/src/test/ui/consts/issue-67529.rs b/src/test/ui/consts/issue-67529.rs new file mode 100644 index 0000000000000..df4bc668bee17 --- /dev/null +++ b/src/test/ui/consts/issue-67529.rs @@ -0,0 +1,11 @@ +// compile-flags: -Z mir-opt-level=2 +// run-pass + +struct Baz { + a: T +} + +fn main() { + let d : Baz<[i32; 4]> = Baz { a: [1,2,3,4] }; + assert_eq!([1, 2, 3, 4], d.a); +} diff --git a/src/test/ui/consts/issue-67640.rs b/src/test/ui/consts/issue-67640.rs new file mode 100644 index 0000000000000..bc0ee8d386f0a --- /dev/null +++ b/src/test/ui/consts/issue-67640.rs @@ -0,0 +1,24 @@ +// compile-flags: -Z mir-opt-level=3 +// run-pass + +struct X { + x: isize +} + +fn f1(a: &mut X, b: &mut isize, c: isize) -> isize { + let r = a.x + *b + c; + a.x = 0; + *b = 10; + return r; +} + +fn f2(a: isize, f: F) -> isize where F: FnOnce(isize) { f(1); return a; } + +pub fn main() { + let mut a = X {x: 1}; + let mut b = 2; + let c = 3; + assert_eq!(f1(&mut a, &mut b, c), 6); + assert_eq!(a.x, 0); + assert_eq!(f2(a.x, |_| a.x = 50), 0); +} diff --git a/src/test/ui/consts/issue-67641.rs b/src/test/ui/consts/issue-67641.rs new file mode 100644 index 0000000000000..f50fba287a231 --- /dev/null +++ b/src/test/ui/consts/issue-67641.rs @@ -0,0 +1,24 @@ +// compile-flags: -Z mir-opt-level=2 +// run-pass + +use std::cell::Cell; + +#[derive(Debug)] +struct B<'a> { + a: [Cell>>; 2] +} + +impl<'a> B<'a> { + fn new() -> B<'a> { + B { a: [Cell::new(None), Cell::new(None)] } + } +} + +fn f() { + let b2 = B::new(); + b2.a[0].set(Some(&b2)); +} + +fn main() { + f(); +} diff --git a/src/test/ui/consts/issue-67862.rs b/src/test/ui/consts/issue-67862.rs new file mode 100644 index 0000000000000..84f72154d262f --- /dev/null +++ b/src/test/ui/consts/issue-67862.rs @@ -0,0 +1,18 @@ +// compile-flags: -Z mir-opt-level=2 +// run-pass + +fn e220() -> (i64, i64) { + #[inline(never)] + fn get_displacement() -> [i64; 2] { + [139776, 963904] + } + + let res = get_displacement(); + match (&res[0], &res[1]) { + (arg0, arg1) => (*arg0, *arg1), + } +} + +fn main() { + assert_eq!(e220(), (139776, 963904)); +} From 5896998e7659bf22ffb804956a3680c028ede45f Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 5 Jan 2020 22:32:53 -0500 Subject: [PATCH 035/169] Don't run const propagation on items with inconsistent bounds Using `#![feature(trivial_bounds)]`, it's possible to write functions with unsatisfiable 'where' clauses, making them uncallable. However, the user can act as if these 'where' clauses are true inside the body of the function, leading to code that would normally be impossible to write. Since const propgation can run even without any user-written calls to a function, we need to explcitly check for these uncallable functions. --- src/librustc_mir/transform/const_prop.rs | 25 +++++++++++++++++++ ...ounds-inconsistent-associated-functions.rs | 4 +++ ...s-inconsistent-associated-functions.stderr | 2 ++ 3 files changed, 31 insertions(+) create mode 100644 src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.stderr diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 1d5a643484a73..48ab24a14c7c6 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -74,6 +74,31 @@ impl<'tcx> MirPass<'tcx> for ConstProp { return; } + // Check if it's even possible to satisy the 'where' clauses + // for this item. + // This branch will never be taken for any normal function. + // However, it's possible to `#!feature(trivial_bounds)]` to write + // a function with impossible to satisfy clauses, e.g.: + // `fn foo() where String: Copy {}` + // + // We don't usually need to worry about this kind of case, + // since we would get a compilation error if the user tried + // to call it. However, since we can do const propagation + // even without any calls to the function, we need to make + // sure that it even makes sense to try to evaluate the body. + // If there are unsatisfiable where clauses, then all bets are + // off, and we just give up. + if !tcx.substitute_normalize_and_test_predicates(( + source.def_id(), + InternalSubsts::identity_for_item(tcx, source.def_id()), + )) { + trace!( + "ConstProp skipped for item with unsatisfiable predicates: {:?}", + source.def_id() + ); + return; + } + trace!("ConstProp starting for {:?}", source.def_id()); let dummy_body = &Body::new( diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs index 6450ddd1b67fc..818be10554720 100644 --- a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs +++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs @@ -1,4 +1,8 @@ // run-pass +// Force mir to be emitted, to ensure that const +// propagation doesn't ICE on a function +// with an 'impossible' body. See issue #67696 +// compile-flags: --emit=mir,link // Inconsistent bounds with trait implementations #![feature(trivial_bounds)] diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.stderr b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.stderr new file mode 100644 index 0000000000000..0ee1e2e0ba56a --- /dev/null +++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.stderr @@ -0,0 +1,2 @@ +warning: due to multiple output types requested, the explicitly specified output file name will be adapted for each output type + From e1fc22c4eba6e07a5549c74b197fbaa53f7b29e1 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 7 Jan 2020 10:01:52 -0500 Subject: [PATCH 036/169] Add additional regression test --- .../ui/consts/issue-67696-const-prop-ice.rs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/test/ui/consts/issue-67696-const-prop-ice.rs diff --git a/src/test/ui/consts/issue-67696-const-prop-ice.rs b/src/test/ui/consts/issue-67696-const-prop-ice.rs new file mode 100644 index 0000000000000..ad52608b3f46d --- /dev/null +++ b/src/test/ui/consts/issue-67696-const-prop-ice.rs @@ -0,0 +1,20 @@ +// check-pass +// compile-flags: --emit=mir,link +// Checks that we don't ICE due to attempting to run const prop +// on a function with unsatisifable 'where' clauses + +#![allow(unused)] + +trait A { + fn foo(&self) -> Self where Self: Copy; +} + +impl A for [fn(&())] { + fn foo(&self) -> Self where Self: Copy { *(&[] as &[_]) } +} + +impl A for i32 { + fn foo(&self) -> Self { 3 } +} + +fn main() {} From 92d86cc9b8bbd744c5eebf3718a9dc87576b786c Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 7 Jan 2020 10:53:04 -0500 Subject: [PATCH 037/169] Fix typo --- src/librustc_mir/transform/const_prop.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 48ab24a14c7c6..35dbf2f7eaa42 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -74,7 +74,7 @@ impl<'tcx> MirPass<'tcx> for ConstProp { return; } - // Check if it's even possible to satisy the 'where' clauses + // Check if it's even possible to satisfy the 'where' clauses // for this item. // This branch will never be taken for any normal function. // However, it's possible to `#!feature(trivial_bounds)]` to write From 7df8ca29545301c1d3020bf8fc9aa8f9fd8759ea Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sat, 11 Jan 2020 13:20:09 -0500 Subject: [PATCH 038/169] Convert test to check-pass --- .../trivial-bounds-inconsistent-associated-functions.rs | 4 ++-- .../trivial-bounds-inconsistent-associated-functions.stderr | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) delete mode 100644 src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.stderr diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs index 818be10554720..e0d4d538b40e7 100644 --- a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs +++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs @@ -1,8 +1,8 @@ -// run-pass +// check-pass +// compile-flags: --emit=mir // Force mir to be emitted, to ensure that const // propagation doesn't ICE on a function // with an 'impossible' body. See issue #67696 -// compile-flags: --emit=mir,link // Inconsistent bounds with trait implementations #![feature(trivial_bounds)] diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.stderr b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.stderr deleted file mode 100644 index 0ee1e2e0ba56a..0000000000000 --- a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.stderr +++ /dev/null @@ -1,2 +0,0 @@ -warning: due to multiple output types requested, the explicitly specified output file name will be adapted for each output type - From 6a0bb1867b2026e05982f865bb48857d7e492cd7 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sat, 11 Jan 2020 14:17:42 -0500 Subject: [PATCH 039/169] Add "--emit=link" This avoids a strange linker error that we get with only "--emit=mir" and "check-pass" --- .../trivial-bounds-inconsistent-associated-functions.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs index e0d4d538b40e7..69eee66e64d89 100644 --- a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs +++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-associated-functions.rs @@ -1,5 +1,5 @@ // check-pass -// compile-flags: --emit=mir +// compile-flags: --emit=mir,link // Force mir to be emitted, to ensure that const // propagation doesn't ICE on a function // with an 'impossible' body. See issue #67696 From e390b91e5717a338db20360a1ddffa23ba66701d Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 13 Jan 2020 06:06:42 -0500 Subject: [PATCH 040/169] Use TraitQueryMode::Canonical when testing predicates in const prop --- src/librustc/mir/mono.rs | 5 ++++- src/librustc/query/mod.rs | 6 +++--- src/librustc/traits/fulfill.rs | 24 ++++++++++++++++++++++-- src/librustc/traits/mod.rs | 18 +++++++++++------- src/librustc/ty/query/keys.rs | 9 +++++++++ src/librustc_mir/transform/const_prop.rs | 16 ++++++++++++++++ 6 files changed, 65 insertions(+), 13 deletions(-) diff --git a/src/librustc/mir/mono.rs b/src/librustc/mir/mono.rs index 51ce575e51f3b..e7a4c5b592105 100644 --- a/src/librustc/mir/mono.rs +++ b/src/librustc/mir/mono.rs @@ -1,6 +1,7 @@ use crate::dep_graph::{DepConstructor, DepNode, WorkProduct, WorkProductId}; use crate::ich::{Fingerprint, NodeIdHashingMode, StableHashingContext}; use crate::session::config::OptLevel; +use crate::traits::TraitQueryMode; use crate::ty::print::obsolete::DefPathBasedNames; use crate::ty::{subst::InternalSubsts, Instance, InstanceDef, SymbolName, TyCtxt}; use rustc_data_structures::base_n; @@ -167,7 +168,9 @@ impl<'tcx> MonoItem<'tcx> { MonoItem::GlobalAsm(..) => return true, }; - tcx.substitute_normalize_and_test_predicates((def_id, &substs)) + // We shouldn't encounter any overflow here, so we use TraitQueryMode::Standard\ + // to report an error if overflow somehow occurs. + tcx.substitute_normalize_and_test_predicates((def_id, &substs, TraitQueryMode::Standard)) } pub fn to_string(&self, tcx: TyCtxt<'tcx>, debug: bool) -> String { diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index 50ef115da2c42..669ba4abfadd8 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -1141,11 +1141,11 @@ rustc_queries! { desc { "normalizing `{:?}`", goal } } - query substitute_normalize_and_test_predicates(key: (DefId, SubstsRef<'tcx>)) -> bool { + query substitute_normalize_and_test_predicates(key: (DefId, SubstsRef<'tcx>, traits::TraitQueryMode)) -> bool { no_force desc { |tcx| - "testing substituted normalized predicates:`{}`", - tcx.def_path_str(key.0) + "testing substituted normalized predicates in mode {:?}:`{}`", + key.2, tcx.def_path_str(key.0) } } diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index 46ece6fc40593..9e5abc80822c7 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -16,6 +16,7 @@ use super::CodeSelectionError; use super::{ConstEvalFailure, Unimplemented}; use super::{FulfillmentError, FulfillmentErrorCode}; use super::{ObligationCause, PredicateObligation}; +use crate::traits::TraitQueryMode; impl<'tcx> ForestObligation for PendingPredicateObligation<'tcx> { type Predicate = ty::Predicate<'tcx>; @@ -62,6 +63,9 @@ pub struct FulfillmentContext<'tcx> { // a snapshot (they don't *straddle* a snapshot, so there // is no trouble there). usable_in_snapshot: bool, + + // The `TraitQueryMode` used when constructing a `SelectionContext` + query_mode: TraitQueryMode, } #[derive(Clone, Debug)] @@ -75,12 +79,26 @@ pub struct PendingPredicateObligation<'tcx> { static_assert_size!(PendingPredicateObligation<'_>, 136); impl<'a, 'tcx> FulfillmentContext<'tcx> { - /// Creates a new fulfillment context. + /// Creates a new fulfillment context with `TraitQueryMode::Standard` + /// You almost always want to use this instead of `with_query_mode` pub fn new() -> FulfillmentContext<'tcx> { FulfillmentContext { predicates: ObligationForest::new(), register_region_obligations: true, usable_in_snapshot: false, + query_mode: TraitQueryMode::Standard, + } + } + + /// Creates a new fulfillment context with the specified query mode. + /// This should only be used when you want to ignore overflow, + /// rather than reporting it as an error. + pub fn with_query_mode(query_mode: TraitQueryMode) -> FulfillmentContext<'tcx> { + FulfillmentContext { + predicates: ObligationForest::new(), + register_region_obligations: true, + usable_in_snapshot: false, + query_mode, } } @@ -89,6 +107,7 @@ impl<'a, 'tcx> FulfillmentContext<'tcx> { predicates: ObligationForest::new(), register_region_obligations: true, usable_in_snapshot: true, + query_mode: TraitQueryMode::Standard, } } @@ -97,6 +116,7 @@ impl<'a, 'tcx> FulfillmentContext<'tcx> { predicates: ObligationForest::new(), register_region_obligations: false, usable_in_snapshot: false, + query_mode: TraitQueryMode::Standard, } } @@ -217,7 +237,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> { &mut self, infcx: &InferCtxt<'_, 'tcx>, ) -> Result<(), Vec>> { - let mut selcx = SelectionContext::new(infcx); + let mut selcx = SelectionContext::with_query_mode(infcx, self.query_mode); self.select(&mut selcx) } diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 2d3160dc3e51a..31de5409fc8be 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -95,7 +95,7 @@ pub enum IntercrateMode { } /// The mode that trait queries run in. -#[derive(Copy, Clone, PartialEq, Eq, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, HashStable)] pub enum TraitQueryMode { // Standard/un-canonicalized queries get accurate // spans etc. passed in and hence can do reasonable @@ -1017,13 +1017,14 @@ where fn normalize_and_test_predicates<'tcx>( tcx: TyCtxt<'tcx>, predicates: Vec>, + mode: TraitQueryMode, ) -> bool { - debug!("normalize_and_test_predicates(predicates={:?})", predicates); + debug!("normalize_and_test_predicates(predicates={:?}, mode={:?})", predicates, mode); let result = tcx.infer_ctxt().enter(|infcx| { let param_env = ty::ParamEnv::reveal_all(); - let mut selcx = SelectionContext::new(&infcx); - let mut fulfill_cx = FulfillmentContext::new(); + let mut selcx = SelectionContext::with_query_mode(&infcx, mode); + let mut fulfill_cx = FulfillmentContext::with_query_mode(mode); let cause = ObligationCause::dummy(); let Normalized { value: predicates, obligations } = normalize(&mut selcx, param_env, cause.clone(), &predicates); @@ -1043,12 +1044,12 @@ fn normalize_and_test_predicates<'tcx>( fn substitute_normalize_and_test_predicates<'tcx>( tcx: TyCtxt<'tcx>, - key: (DefId, SubstsRef<'tcx>), + key: (DefId, SubstsRef<'tcx>, TraitQueryMode), ) -> bool { debug!("substitute_normalize_and_test_predicates(key={:?})", key); let predicates = tcx.predicates_of(key.0).instantiate(tcx, key.1).predicates; - let result = normalize_and_test_predicates(tcx, predicates); + let result = normalize_and_test_predicates(tcx, predicates, key.2); debug!("substitute_normalize_and_test_predicates(key={:?}) = {:?}", key, result); result @@ -1101,7 +1102,10 @@ fn vtable_methods<'tcx>( // Note that this method could then never be called, so we // do not want to try and codegen it, in that case (see #23435). let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs); - if !normalize_and_test_predicates(tcx, predicates.predicates) { + // We don't expect overflow here, so report an error if it somehow ends + // up happening. + if !normalize_and_test_predicates(tcx, predicates.predicates, TraitQueryMode::Standard) + { debug!("vtable_methods: predicates do not hold"); return None; } diff --git a/src/librustc/ty/query/keys.rs b/src/librustc/ty/query/keys.rs index d64f27d9cc26c..20f8e7f564abd 100644 --- a/src/librustc/ty/query/keys.rs +++ b/src/librustc/ty/query/keys.rs @@ -115,6 +115,15 @@ impl<'tcx> Key for (DefId, SubstsRef<'tcx>) { } } +impl<'tcx> Key for (DefId, SubstsRef<'tcx>, traits::TraitQueryMode) { + fn query_crate(&self) -> CrateNum { + self.0.krate + } + fn default_span(&self, tcx: TyCtxt<'_>) -> Span { + self.0.default_span(tcx) + } +} + impl<'tcx> Key for (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) { fn query_crate(&self) -> CrateNum { self.1.def_id().krate diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 35dbf2f7eaa42..90c97480c7562 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -14,6 +14,7 @@ use rustc::mir::{ SourceInfo, SourceScope, SourceScopeData, Statement, StatementKind, Terminator, TerminatorKind, UnOp, RETURN_PLACE, }; +use rustc::traits::TraitQueryMode; use rustc::ty::layout::{ HasDataLayout, HasTyCtxt, LayoutError, LayoutOf, Size, TargetDataLayout, TyLayout, }; @@ -88,9 +89,24 @@ impl<'tcx> MirPass<'tcx> for ConstProp { // sure that it even makes sense to try to evaluate the body. // If there are unsatisfiable where clauses, then all bets are // off, and we just give up. + // + // Note that we use TraitQueryMode::Canonical here, which causes + // us to treat overflow like any other error. This is because we + // are "speculatively" evaluating this item with the default substs. + // While this usually succeeds, it may fail with tricky impls + // (e.g. the typenum crate). Const-propagation is fundamentally + // "best-effort", and does not affect correctness in any way. + // Therefore, it's perfectly fine to just "give up" if we're + // unable to check the bounds with the default substs. + // + // False negatives (failing to run const-prop on something when we actually + // could) are fine. However, false positives (running const-prop on + // an item with unsatisfiable bounds) can lead to us generating invalid + // MIR. if !tcx.substitute_normalize_and_test_predicates(( source.def_id(), InternalSubsts::identity_for_item(tcx, source.def_id()), + TraitQueryMode::Canonical, )) { trace!( "ConstProp skipped for item with unsatisfiable predicates: {:?}", From 9908a8736736fe3b7c416eb4560de87c15d10f47 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 13 Jan 2020 13:40:30 +0100 Subject: [PATCH 041/169] Move to new crate rustc_ty. --- Cargo.lock | 12 +++++++++++ src/librustc_interface/Cargo.toml | 1 + src/librustc_passes/lib.rs | 2 -- src/librustc_ty/Cargo.toml | 16 ++++++++++++++ src/librustc_ty/lib.rs | 25 ++++++++++++++++++++++ src/{librustc_passes => librustc_ty}/ty.rs | 0 6 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 src/librustc_ty/Cargo.toml create mode 100644 src/librustc_ty/lib.rs rename src/{librustc_passes => librustc_ty}/ty.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index 54ad60e71506b..14e41ca209625 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3642,6 +3642,7 @@ dependencies = [ "rustc_span", "rustc_target", "rustc_traits", + "rustc_ty", "rustc_typeck", "serialize", "smallvec 1.0.0", @@ -3918,6 +3919,17 @@ dependencies = [ "syntax", ] +[[package]] +name = "rustc_ty" +version = "0.0.0" +dependencies = [ + "log", + "rustc", + "rustc_data_structures", + "rustc_hir", + "rustc_span", +] + [[package]] name = "rustc_typeck" version = "0.0.0" diff --git a/src/librustc_interface/Cargo.toml b/src/librustc_interface/Cargo.toml index eb0551c606548..c7d387caa2d1d 100644 --- a/src/librustc_interface/Cargo.toml +++ b/src/librustc_interface/Cargo.toml @@ -39,6 +39,7 @@ rustc_errors = { path = "../librustc_errors" } rustc_plugin_impl = { path = "../librustc_plugin_impl" } rustc_privacy = { path = "../librustc_privacy" } rustc_resolve = { path = "../librustc_resolve" } +rustc_ty = { path = "../librustc_ty" } tempfile = "3.0.5" once_cell = "1" diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs index 8bd06465628fa..c45f83f213078 100644 --- a/src/librustc_passes/lib.rs +++ b/src/librustc_passes/lib.rs @@ -31,7 +31,6 @@ pub mod loops; mod reachable; mod region; pub mod stability; -mod ty; pub fn provide(providers: &mut Providers<'_>) { check_const::provide(providers); @@ -44,5 +43,4 @@ pub fn provide(providers: &mut Providers<'_>) { reachable::provide(providers); region::provide(providers); stability::provide(providers); - ty::provide(providers); } diff --git a/src/librustc_ty/Cargo.toml b/src/librustc_ty/Cargo.toml new file mode 100644 index 0000000000000..fb0d93fe5ebb6 --- /dev/null +++ b/src/librustc_ty/Cargo.toml @@ -0,0 +1,16 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_ty" +version = "0.0.0" +edition = "2018" + +[lib] +name = "rustc_ty" +path = "lib.rs" + +[dependencies] +log = "0.4" +rustc = { path = "../librustc" } +rustc_data_structures = { path = "../librustc_data_structures" } +rustc_hir = { path = "../librustc_hir" } +rustc_span = { path = "../librustc_span" } diff --git a/src/librustc_ty/lib.rs b/src/librustc_ty/lib.rs new file mode 100644 index 0000000000000..2548d2cff9766 --- /dev/null +++ b/src/librustc_ty/lib.rs @@ -0,0 +1,25 @@ +//! Various checks +//! +//! # Note +//! +//! This API is completely unstable and subject to change. + +#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] +#![feature(bool_to_option)] +#![feature(in_band_lifetimes)] +#![feature(nll)] +#![feature(slice_patterns)] +#![recursion_limit = "256"] + +#[macro_use] +extern crate rustc; +#[macro_use] +extern crate log; + +use rustc::ty::query::Providers; + +mod ty; + +pub fn provide(providers: &mut Providers<'_>) { + ty::provide(providers); +} diff --git a/src/librustc_passes/ty.rs b/src/librustc_ty/ty.rs similarity index 100% rename from src/librustc_passes/ty.rs rename to src/librustc_ty/ty.rs From 894dc2d3d2b96e1f992324aa95125e0d161ab681 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 13 Jan 2020 15:36:05 +0100 Subject: [PATCH 042/169] Do not forget to provide queries. --- src/librustc_interface/passes.rs | 1 + src/librustc_passes/lib.rs | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 9119466cbc048..787d9a8ed77d7 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -677,6 +677,7 @@ pub fn default_provide(providers: &mut ty::query::Providers<'_>) { rustc_passes::provide(providers); rustc_resolve::provide(providers); rustc_traits::provide(providers); + rustc_ty::provide(providers); rustc_metadata::provide(providers); rustc_lint::provide(providers); rustc_codegen_utils::provide(providers); diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs index c45f83f213078..65eb07b989d83 100644 --- a/src/librustc_passes/lib.rs +++ b/src/librustc_passes/lib.rs @@ -5,7 +5,6 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] -#![feature(bool_to_option)] #![feature(in_band_lifetimes)] #![feature(nll)] #![feature(slice_patterns)] From 6421127340047130e546af9dc3afb45643cf692f Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 7 Jan 2020 00:51:00 +0900 Subject: [PATCH 043/169] Update rustc-guide --- src/doc/rustc-guide | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-guide b/src/doc/rustc-guide index b5c6babcdd4ce..92baf7293dd2d 160000 --- a/src/doc/rustc-guide +++ b/src/doc/rustc-guide @@ -1 +1 @@ -Subproject commit b5c6babcdd4ce1fa90458b7827a5fde082e79e87 +Subproject commit 92baf7293dd2d418d2ac4b141b0faa822075d9f7 From 06b9a73cfa5ef1cb6fb9160d61f1beada2b81b79 Mon Sep 17 00:00:00 2001 From: Charles Lew Date: Tue, 14 Jan 2020 20:02:27 +0800 Subject: [PATCH 044/169] Update APIs according to RFC change suggestions. --- src/liballoc/collections/linked_list.rs | 43 +++++++++---- src/liballoc/collections/linked_list/tests.rs | 60 ++++++++++++++++--- 2 files changed, 85 insertions(+), 18 deletions(-) diff --git a/src/liballoc/collections/linked_list.rs b/src/liballoc/collections/linked_list.rs index d7504b0b80bd9..b88ca8a0fb0d1 100644 --- a/src/liballoc/collections/linked_list.rs +++ b/src/liballoc/collections/linked_list.rs @@ -509,20 +509,42 @@ impl LinkedList { IterMut { head: self.head, tail: self.tail, len: self.len, list: self } } - /// Provides a cursor. + /// Provides a cursor at the front element. + /// + /// The cursor is pointing to the "ghost" non-element if the list is empty. #[inline] #[unstable(feature = "linked_list_cursors", issue = "58533")] - pub fn cursor(&self) -> Cursor<'_, T> { + pub fn cursor_front(&self) -> Cursor<'_, T> { Cursor { index: 0, current: self.head, list: self } } - /// Provides a cursor with editing operations. + /// Provides a cursor with editing operations at the front element. + /// + /// The cursor is pointing to the "ghost" non-element if the list is empty. #[inline] #[unstable(feature = "linked_list_cursors", issue = "58533")] - pub fn cursor_mut(&mut self) -> CursorMut<'_, T> { + pub fn cursor_front_mut(&mut self) -> CursorMut<'_, T> { CursorMut { index: 0, current: self.head, list: self } } + /// Provides a cursor at the back element. + /// + /// The cursor is pointing to the "ghost" non-element if the list is empty. + #[inline] + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn cursor_back(&self) -> Cursor<'_, T> { + Cursor { index: self.len.checked_sub(1).unwrap_or(0), current: self.tail, list: self } + } + + /// Provides a cursor with editing operations at the back element. + /// + /// The cursor is pointing to the "ghost" non-element if the list is empty. + #[inline] + #[unstable(feature = "linked_list_cursors", issue = "58533")] + pub fn cursor_back_mut(&mut self) -> CursorMut<'_, T> { + CursorMut { index: self.len.checked_sub(1).unwrap_or(0), current: self.tail, list: self } + } + /// Returns `true` if the `LinkedList` is empty. /// /// This operation should compute in O(1) time. @@ -1146,8 +1168,6 @@ impl fmt::Debug for Cursor<'_, T> { /// Cursors always rest between two elements in the list, and index in a logically circular way. /// To accommodate this, there is a "ghost" non-element that yields `None` between the head and /// tail of the list. -/// -/// When created, cursors start at the front of the list, or the "ghost" non-element if the list is empty. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub struct CursorMut<'a, T: 'a> { index: usize, @@ -1474,9 +1494,12 @@ impl<'a, T> CursorMut<'a, T> { /// If the cursor is pointing at the "ghost" non-element then the entire contents /// of the `LinkedList` are moved. #[unstable(feature = "linked_list_cursors", issue = "58533")] - pub fn split_after(self) -> LinkedList { + pub fn split_after(&mut self) -> LinkedList { let split_off_idx = if self.index == self.list.len { 0 } else { self.index + 1 }; - // no need to update `self.index` because the cursor is consumed. + if self.index == self.list.len { + // The "ghost" non-element's index has changed to 0. + self.index = 0; + } unsafe { self.list.split_off_after_node(self.current, split_off_idx) } } @@ -1487,9 +1510,9 @@ impl<'a, T> CursorMut<'a, T> { /// If the cursor is pointing at the "ghost" non-element then the entire contents /// of the `LinkedList` are moved. #[unstable(feature = "linked_list_cursors", issue = "58533")] - pub fn split_before(self) -> LinkedList { + pub fn split_before(&mut self) -> LinkedList { let split_off_idx = self.index; - // no need to update `self.index` because the cursor is consumed. + self.index = 0; unsafe { self.list.split_off_before_node(self.current, split_off_idx) } } } diff --git a/src/liballoc/collections/linked_list/tests.rs b/src/liballoc/collections/linked_list/tests.rs index d223752c7f7ec..085f734ed916a 100644 --- a/src/liballoc/collections/linked_list/tests.rs +++ b/src/liballoc/collections/linked_list/tests.rs @@ -309,7 +309,7 @@ fn drain_to_empty_test() { fn test_cursor_move_peek() { let mut m: LinkedList = LinkedList::new(); m.extend(&[1, 2, 3, 4, 5, 6]); - let mut cursor = m.cursor(); + let mut cursor = m.cursor_front(); assert_eq!(cursor.current(), Some(&1)); assert_eq!(cursor.peek_next(), Some(&2)); assert_eq!(cursor.peek_prev(), None); @@ -326,9 +326,26 @@ fn test_cursor_move_peek() { assert_eq!(cursor.peek_prev(), Some(&1)); assert_eq!(cursor.index(), Some(1)); + let mut cursor = m.cursor_back(); + assert_eq!(cursor.current(), Some(&6)); + assert_eq!(cursor.peek_next(), None); + assert_eq!(cursor.peek_prev(), Some(&5)); + assert_eq!(cursor.index(), Some(5)); + cursor.move_next(); + assert_eq!(cursor.current(), None); + assert_eq!(cursor.peek_next(), Some(&1)); + assert_eq!(cursor.peek_prev(), Some(&6)); + assert_eq!(cursor.index(), None); + cursor.move_prev(); + cursor.move_prev(); + assert_eq!(cursor.current(), Some(&5)); + assert_eq!(cursor.peek_next(), Some(&6)); + assert_eq!(cursor.peek_prev(), Some(&4)); + assert_eq!(cursor.index(), Some(4)); + let mut m: LinkedList = LinkedList::new(); m.extend(&[1, 2, 3, 4, 5, 6]); - let mut cursor = m.cursor_mut(); + let mut cursor = m.cursor_front_mut(); assert_eq!(cursor.current(), Some(&mut 1)); assert_eq!(cursor.peek_next(), Some(&mut 2)); assert_eq!(cursor.peek_prev(), None); @@ -352,24 +369,51 @@ fn test_cursor_move_peek() { assert_eq!(cursor2.index(), Some(2)); assert_eq!(cursor.current(), Some(&mut 2)); assert_eq!(cursor.index(), Some(1)); + + let mut m: LinkedList = LinkedList::new(); + m.extend(&[1, 2, 3, 4, 5, 6]); + let mut cursor = m.cursor_back_mut(); + assert_eq!(cursor.current(), Some(&mut 6)); + assert_eq!(cursor.peek_next(), None); + assert_eq!(cursor.peek_prev(), Some(&mut 5)); + assert_eq!(cursor.index(), Some(5)); + cursor.move_next(); + assert_eq!(cursor.current(), None); + assert_eq!(cursor.peek_next(), Some(&mut 1)); + assert_eq!(cursor.peek_prev(), Some(&mut 6)); + assert_eq!(cursor.index(), None); + cursor.move_prev(); + cursor.move_prev(); + assert_eq!(cursor.current(), Some(&mut 5)); + assert_eq!(cursor.peek_next(), Some(&mut 6)); + assert_eq!(cursor.peek_prev(), Some(&mut 4)); + assert_eq!(cursor.index(), Some(4)); + let mut cursor2 = cursor.as_cursor(); + assert_eq!(cursor2.current(), Some(&5)); + assert_eq!(cursor2.index(), Some(4)); + cursor2.move_prev(); + assert_eq!(cursor2.current(), Some(&4)); + assert_eq!(cursor2.index(), Some(3)); + assert_eq!(cursor.current(), Some(&mut 5)); + assert_eq!(cursor.index(), Some(4)); } #[test] fn test_cursor_mut_insert() { let mut m: LinkedList = LinkedList::new(); m.extend(&[1, 2, 3, 4, 5, 6]); - let mut cursor = m.cursor_mut(); + let mut cursor = m.cursor_front_mut(); cursor.insert_before(7); cursor.insert_after(8); check_links(&m); assert_eq!(m.iter().cloned().collect::>(), &[7, 1, 8, 2, 3, 4, 5, 6]); - let mut cursor = m.cursor_mut(); + let mut cursor = m.cursor_front_mut(); cursor.move_prev(); cursor.insert_before(9); cursor.insert_after(10); check_links(&m); assert_eq!(m.iter().cloned().collect::>(), &[10, 7, 1, 8, 2, 3, 4, 5, 6, 9]); - let mut cursor = m.cursor_mut(); + let mut cursor = m.cursor_front_mut(); cursor.move_prev(); assert_eq!(cursor.remove_current(), None); cursor.move_next(); @@ -383,7 +427,7 @@ fn test_cursor_mut_insert() { assert_eq!(cursor.remove_current(), Some(10)); check_links(&m); assert_eq!(m.iter().cloned().collect::>(), &[1, 8, 2, 3, 4, 5, 6]); - let mut cursor = m.cursor_mut(); + let mut cursor = m.cursor_front_mut(); let mut p: LinkedList = LinkedList::new(); p.extend(&[100, 101, 102, 103]); let mut q: LinkedList = LinkedList::new(); @@ -395,12 +439,12 @@ fn test_cursor_mut_insert() { m.iter().cloned().collect::>(), &[200, 201, 202, 203, 1, 100, 101, 102, 103, 8, 2, 3, 4, 5, 6] ); - let mut cursor = m.cursor_mut(); + let mut cursor = m.cursor_front_mut(); cursor.move_prev(); let tmp = cursor.split_before(); assert_eq!(m.into_iter().collect::>(), &[]); m = tmp; - let mut cursor = m.cursor_mut(); + let mut cursor = m.cursor_front_mut(); cursor.move_next(); cursor.move_next(); cursor.move_next(); From 5076a3efc707436c20c62f90e5df47e78052ed2d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 14 Jan 2020 14:04:03 +0100 Subject: [PATCH 045/169] Add failing example for E0170 explanation --- src/librustc_error_codes/error_codes/E0170.md | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/librustc_error_codes/error_codes/E0170.md b/src/librustc_error_codes/error_codes/E0170.md index 4b870dbf22155..56e1b5aa241d2 100644 --- a/src/librustc_error_codes/error_codes/E0170.md +++ b/src/librustc_error_codes/error_codes/E0170.md @@ -1,3 +1,24 @@ +A pattern binding is using the same name as one of the variants a type. + +Erroneous code example: + +```compile_fail,E0170 +# #![deny(warnings)] +enum Method { + GET, + POST, +} + +fn is_empty(s: Method) -> bool { + match s { + GET => true, + _ => false + } +} + +fn main() {} +``` + Enum variants are qualified by default. For example, given this type: ``` From 148c1bca0f0eb8da23a50cd876cb86cb060a8375 Mon Sep 17 00:00:00 2001 From: csmoe Date: Tue, 14 Jan 2020 21:21:14 +0800 Subject: [PATCH 046/169] record generoator interior exprs in typecktable --- src/librustc/traits/error_reporting.rs | 33 +++++++++++++++++++++----- src/librustc/ty/adjustment.rs | 9 +++++++ src/librustc/ty/context.rs | 5 ++++ 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 0c9a73d78a5eb..66737372bda37 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -2456,7 +2456,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let target_span = tables .generator_interior_types .iter() - .find(|ty::GeneratorInteriorTypeCause { ty, .. }| { + .zip(tables.generator_interior_exprs.iter()) + .find(|(ty::GeneratorInteriorTypeCause { ty, .. }, _)| { // Careful: the regions for types that appear in the // generator interior are not generally known, so we // want to erase them when comparing (and anyway, @@ -2479,19 +2480,21 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ); eq }) - .map(|ty::GeneratorInteriorTypeCause { span, scope_span, .. }| { - (span, source_map.span_to_snippet(*span), scope_span) + .map(|(ty::GeneratorInteriorTypeCause { span, scope_span, .. }, expr)| { + (span, source_map.span_to_snippet(*span), scope_span, expr) }); + debug!( "maybe_note_obligation_cause_for_async_await: target_ty={:?} \ generator_interior_types={:?} target_span={:?}", target_ty, tables.generator_interior_types, target_span ); - if let Some((target_span, Ok(snippet), scope_span)) = target_span { + if let Some((target_span, Ok(snippet), scope_span, expr)) = target_span { self.note_obligation_cause_for_async_await( err, *target_span, scope_span, + *expr, snippet, generator_did, last_generator, @@ -2514,6 +2517,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { err: &mut DiagnosticBuilder<'_>, target_span: Span, scope_span: &Option, + expr: Option, snippet: String, first_generator: DefId, last_generator: Option, @@ -2549,6 +2553,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // not implemented. let is_send = self.tcx.is_diagnostic_item(sym::send_trait, trait_ref.def_id); let is_sync = self.tcx.is_diagnostic_item(sym::sync_trait, trait_ref.def_id); + let hir = self.tcx.hir(); let trait_explanation = if is_send || is_sync { let (trait_name, trait_verb) = if is_send { ("`Send`", "sent") } else { ("`Sync`", "shared") }; @@ -2564,8 +2569,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let message = if let Some(name) = last_generator .and_then(|generator_did| self.tcx.parent(generator_did)) - .and_then(|parent_did| self.tcx.hir().as_local_hir_id(parent_did)) - .and_then(|parent_hir_id| self.tcx.hir().opt_name(parent_hir_id)) + .and_then(|parent_did| hir.as_local_hir_id(parent_did)) + .and_then(|parent_hir_id| hir.opt_name(parent_hir_id)) { format!("future returned by `{}` is not {}", name, trait_name) } else { @@ -2588,6 +2593,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { format!("{} occurs here, with `{}` maybe used later", await_or_yield, snippet), ); + if let Some(expr_id) = expr { + let expr = hir.expect_expr(expr_id); + let is_ref = tables.expr_adjustments(expr).iter().any(|adj| adj.is_region_borrow()); + let parent = hir.get_parent_node(expr_id); + if let Some(hir::Node::Expr(e)) = hir.find(parent) { + let method_span = hir.span(parent); + if tables.is_method_call(e) && is_ref { + err.span_help( + method_span, + "consider moving this method call into a `let` \ + binding to create a shorter lived borrow" + ); + } + } + } + span.push_span_label(target_span, format!("has type `{}`", target_ty)); // If available, use the scope span to annotate the drop location. diff --git a/src/librustc/ty/adjustment.rs b/src/librustc/ty/adjustment.rs index ebefb03b813f2..6531289bd7050 100644 --- a/src/librustc/ty/adjustment.rs +++ b/src/librustc/ty/adjustment.rs @@ -81,6 +81,15 @@ pub struct Adjustment<'tcx> { pub target: Ty<'tcx>, } +impl Adjustment<'tcx> { + pub fn is_region_borrow(&self) -> bool { + match self.kind { + Adjust::Borrow(AutoBorrow::Ref(..)) => true, + _ => false + } + } +} + #[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)] pub enum Adjust<'tcx> { /// Go from ! to any type. diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 6b98fddb22ef9..4a5fced7a89e5 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -439,6 +439,8 @@ pub struct TypeckTables<'tcx> { /// Stores the type, span and optional scope span of all types /// that are live across the yield of this generator (if a generator). pub generator_interior_types: Vec>, + + pub generator_interior_exprs: Vec>, } impl<'tcx> TypeckTables<'tcx> { @@ -465,6 +467,7 @@ impl<'tcx> TypeckTables<'tcx> { concrete_opaque_types: Default::default(), upvar_list: Default::default(), generator_interior_types: Default::default(), + generator_interior_exprs: Default::default(), } } @@ -728,6 +731,7 @@ impl<'a, 'tcx> HashStable> for TypeckTables<'tcx> { ref concrete_opaque_types, ref upvar_list, ref generator_interior_types, + ref generator_interior_exprs, } = *self; hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { @@ -766,6 +770,7 @@ impl<'a, 'tcx> HashStable> for TypeckTables<'tcx> { concrete_opaque_types.hash_stable(hcx, hasher); upvar_list.hash_stable(hcx, hasher); generator_interior_types.hash_stable(hcx, hasher); + generator_interior_exprs.hash_stable(hcx, hasher); }) } } From b97560116785f2dbb488e66ab34aeee981ec2912 Mon Sep 17 00:00:00 2001 From: csmoe Date: Tue, 14 Jan 2020 21:22:19 +0800 Subject: [PATCH 047/169] suggest to limit lifetime of temporary borrow with let --- src/librustc/traits/error_reporting.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 66737372bda37..13eb47a041fa6 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -2578,7 +2578,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { }; span.push_span_label(original_span, message); - err.set_span(span); + err.set_span(span.clone()); format!("is not {}", trait_name) } else { From 6faad6dc7a0ad1524e3c490f4ea99c998ce9ae04 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 13 Jan 2020 17:58:37 +0100 Subject: [PATCH 048/169] Untangle ZST validation from integer validation and generalize it to all zsts --- src/librustc_mir/interpret/validity.rs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index 2f0fb81fffd13..6934ec0bdb6aa 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -587,12 +587,6 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> // padding. match tys.kind { ty::Int(..) | ty::Uint(..) | ty::Float(..) => true, - ty::Tuple(tys) if tys.len() == 0 => true, - ty::Adt(adt_def, _) - if adt_def.is_struct() && adt_def.all_fields().next().is_none() => - { - true - } _ => false, } } => @@ -609,11 +603,6 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> } // This is the element type size. let layout = self.ecx.layout_of(tys)?; - // Empty tuples and fieldless structs (the only ZSTs that allow reaching this code) - // have no data to be checked. - if layout.is_zst() { - return Ok(()); - } // This is the size in bytes of the whole array. let size = layout.size * len; // Size is not 0, get a pointer. @@ -656,6 +645,13 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> } } } + // Fast path for arrays and slices of ZSTs. We only need to check a single ZST element + // of an array and not all of them, because there's only a single value of a specific + // ZST type, so either validation fails for all elements or none. + ty::Array(tys, ..) | ty::Slice(tys) if self.ecx.layout_of(tys)?.is_zst() => { + // Validate just the first element + self.walk_aggregate(op, fields.take(1))? + } _ => { self.walk_aggregate(op, fields)? // default handler } From 5ad8b9e3948fa05df0b9c2a6c71146c3af10cbc8 Mon Sep 17 00:00:00 2001 From: csmoe Date: Tue, 14 Jan 2020 21:22:43 +0800 Subject: [PATCH 049/169] update async-await send/sync test --- src/librustc/traits/error_reporting.rs | 38 +++++++++---------- src/librustc/ty/adjustment.rs | 2 +- src/librustc/ty/context.rs | 9 +---- .../check/generator_interior.rs | 6 ++- .../issue-64130-4-async-move.stderr | 5 +++ 5 files changed, 32 insertions(+), 28 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 13eb47a041fa6..aaad0be9a048c 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -2456,7 +2456,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let target_span = tables .generator_interior_types .iter() - .zip(tables.generator_interior_exprs.iter()) .find(|(ty::GeneratorInteriorTypeCause { ty, .. }, _)| { // Careful: the regions for types that appear in the // generator interior are not generally known, so we @@ -2578,7 +2577,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { }; span.push_span_label(original_span, message); - err.set_span(span.clone()); + err.set_span(span); format!("is not {}", trait_name) } else { @@ -2586,29 +2585,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { }; // Look at the last interior type to get a span for the `.await`. - let await_span = tables.generator_interior_types.iter().map(|i| i.span).last().unwrap(); + let await_span = + tables.generator_interior_types.iter().map(|(i, _)| i.span).last().unwrap(); let mut span = MultiSpan::from_span(await_span); span.push_span_label( await_span, format!("{} occurs here, with `{}` maybe used later", await_or_yield, snippet), ); - if let Some(expr_id) = expr { - let expr = hir.expect_expr(expr_id); - let is_ref = tables.expr_adjustments(expr).iter().any(|adj| adj.is_region_borrow()); - let parent = hir.get_parent_node(expr_id); - if let Some(hir::Node::Expr(e)) = hir.find(parent) { - let method_span = hir.span(parent); - if tables.is_method_call(e) && is_ref { - err.span_help( - method_span, - "consider moving this method call into a `let` \ - binding to create a shorter lived borrow" - ); - } - } - } - span.push_span_label(target_span, format!("has type `{}`", target_ty)); // If available, use the scope span to annotate the drop location. @@ -2627,6 +2611,22 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ), ); + if let Some(expr_id) = expr { + let expr = hir.expect_expr(expr_id); + let is_ref = tables.expr_adjustments(expr).iter().any(|adj| adj.is_region_borrow()); + let parent = hir.get_parent_node(expr_id); + if let Some(hir::Node::Expr(e)) = hir.find(parent) { + let method_span = hir.span(parent); + if tables.is_method_call(e) && is_ref { + err.span_help( + method_span, + "consider moving this method call into a `let` \ + binding to create a shorter lived borrow", + ); + } + } + } + // Add a note for the item obligation that remains - normally a note pointing to the // bound that introduced the obligation (e.g. `T: Send`). debug!("note_obligation_cause_for_async_await: next_code={:?}", next_code); diff --git a/src/librustc/ty/adjustment.rs b/src/librustc/ty/adjustment.rs index 6531289bd7050..db034d1618cea 100644 --- a/src/librustc/ty/adjustment.rs +++ b/src/librustc/ty/adjustment.rs @@ -85,7 +85,7 @@ impl Adjustment<'tcx> { pub fn is_region_borrow(&self) -> bool { match self.kind { Adjust::Borrow(AutoBorrow::Ref(..)) => true, - _ => false + _ => false, } } } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 4a5fced7a89e5..d64e049c47b54 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -436,11 +436,9 @@ pub struct TypeckTables<'tcx> { /// entire variable. pub upvar_list: ty::UpvarListMap, - /// Stores the type, span and optional scope span of all types + /// Stores the type, expression, span and optional scope span of all types /// that are live across the yield of this generator (if a generator). - pub generator_interior_types: Vec>, - - pub generator_interior_exprs: Vec>, + pub generator_interior_types: Vec<(GeneratorInteriorTypeCause<'tcx>, Option)>, } impl<'tcx> TypeckTables<'tcx> { @@ -467,7 +465,6 @@ impl<'tcx> TypeckTables<'tcx> { concrete_opaque_types: Default::default(), upvar_list: Default::default(), generator_interior_types: Default::default(), - generator_interior_exprs: Default::default(), } } @@ -731,7 +728,6 @@ impl<'a, 'tcx> HashStable> for TypeckTables<'tcx> { ref concrete_opaque_types, ref upvar_list, ref generator_interior_types, - ref generator_interior_exprs, } = *self; hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| { @@ -770,7 +766,6 @@ impl<'a, 'tcx> HashStable> for TypeckTables<'tcx> { concrete_opaque_types.hash_stable(hcx, hasher); upvar_list.hash_stable(hcx, hasher); generator_interior_types.hash_stable(hcx, hasher); - generator_interior_exprs.hash_stable(hcx, hasher); }) } } diff --git a/src/librustc_typeck/check/generator_interior.rs b/src/librustc_typeck/check/generator_interior.rs index 9d8805f225d7e..7185de76fcbb6 100644 --- a/src/librustc_typeck/check/generator_interior.rs +++ b/src/librustc_typeck/check/generator_interior.rs @@ -18,6 +18,7 @@ use rustc_span::Span; struct InteriorVisitor<'a, 'tcx> { fcx: &'a FnCtxt<'a, 'tcx>, types: FxHashMap, usize>, + exprs: Vec>, region_scope_tree: &'tcx region::ScopeTree, expr_count: usize, kind: hir::GeneratorKind, @@ -99,6 +100,7 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> { scope_span, }) .or_insert(entries); + self.exprs.push(expr.map(|e| e.hir_id)); } } else { debug!( @@ -136,6 +138,7 @@ pub fn resolve_interior<'a, 'tcx>( expr_count: 0, kind, prev_unresolved_span: None, + exprs: vec![], }; intravisit::walk_body(&mut visitor, body); @@ -170,7 +173,8 @@ pub fn resolve_interior<'a, 'tcx>( }); // Store the generator types and spans into the tables for this generator. - let interior_types = types.iter().map(|t| t.0.clone()).collect::>(); + let interior_types = + types.iter().zip(visitor.exprs).map(|(t, e)| (t.0.clone(), e)).collect::>(); visitor.fcx.inh.tables.borrow_mut().generator_interior_types = interior_types; // Extract type components diff --git a/src/test/ui/async-await/issue-64130-4-async-move.stderr b/src/test/ui/async-await/issue-64130-4-async-move.stderr index ddbb469b99c24..77d0885c38d58 100644 --- a/src/test/ui/async-await/issue-64130-4-async-move.stderr +++ b/src/test/ui/async-await/issue-64130-4-async-move.stderr @@ -16,6 +16,11 @@ LL | let _x = get().await; ... LL | } | - `client` is later dropped here +help: consider moving this method call into a `let` binding to create a shorter lived borrow + --> $DIR/issue-64130-4-async-move.rs:19:15 + | +LL | match client.status() { + | ^^^^^^^^^^^^^^^ = note: the return type of a function must have a statically known size error: aborting due to previous error From 9864ec499ffe5621c1da47150adcfaf606ec76a4 Mon Sep 17 00:00:00 2001 From: Richard Dodd Date: Sun, 24 Nov 2019 20:44:19 +0000 Subject: [PATCH 050/169] Implement `finish_non_exhaustive` for `DebugStruct`. --- src/libcore/fmt/builders.rs | 56 +++++++++++++++++++++ src/libcore/tests/fmt/builders.rs | 83 +++++++++++++++++++++++++++++++ src/libcore/tests/lib.rs | 1 + 3 files changed, 140 insertions(+) diff --git a/src/libcore/fmt/builders.rs b/src/libcore/fmt/builders.rs index 626eb1e862d99..dd0f3ccb15841 100644 --- a/src/libcore/fmt/builders.rs +++ b/src/libcore/fmt/builders.rs @@ -159,6 +159,62 @@ impl<'a, 'b: 'a> DebugStruct<'a, 'b> { self } + /// Marks the struct as non-exhaustive, indicating to the reader that there are some other + /// fields that are not shown in the debug representation. + /// + /// # Examples + /// + /// ``` + /// # #![feature(debug_non_exhaustive)] + /// use std::fmt; + /// + /// struct Bar { + /// bar: i32, + /// hidden: f32, + /// } + /// + /// impl fmt::Debug for Bar { + /// fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + /// fmt.debug_struct("Bar") + /// .field("bar", &self.bar) + /// .finish_non_exhaustive() // Show that some other field(s) exist. + /// } + /// } + /// + /// assert_eq!( + /// format!("{:?}", Bar { bar: 10, hidden: 1.0 }), + /// "Bar { bar: 10, .. }", + /// ); + /// ``` + #[unstable(feature = "debug_non_exhaustive", issue = "67364")] + pub fn finish_non_exhaustive(&mut self) -> fmt::Result { + self.result = self.result.and_then(|_| { + // Draw non-exhaustive dots (`..`), and open brace if necessary (no fields). + if self.is_pretty() { + if !self.has_fields { + self.fmt.write_str(" {\n")?; + } + let mut slot = None; + let mut state = Default::default(); + let mut writer = PadAdapter::wrap(&mut self.fmt, &mut slot, &mut state); + writer.write_str("..\n")?; + } else { + if self.has_fields { + self.fmt.write_str(", ..")?; + } else { + self.fmt.write_str(" { ..")?; + } + } + if self.is_pretty() { + self.fmt.write_str("}")? + } else { + self.fmt.write_str(" }")?; + } + Ok(()) + }); + self.result + } + /// Finishes output and returns any error encountered. /// /// # Examples diff --git a/src/libcore/tests/fmt/builders.rs b/src/libcore/tests/fmt/builders.rs index 90a9bccda1580..d8ec6764bc620 100644 --- a/src/libcore/tests/fmt/builders.rs +++ b/src/libcore/tests/fmt/builders.rs @@ -93,6 +93,89 @@ mod debug_struct { format!("{:#?}", Bar) ); } + + #[test] + fn test_only_non_exhaustive() { + struct Foo; + + impl fmt::Debug for Foo { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_struct("Foo") + .finish_non_exhaustive() + } + } + + + assert_eq!("Foo { .. }", format!("{:?}", Foo)); + assert_eq!( +"Foo { + .. +}", + format!("{:#?}", Foo)); + } + + #[test] + fn test_multiple_and_non_exhaustive() { + struct Foo; + + impl fmt::Debug for Foo { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_struct("Foo") + .field("bar", &true) + .field("baz", &format_args!("{}/{}", 10, 20)) + .finish_non_exhaustive() + } + } + + assert_eq!("Foo { bar: true, baz: 10/20, .. }", format!("{:?}", Foo)); + assert_eq!( +"Foo { + bar: true, + baz: 10/20, + .. +}", + format!("{:#?}", Foo)); + } + + #[test] + fn test_nested_non_exhaustive() { + struct Foo; + + impl fmt::Debug for Foo { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_struct("Foo") + .field("bar", &true) + .field("baz", &format_args!("{}/{}", 10, 20)) + .finish_non_exhaustive() + } + } + + struct Bar; + + impl fmt::Debug for Bar { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_struct("Bar") + .field("foo", &Foo) + .field("hello", &"world") + .finish_non_exhaustive() + } + } + + assert_eq!("Bar { foo: Foo { bar: true, baz: 10/20, .. }, hello: \"world\", .. }", + format!("{:?}", Bar)); + assert_eq!( +"Bar { + foo: Foo { + bar: true, + baz: 10/20, + .. + }, + hello: \"world\", + .. +}", + format!("{:#?}", Bar)); + } + } mod debug_tuple { diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 86cf6fc104c83..8c034938c2bb9 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -5,6 +5,7 @@ #![feature(core_private_bignum)] #![feature(core_private_diy_float)] #![feature(debug_map_key_value)] +#![feature(debug_non_exhaustive)] #![feature(dec2flt)] #![feature(exact_size_is_empty)] #![feature(fixed_size_array)] From 87504173b3bb948ca0292055fbeb833fc5a41400 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 14 Jan 2020 09:59:46 -0800 Subject: [PATCH 051/169] Update the wasi-libc bundled with libstd --- src/ci/docker/dist-various-2/build-wasi-toolchain.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/dist-various-2/build-wasi-toolchain.sh b/src/ci/docker/dist-various-2/build-wasi-toolchain.sh index 925d5ca0223b1..b868677564298 100755 --- a/src/ci/docker/dist-various-2/build-wasi-toolchain.sh +++ b/src/ci/docker/dist-various-2/build-wasi-toolchain.sh @@ -12,7 +12,7 @@ export PATH=`pwd`/clang+llvm-9.0.0-x86_64-linux-gnu-ubuntu-14.04/bin:$PATH git clone https://github.com/CraneStation/wasi-libc cd wasi-libc -git reset --hard f645f498dfbbbc00a7a97874d33082d3605c3f21 +git reset --hard 1fad33890a5e299027ce0eab7b6ad5260585e347 make -j$(nproc) INSTALL_DIR=/wasm32-wasi install cd .. From 1bf9f69579e525a35fd712b7f00f2f24eebc6387 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 14 Jan 2020 19:21:10 +0100 Subject: [PATCH 052/169] Prevent urls in headings --- src/librustdoc/html/markdown.rs | 8 ++++++-- src/test/rustdoc/remove-url-from-headings.rs | 12 ++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 src/test/rustdoc/remove-url-from-headings.rs diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index c5f88f9f7f421..b2f5c8e81ff7e 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -380,7 +380,11 @@ impl<'a, 'b, 'ids, I: Iterator>> Iterator for HeadingLinks<'a, } _ => {} } - self.buf.push_back(event); + match event { + Event::Start(Tag::Link(_, _, text)) => self.buf.push_back(Event::Text(text)), + Event::End(Tag::Link(..)) => {} + event => self.buf.push_back(event), + } } let id = self.id_map.derive(id); @@ -395,7 +399,7 @@ impl<'a, 'b, 'ids, I: Iterator>> Iterator for HeadingLinks<'a, let start_tags = format!( "\ - ", + ", id = id, level = level ); diff --git a/src/test/rustdoc/remove-url-from-headings.rs b/src/test/rustdoc/remove-url-from-headings.rs new file mode 100644 index 0000000000000..7fbcdbafa7486 --- /dev/null +++ b/src/test/rustdoc/remove-url-from-headings.rs @@ -0,0 +1,12 @@ +#![crate_name = "foo"] + +// @has foo/fn.foo.html +// !@has - '//a[@href="http://a.a"]' +// @has - '//a[@href="#implementing-stuff-somewhere"]' 'Implementing stuff somewhere' + +/// fooo +/// +/// # Implementing [stuff](http://a.a) somewhere +/// +/// hello +pub fn foo() {} From 9f1452f6996935f796daadab05a956fd0ae69196 Mon Sep 17 00:00:00 2001 From: Daniel Frampton Date: Tue, 14 Jan 2020 11:26:03 -0800 Subject: [PATCH 053/169] Update libssh2-sys to a version that can build for aarch64-pc-windows-msvc --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4836e15cd799a..202c297b82de2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1806,9 +1806,9 @@ dependencies = [ [[package]] name = "libssh2-sys" -version = "0.2.11" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "126a1f4078368b163bfdee65fbab072af08a1b374a5551b21e87ade27b1fbf9d" +checksum = "36aa6e813339d3a063292b77091dfbbb6152ff9006a459895fa5bebed7d34f10" dependencies = [ "cc", "libc", From 535fc9ce4c97598f7cc1a093c9cd506a81e22689 Mon Sep 17 00:00:00 2001 From: Daniel Frampton Date: Tue, 14 Jan 2020 11:52:46 -0800 Subject: [PATCH 054/169] Update iovec to a version with no winapi dependency --- Cargo.lock | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4836e15cd799a..9eedab0a1d093 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1581,12 +1581,11 @@ dependencies = [ [[package]] name = "iovec" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" dependencies = [ "libc", - "winapi 0.2.8", ] [[package]] From 9febc2bc7a3a6397ca7e30155924d2d180a5e940 Mon Sep 17 00:00:00 2001 From: Daniel Frampton Date: Tue, 14 Jan 2020 11:56:51 -0800 Subject: [PATCH 055/169] Update to a version of cmake with windows arm64 support --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4836e15cd799a..602e0ae150a73 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -514,9 +514,9 @@ dependencies = [ [[package]] name = "cmake" -version = "0.1.38" +version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96210eec534fc3fbfc0452a63769424eaa80205fda6cea98e5b61cb3d97bcec8" +checksum = "81fb25b677f8bf1eb325017cb6bb8452f87969db0fedb4f757b297bee78a7c62" dependencies = [ "cc", ] From 7d6271b76b7ee7a192e03933ed6b37e6e6385c08 Mon Sep 17 00:00:00 2001 From: Daniel Frampton Date: Fri, 10 Jan 2020 09:11:32 -0800 Subject: [PATCH 056/169] Better support for cross compilation on Windows. --- src/bootstrap/native.rs | 2 ++ src/librustc_llvm/build.rs | 10 ++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index ce977f1bbc44e..89e1a7319cf59 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -230,6 +230,8 @@ impl Step for Llvm { cfg.define("CMAKE_SYSTEM_NAME", "NetBSD"); } else if target.contains("freebsd") { cfg.define("CMAKE_SYSTEM_NAME", "FreeBSD"); + } else if target.contains("windows") { + cfg.define("CMAKE_SYSTEM_NAME", "Windows"); } cfg.define("LLVM_NATIVE_BUILD", builder.llvm_out(builder.config.build).join("build")); diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs index dff20f8741065..405ce0307cd82 100644 --- a/src/librustc_llvm/build.rs +++ b/src/librustc_llvm/build.rs @@ -215,12 +215,14 @@ fn main() { let mut cmd = Command::new(&llvm_config); cmd.arg(llvm_link_arg).arg("--ldflags"); for lib in output(&mut cmd).split_whitespace() { - if lib.starts_with("-LIBPATH:") { - println!("cargo:rustc-link-search=native={}", &lib[9..]); - } else if is_crossed { - if lib.starts_with("-L") { + if is_crossed { + if lib.starts_with("-LIBPATH:") { + println!("cargo:rustc-link-search=native={}", lib[9..].replace(&host, &target)); + } else if lib.starts_with("-L") { println!("cargo:rustc-link-search=native={}", lib[2..].replace(&host, &target)); } + } else if lib.starts_with("-LIBPATH:") { + println!("cargo:rustc-link-search=native={}", &lib[9..]); } else if lib.starts_with("-l") { println!("cargo:rustc-link-lib={}", &lib[2..]); } else if lib.starts_with("-L") { From 106fe0b13a60c678c7a3372b8ef3f6160549ad5c Mon Sep 17 00:00:00 2001 From: Daniel Frampton Date: Tue, 14 Jan 2020 13:32:26 -0800 Subject: [PATCH 057/169] Update to a version of compiler_builtins with changes for fixes remainder for aarch64 windows --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4836e15cd799a..08b22e629d221 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -570,9 +570,9 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.22" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6f083abf9bb9005a27d2da62706f661245278cb7096da37ab27410eaf60f2c1" +checksum = "b9975aefa63997ef75ca9cf013ff1bb81487aaa0b622c21053afd3b92979a7af" dependencies = [ "cc", "rustc-std-workspace-core", From 01dc44bfe00e374cf769cee5757d0ac97faa15a2 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 14 Jan 2020 14:26:35 -0500 Subject: [PATCH 058/169] Avoid calling tcx.hir().get() on CRATE_HIR_ID This was causing an ICE when enabling trace logging for an unrelated module, since the arguments to `trace!` ended up getting evaluated --- src/librustc/infer/opaque_types/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index a1afb1a86be44..ee214bea7b8fc 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -1219,7 +1219,7 @@ pub fn may_define_opaque_type(tcx: TyCtxt<'_>, def_id: DefId, opaque_hir_id: hir let res = hir_id == scope; trace!( "may_define_opaque_type(def={:?}, opaque_node={:?}) = {}", - tcx.hir().get(hir_id), + tcx.hir().find(hir_id), tcx.hir().get(opaque_hir_id), res ); From 064f8885d5e1d38673783d626d9d3fc1b7b909f4 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 13 Jan 2020 16:40:19 -0500 Subject: [PATCH 059/169] Add unicode table generator --- .gitignore | 9 +- Cargo.lock | 17 ++ Cargo.toml | 1 + src/tools/unicode-table-generator/Cargo.toml | 10 + .../src/case_mapping.rs | 62 +++++ src/tools/unicode-table-generator/src/main.rs | 261 ++++++++++++++++++ .../src/raw_emitter.rs | 170 ++++++++++++ .../src/unicode_download.rs | 42 +++ 8 files changed, 564 insertions(+), 8 deletions(-) create mode 100644 src/tools/unicode-table-generator/Cargo.toml create mode 100644 src/tools/unicode-table-generator/src/case_mapping.rs create mode 100644 src/tools/unicode-table-generator/src/main.rs create mode 100644 src/tools/unicode-table-generator/src/raw_emitter.rs create mode 100644 src/tools/unicode-table-generator/src/unicode_download.rs diff --git a/.gitignore b/.gitignore index 1428ee6c9bc23..d9761ce40927c 100644 --- a/.gitignore +++ b/.gitignore @@ -34,14 +34,7 @@ __pycache__/ # Created by default with `src/ci/docker/run.sh`: /obj/ /rustllvm/ -/src/libcore/unicode/DerivedCoreProperties.txt -/src/libcore/unicode/DerivedNormalizationProps.txt -/src/libcore/unicode/PropList.txt -/src/libcore/unicode/ReadMe.txt -/src/libcore/unicode/Scripts.txt -/src/libcore/unicode/SpecialCasing.txt -/src/libcore/unicode/UnicodeData.txt -/src/libcore/unicode/downloaded +/unicode-downloads /target/ # Generated by compiletest for incremental: /tmp/ diff --git a/Cargo.lock b/Cargo.lock index 4836e15cd799a..3f1058645d264 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4930,6 +4930,16 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" +[[package]] +name = "ucd-parse" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca6b52bf4da6512f0f07785a04769222e50d29639e7ecd016b7806fd2de306b4" +dependencies = [ + "lazy_static 1.3.0", + "regex", +] + [[package]] name = "ucd-trie" version = "0.1.1" @@ -4951,6 +4961,13 @@ dependencies = [ "version_check 0.1.5", ] +[[package]] +name = "unicode-bdd" +version = "0.1.0" +dependencies = [ + "ucd-parse", +] + [[package]] name = "unicode-bidi" version = "0.3.4" diff --git a/Cargo.toml b/Cargo.toml index a242f090fbc07..9d5c27b96df5d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,7 @@ members = [ "src/tools/rustfmt", "src/tools/miri", "src/tools/rustdoc-themes", + "src/tools/unicode-table-generator", ] exclude = [ "build", diff --git a/src/tools/unicode-table-generator/Cargo.toml b/src/tools/unicode-table-generator/Cargo.toml new file mode 100644 index 0000000000000..92344cdfc89ee --- /dev/null +++ b/src/tools/unicode-table-generator/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "unicode-bdd" +version = "0.1.0" +authors = ["Mark Rousskov "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +ucd-parse = "0.1.3" diff --git a/src/tools/unicode-table-generator/src/case_mapping.rs b/src/tools/unicode-table-generator/src/case_mapping.rs new file mode 100644 index 0000000000000..01f199c213e02 --- /dev/null +++ b/src/tools/unicode-table-generator/src/case_mapping.rs @@ -0,0 +1,62 @@ +use crate::{fmt_list, UnicodeData}; +use std::fmt; + +pub(crate) fn generate_case_mapping(data: &UnicodeData) -> String { + let mut file = String::new(); + + file.push_str(HEADER.trim_start()); + + let decl_type = "&[(char, [char; 3])]"; + + file.push_str(&format!( + "static LOWERCASE_TABLE: {} = &[{}];", + decl_type, + fmt_list(data.to_lower.iter().map(to_mapping)) + )); + file.push_str("\n\n"); + file.push_str(&format!( + "static UPPERCASE_TABLE: {} = &[{}];", + decl_type, + fmt_list(data.to_upper.iter().map(to_mapping)) + )); + file +} + +fn to_mapping((key, (a, b, c)): (&u32, &(u32, u32, u32))) -> (CharEscape, [CharEscape; 3]) { + ( + CharEscape(std::char::from_u32(*key).unwrap()), + [ + CharEscape(std::char::from_u32(*a).unwrap()), + CharEscape(std::char::from_u32(*b).unwrap()), + CharEscape(std::char::from_u32(*c).unwrap()), + ], + ) +} + +struct CharEscape(char); + +impl fmt::Debug for CharEscape { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "'{}'", self.0.escape_default()) + } +} + +static HEADER: &str = " +pub fn to_lower(c: char) -> [char; 3] { + match bsearch_case_table(c, LOWERCASE_TABLE) { + None => [c, '\\0', '\\0'], + Some(index) => LOWERCASE_TABLE[index].1, + } +} + +pub fn to_upper(c: char) -> [char; 3] { + match bsearch_case_table(c, UPPERCASE_TABLE) { + None => [c, '\\0', '\\0'], + Some(index) => UPPERCASE_TABLE[index].1, + } +} + +fn bsearch_case_table(c: char, table: &[(char, [char; 3])]) -> Option { + table.binary_search_by(|&(key, _)| key.cmp(&c)).ok() +} +"; diff --git a/src/tools/unicode-table-generator/src/main.rs b/src/tools/unicode-table-generator/src/main.rs new file mode 100644 index 0000000000000..be8508e3973a2 --- /dev/null +++ b/src/tools/unicode-table-generator/src/main.rs @@ -0,0 +1,261 @@ +use std::collections::{BTreeMap, HashMap}; +use std::ops::Range; +use ucd_parse::Codepoints; + +mod case_mapping; +mod raw_emitter; +mod unicode_download; + +use raw_emitter::{emit_codepoints, RawEmitter}; + +static PROPERTIES: &[&str] = &[ + "Alphabetic", + "Lowercase", + "Uppercase", + "Cased", + "Case_Ignorable", + "Grapheme_Extend", + "White_Space", + "Cc", + "N", +]; + +struct UnicodeData { + ranges: Vec<(&'static str, Vec>)>, + to_upper: BTreeMap, + to_lower: BTreeMap, +} + +fn to_mapping(origin: u32, codepoints: Vec) -> Option<(u32, u32, u32)> { + let mut a = None; + let mut b = None; + let mut c = None; + + for codepoint in codepoints { + if origin == codepoint.value() { + return None; + } + + if a.is_none() { + a = Some(codepoint.value()); + } else if b.is_none() { + b = Some(codepoint.value()); + } else if c.is_none() { + c = Some(codepoint.value()); + } else { + panic!("more than 3 mapped codepoints") + } + } + + Some((a.unwrap(), b.unwrap_or(0), c.unwrap_or(0))) +} + +static UNICODE_DIRECTORY: &str = "unicode-downloads"; + +fn load_data() -> UnicodeData { + unicode_download::fetch_latest(); + + let mut properties = HashMap::new(); + for row in ucd_parse::parse::<_, ucd_parse::CoreProperty>(&UNICODE_DIRECTORY).unwrap() { + if let Some(name) = PROPERTIES.iter().find(|prop| **prop == row.property.as_str()) { + properties.entry(*name).or_insert_with(Vec::new).push(row.codepoints); + } + } + for row in ucd_parse::parse::<_, ucd_parse::Property>(&UNICODE_DIRECTORY).unwrap() { + if let Some(name) = PROPERTIES.iter().find(|prop| **prop == row.property.as_str()) { + properties.entry(*name).or_insert_with(Vec::new).push(row.codepoints); + } + } + + let mut to_lower = BTreeMap::new(); + let mut to_upper = BTreeMap::new(); + for row in ucd_parse::UnicodeDataExpander::new( + ucd_parse::parse::<_, ucd_parse::UnicodeData>(&UNICODE_DIRECTORY).unwrap(), + ) { + let general_category = if ["Nd", "Nl", "No"].contains(&row.general_category.as_str()) { + "N" + } else { + row.general_category.as_str() + }; + if let Some(name) = PROPERTIES.iter().find(|prop| **prop == general_category) { + properties + .entry(*name) + .or_insert_with(Vec::new) + .push(Codepoints::Single(row.codepoint)); + } + + if let Some(mapped) = row.simple_lowercase_mapping { + if mapped != row.codepoint { + to_lower.insert(row.codepoint.value(), (mapped.value(), 0, 0)); + } + } + if let Some(mapped) = row.simple_uppercase_mapping { + if mapped != row.codepoint { + to_upper.insert(row.codepoint.value(), (mapped.value(), 0, 0)); + } + } + } + + for row in ucd_parse::parse::<_, ucd_parse::SpecialCaseMapping>(&UNICODE_DIRECTORY).unwrap() { + if !row.conditions.is_empty() { + // Skip conditional case mappings + continue; + } + + let key = row.codepoint.value(); + if let Some(lower) = to_mapping(key, row.lowercase) { + to_lower.insert(key, lower); + } + if let Some(upper) = to_mapping(key, row.uppercase) { + to_upper.insert(key, upper); + } + } + + let mut properties: HashMap<&'static str, Vec>> = properties + .into_iter() + .map(|(k, v)| { + ( + k, + v.into_iter() + .flat_map(|codepoints| match codepoints { + Codepoints::Single(c) => c + .scalar() + .map(|ch| (ch as u32..ch as u32 + 1)) + .into_iter() + .collect::>(), + Codepoints::Range(c) => c + .into_iter() + .flat_map(|c| c.scalar().map(|ch| (ch as u32..ch as u32 + 1))) + .collect::>(), + }) + .collect::>>(), + ) + }) + .collect(); + + for ranges in properties.values_mut() { + merge_ranges(ranges); + } + + let mut properties = properties.into_iter().collect::>(); + properties.sort_by_key(|p| p.0); + UnicodeData { ranges: properties, to_lower, to_upper } +} + +fn main() { + let write_location = std::env::args().nth(1).unwrap_or_else(|| { + eprintln!("Must provide path to write unicode tables to"); + eprintln!( + "e.g. {} src/libcore/unicode/unicode_data.rs", + std::env::args().nth(0).unwrap_or_default() + ); + std::process::exit(1); + }); + + let unicode_data = load_data(); + let ranges_by_property = &unicode_data.ranges; + + let mut total_bytes = 0; + let mut modules = Vec::new(); + for (property, ranges) in ranges_by_property { + let datapoints = ranges.iter().map(|r| r.end - r.start).sum::(); + let mut emitter = RawEmitter::new(); + emit_codepoints(&mut emitter, &ranges); + + modules.push((property.to_lowercase().to_string(), emitter.file)); + println!("{:15}: {} bytes, {} codepoints", property, emitter.bytes_used, datapoints,); + total_bytes += emitter.bytes_used; + } + + let mut table_file = String::new(); + + table_file.push_str( + "///! This file is generated by src/tools/unicode-table-generator; do not edit manually!\n", + ); + + table_file.push_str("use super::range_search;\n\n"); + + table_file.push_str(&version()); + + table_file.push('\n'); + + modules.push((String::from("conversions"), case_mapping::generate_case_mapping(&unicode_data))); + + for (name, contents) in modules { + table_file.push_str("#[rustfmt::skip]\n"); + table_file.push_str(&format!("pub mod {} {{\n", name)); + for line in contents.lines() { + if !line.trim().is_empty() { + table_file.push_str(" "); + table_file.push_str(&line); + } + table_file.push('\n'); + } + table_file.push_str("}\n\n"); + } + + std::fs::write(&write_location, format!("{}\n", table_file.trim_end())).unwrap(); + + println!("Total table sizes: {} bytes", total_bytes); +} + +fn version() -> String { + let mut out = String::new(); + out.push_str("pub const UNICODE_VERSION: (u32, u32, u32) = "); + + let readme = + std::fs::read_to_string(std::path::Path::new(UNICODE_DIRECTORY).join("ReadMe.txt")) + .unwrap(); + + let prefix = "for Version "; + let start = readme.find(prefix).unwrap() + prefix.len(); + let end = readme.find(" of the Unicode Standard.").unwrap(); + let version = + readme[start..end].split('.').map(|v| v.parse::().expect(&v)).collect::>(); + let [major, minor, micro] = [version[0], version[1], version[2]]; + + out.push_str(&format!("({}, {}, {});\n", major, minor, micro)); + out +} + +fn fmt_list(values: impl IntoIterator) -> String { + let pieces = values.into_iter().map(|b| format!("{:?}, ", b)).collect::>(); + let mut out = String::new(); + let mut line = format!("\n "); + for piece in pieces { + if line.len() + piece.len() < 98 { + line.push_str(&piece); + } else { + out.push_str(line.trim_end()); + out.push('\n'); + line = format!(" {}", piece); + } + } + out.push_str(line.trim_end()); + out.push('\n'); + out +} + +fn merge_ranges(ranges: &mut Vec>) { + loop { + let mut new_ranges = Vec::new(); + let mut idx_iter = 0..(ranges.len() - 1); + while let Some(idx) = idx_iter.next() { + let cur = ranges[idx].clone(); + let next = ranges[idx + 1].clone(); + if cur.end == next.start { + let _ = idx_iter.next(); // skip next as we're merging it in + new_ranges.push(cur.start..next.end); + } else { + new_ranges.push(cur); + } + } + new_ranges.push(ranges.last().unwrap().clone()); + if new_ranges.len() == ranges.len() { + *ranges = new_ranges; + break; + } else { + *ranges = new_ranges; + } + } +} diff --git a/src/tools/unicode-table-generator/src/raw_emitter.rs b/src/tools/unicode-table-generator/src/raw_emitter.rs new file mode 100644 index 0000000000000..3e60ce13f9223 --- /dev/null +++ b/src/tools/unicode-table-generator/src/raw_emitter.rs @@ -0,0 +1,170 @@ +//! This implements the core logic of the compression scheme used to compactly +//! encode the Unicode character classes. +//! +//! The primary idea is that we 'flatten' the Unicode ranges into an enormous +//! bitset. To represent any arbitrary codepoint in a raw bitset, we would need +//! over 17 kilobytes of data per character set -- way too much for our +//! purposes. +//! +//! We have two primary goals with the encoding: we want to be compact, because +//! these tables often end up in ~every Rust program (especially the +//! grapheme_extend table, used for str debugging), including those for embedded +//! targets (where space is important). We also want to be relatively fast, +//! though this is more of a nice to have rather than a key design constraint. +//! In practice, due to modern processor design these two are closely related. +//! +//! The encoding scheme here compresses the bitset by first deduplicating the +//! "words" (64 bits on all platforms). In practice very few words are present +//! in most data sets. +//! +//! This gives us an array that maps `u8 -> word` (if we ever went beyond 256 +//! words, we could go to u16 -> word or have some dual compression scheme +//! mapping into two separate sets; currently this is not dealt with). +//! +//! With that scheme, we now have a single byte for every 64 codepoints. We +//! further group these by 16 (arbitrarily chosen), and again deduplicate and +//! store in an array (u8 -> [u8; 16]). +//! +//! The indices into this array represent ranges of 64*16 = 1024 codepoints. +//! +//! This already reduces the top-level array to at most 1,086 bytes, but in +//! practice we usually can encode in far fewer (the first couple Unicode planes +//! are dense). +//! +//! The last byte of this top-level array is pulled out to a separate static +//! and trailing zeros are dropped; this is simply because grapheme_extend and +//! case_ignorable have a single entry in the 896th entry, so this shrinks them +//! down considerably. + +use crate::fmt_list; +use std::collections::{BTreeSet, HashMap}; +use std::convert::TryFrom; +use std::fmt::Write; +use std::ops::Range; + +pub struct RawEmitter { + pub file: String, + pub bytes_used: usize, +} + +impl RawEmitter { + pub fn new() -> RawEmitter { + RawEmitter { file: String::new(), bytes_used: 0 } + } + + fn blank_line(&mut self) { + if self.file.is_empty() || self.file.ends_with("\n\n") { + return; + } + writeln!(&mut self.file, "").unwrap(); + } + + fn emit_bitset(&mut self, words: &[u64]) { + let unique_words = + words.iter().cloned().collect::>().into_iter().collect::>(); + if unique_words.len() > u8::max_value() as usize { + panic!("cannot pack {} into 8 bits", unique_words.len()); + } + + let word_indices = unique_words + .iter() + .cloned() + .enumerate() + .map(|(idx, word)| (word, u8::try_from(idx).unwrap())) + .collect::>(); + + let mut idx = words.iter().map(|w| word_indices[w]).collect::>(); + let chunk_length = 16; + for _ in 0..(chunk_length - (idx.len() % chunk_length)) { + assert_eq!(unique_words[0], 0, "first word is all zeros"); + // pad out bitset index with zero words so we have all chunks of 16 + idx.push(0); + } + + let mut chunks = BTreeSet::new(); + for chunk in idx.chunks(chunk_length) { + chunks.insert(chunk); + } + let chunk_map = chunks + .clone() + .into_iter() + .enumerate() + .map(|(idx, chunk)| (chunk, idx)) + .collect::>(); + let mut chunk_indices = Vec::new(); + for chunk in idx.chunks(chunk_length) { + chunk_indices.push(chunk_map[chunk]); + } + writeln!( + &mut self.file, + "static BITSET_LAST_CHUNK_MAP: (u16, u8) = ({}, {});", + chunk_indices.len() - 1, + chunk_indices.pop().unwrap(), + ) + .unwrap(); + self.bytes_used += 3; + // Strip out the empty pieces, presuming our above pop() made us now + // have some trailing zeros. + assert_eq!(unique_words[0], 0, "first word is all zeros"); + while let Some(0) = chunk_indices.last() { + chunk_indices.pop(); + } + writeln!( + &mut self.file, + "static BITSET_CHUNKS_MAP: [u8; {}] = [{}];", + chunk_indices.len(), + fmt_list(&chunk_indices), + ) + .unwrap(); + self.bytes_used += chunk_indices.len(); + writeln!( + &mut self.file, + "static BITSET_INDEX_CHUNKS: [[u8; 16]; {}] = [{}];", + chunks.len(), + fmt_list(chunks.iter()), + ) + .unwrap(); + self.bytes_used += 16 * chunks.len(); + writeln!( + &mut self.file, + "static BITSET: [u64; {}] = [{}];", + unique_words.len(), + fmt_list(&unique_words), + ) + .unwrap(); + self.bytes_used += 8 * unique_words.len(); + } + + pub fn emit_lookup(&mut self) { + writeln!(&mut self.file, "pub fn lookup(c: char) -> bool {{").unwrap(); + writeln!(&mut self.file, " super::range_search(",).unwrap(); + writeln!(&mut self.file, " c as u32,").unwrap(); + writeln!(&mut self.file, " &BITSET_CHUNKS_MAP,").unwrap(); + writeln!(&mut self.file, " BITSET_LAST_CHUNK_MAP,").unwrap(); + writeln!(&mut self.file, " &BITSET_INDEX_CHUNKS,").unwrap(); + writeln!(&mut self.file, " &BITSET,").unwrap(); + writeln!(&mut self.file, " )").unwrap(); + writeln!(&mut self.file, "}}").unwrap(); + } +} + +pub fn emit_codepoints(emitter: &mut RawEmitter, ranges: &[Range]) { + emitter.blank_line(); + + let last_code_point = ranges.last().unwrap().end; + // bitset for every bit in the codepoint range + // + // + 2 to ensure an all zero word to use for padding + let mut buckets = vec![0u64; (last_code_point as usize / 64) + 2]; + for range in ranges { + for codepoint in range.clone() { + let bucket = codepoint as usize / 64; + let bit = codepoint as u64 % 64; + buckets[bucket] |= 1 << bit; + } + } + + emitter.emit_bitset(&buckets); + emitter.blank_line(); + emitter.emit_lookup(); +} diff --git a/src/tools/unicode-table-generator/src/unicode_download.rs b/src/tools/unicode-table-generator/src/unicode_download.rs new file mode 100644 index 0000000000000..3f6de9ea3bbd7 --- /dev/null +++ b/src/tools/unicode-table-generator/src/unicode_download.rs @@ -0,0 +1,42 @@ +use crate::UNICODE_DIRECTORY; +use std::path::Path; +use std::process::Command; + +static URL_PREFIX: &str = "https://www.unicode.org/Public/UCD/latest/ucd/"; + +static README: &str = "ReadMe.txt"; + +static RESOURCES: &[&str] = + &["DerivedCoreProperties.txt", "PropList.txt", "UnicodeData.txt", "SpecialCasing.txt"]; + +pub fn fetch_latest() { + let directory = Path::new(UNICODE_DIRECTORY); + if let Err(e) = std::fs::create_dir_all(directory) { + if e.kind() != std::io::ErrorKind::AlreadyExists { + panic!("Failed to create {:?}: {}", UNICODE_DIRECTORY, e); + } + } + let output = Command::new("curl").arg(URL_PREFIX.to_owned() + README).output().unwrap(); + if !output.status.success() { + panic!( + "Failed to run curl to fetch readme: stderr: {}", + String::from_utf8_lossy(&output.stderr) + ); + } + let current = std::fs::read_to_string(directory.join(README)).unwrap_or_default(); + if current.as_bytes() != &output.stdout[..] { + std::fs::write(directory.join(README), output.stdout).unwrap(); + } + + for resource in RESOURCES { + let output = Command::new("curl").arg(URL_PREFIX.to_owned() + resource).output().unwrap(); + if !output.status.success() { + panic!( + "Failed to run curl to fetch {}: stderr: {}", + resource, + String::from_utf8_lossy(&output.stderr) + ); + } + std::fs::write(directory.join(resource), output.stdout).unwrap(); + } +} From 40ad8778513185c3597e99170371181d1e1d694c Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 13 Jan 2020 16:58:50 -0500 Subject: [PATCH 060/169] Add support code for new unicode_data module --- src/libcore/unicode/mod.rs | 54 ++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/src/libcore/unicode/mod.rs b/src/libcore/unicode/mod.rs index e424174f55469..b6eaf06aa7f63 100644 --- a/src/libcore/unicode/mod.rs +++ b/src/libcore/unicode/mod.rs @@ -1,15 +1,59 @@ #![unstable(feature = "unicode_internals", issue = "none")] #![allow(missing_docs)] -mod bool_trie; pub(crate) mod printable; -pub(crate) mod tables; +mod unicode_data; pub(crate) mod version; +use version::UnicodeVersion; + +/// The version of [Unicode](http://www.unicode.org/) that the Unicode parts of +/// `char` and `str` methods are based on. +#[unstable(feature = "unicode_version", issue = "49726")] +pub const UNICODE_VERSION: UnicodeVersion = UnicodeVersion { + major: unicode_data::UNICODE_VERSION.0, + minor: unicode_data::UNICODE_VERSION.1, + micro: unicode_data::UNICODE_VERSION.2, + _priv: (), +}; + // For use in liballoc, not re-exported in libstd. pub mod derived_property { - pub use crate::unicode::tables::derived_property::{Case_Ignorable, Cased}; + pub use super::{Case_Ignorable, Cased}; } -pub mod conversions { - pub use crate::unicode::tables::conversions::{to_lower, to_upper}; + +pub use unicode_data::alphabetic::lookup as Alphabetic; +pub use unicode_data::case_ignorable::lookup as Case_Ignorable; +pub use unicode_data::cased::lookup as Cased; +pub use unicode_data::cc::lookup as Cc; +pub use unicode_data::conversions; +pub use unicode_data::grapheme_extend::lookup as Grapheme_Extend; +pub use unicode_data::lowercase::lookup as Lowercase; +pub use unicode_data::n::lookup as N; +pub use unicode_data::uppercase::lookup as Uppercase; +pub use unicode_data::white_space::lookup as White_Space; + +#[inline(always)] +fn range_search( + needle: u32, + chunk_idx_map: &[u8; N], + (last_chunk_idx, last_chunk_mapping): (u16, u8), + bitset_chunk_idx: &[[u8; 16]; N1], + bitset: &[u64; N2], +) -> bool { + let bucket_idx = (needle / 64) as usize; + let chunk_map_idx = bucket_idx / 16; + let chunk_piece = bucket_idx % 16; + let chunk_idx = if chunk_map_idx >= N { + if chunk_map_idx == last_chunk_idx as usize { + last_chunk_mapping + } else { + return false; + } + } else { + chunk_idx_map[chunk_map_idx] + }; + let idx = bitset_chunk_idx[(chunk_idx as usize)][chunk_piece]; + let word = bitset[(idx as usize)]; + (word & (1 << (needle % 64) as u64)) != 0 } From efcda047397262f403df54d9f5e569dd32704168 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 13 Jan 2020 16:59:33 -0500 Subject: [PATCH 061/169] Replace old tables with new unicode data --- src/libcore/char/methods.rs | 16 +- src/libcore/char/mod.rs | 4 +- src/libcore/unicode/bool_trie.rs | 66 - src/libcore/unicode/tables.rs | 2235 ------------------------- src/libcore/unicode/unicode.py | 878 ---------- src/libcore/unicode/unicode_data.rs | 2343 +++++++++++++++++++++++++++ 6 files changed, 2353 insertions(+), 3189 deletions(-) delete mode 100644 src/libcore/unicode/bool_trie.rs delete mode 100644 src/libcore/unicode/tables.rs delete mode 100755 src/libcore/unicode/unicode.py create mode 100644 src/libcore/unicode/unicode_data.rs diff --git a/src/libcore/char/methods.rs b/src/libcore/char/methods.rs index fe5d16862a6a6..c341bb552a1ea 100644 --- a/src/libcore/char/methods.rs +++ b/src/libcore/char/methods.rs @@ -3,7 +3,7 @@ use crate::slice; use crate::str::from_utf8_unchecked_mut; use crate::unicode::printable::is_printable; -use crate::unicode::tables::{conversions, derived_property, general_category, property}; +use crate::unicode::{self, conversions}; use super::*; @@ -552,7 +552,7 @@ impl char { pub fn is_alphabetic(self) -> bool { match self { 'a'..='z' | 'A'..='Z' => true, - c => c > '\x7f' && derived_property::Alphabetic(c), + c => c > '\x7f' && unicode::Alphabetic(c), } } @@ -583,7 +583,7 @@ impl char { pub fn is_lowercase(self) -> bool { match self { 'a'..='z' => true, - c => c > '\x7f' && derived_property::Lowercase(c), + c => c > '\x7f' && unicode::Lowercase(c), } } @@ -614,7 +614,7 @@ impl char { pub fn is_uppercase(self) -> bool { match self { 'A'..='Z' => true, - c => c > '\x7f' && derived_property::Uppercase(c), + c => c > '\x7f' && unicode::Uppercase(c), } } @@ -642,7 +642,7 @@ impl char { pub fn is_whitespace(self) -> bool { match self { ' ' | '\x09'..='\x0d' => true, - c => c > '\x7f' && property::White_Space(c), + c => c > '\x7f' && unicode::White_Space(c), } } @@ -693,7 +693,7 @@ impl char { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn is_control(self) -> bool { - general_category::Cc(self) + unicode::Cc(self) } /// Returns `true` if this `char` has the `Grapheme_Extend` property. @@ -707,7 +707,7 @@ impl char { /// [`DerivedCoreProperties.txt`]: https://www.unicode.org/Public/UCD/latest/ucd/DerivedCoreProperties.txt #[inline] pub(crate) fn is_grapheme_extended(self) -> bool { - derived_property::Grapheme_Extend(self) + unicode::Grapheme_Extend(self) } /// Returns `true` if this `char` has one of the general categories for numbers. @@ -739,7 +739,7 @@ impl char { pub fn is_numeric(self) -> bool { match self { '0'..='9' => true, - c => c > '\x7f' && general_category::N(c), + c => c > '\x7f' && unicode::N(c), } } diff --git a/src/libcore/char/mod.rs b/src/libcore/char/mod.rs index a655ee6e7e32a..cf5576e549cdf 100644 --- a/src/libcore/char/mod.rs +++ b/src/libcore/char/mod.rs @@ -37,9 +37,9 @@ pub use self::decode::{decode_utf16, DecodeUtf16, DecodeUtf16Error}; // unstable re-exports #[unstable(feature = "unicode_version", issue = "49726")] -pub use crate::unicode::tables::UNICODE_VERSION; -#[unstable(feature = "unicode_version", issue = "49726")] pub use crate::unicode::version::UnicodeVersion; +#[unstable(feature = "unicode_version", issue = "49726")] +pub use crate::unicode::UNICODE_VERSION; use crate::fmt::{self, Write}; use crate::iter::FusedIterator; diff --git a/src/libcore/unicode/bool_trie.rs b/src/libcore/unicode/bool_trie.rs deleted file mode 100644 index b7fba88a540f9..0000000000000 --- a/src/libcore/unicode/bool_trie.rs +++ /dev/null @@ -1,66 +0,0 @@ -/// BoolTrie is a trie for representing a set of Unicode codepoints. It is -/// implemented with postfix compression (sharing of identical child nodes), -/// which gives both compact size and fast lookup. -/// -/// The space of Unicode codepoints is divided into 3 subareas, each -/// represented by a trie with different depth. In the first (0..0x800), there -/// is no trie structure at all; each u64 entry corresponds to a bitvector -/// effectively holding 64 bool values. -/// -/// In the second (0x800..0x10000), each child of the root node represents a -/// 64-wide subrange, but instead of storing the full 64-bit value of the leaf, -/// the trie stores an 8-bit index into a shared table of leaf values. This -/// exploits the fact that in reasonable sets, many such leaves can be shared. -/// -/// In the third (0x10000..0x110000), each child of the root node represents a -/// 4096-wide subrange, and the trie stores an 8-bit index into a 64-byte slice -/// of a child tree. Each of these 64 bytes represents an index into the table -/// of shared 64-bit leaf values. This exploits the sparse structure in the -/// non-BMP range of most Unicode sets. -pub struct BoolTrie { - // 0..0x800 (corresponding to 1 and 2 byte utf-8 sequences) - pub r1: [u64; 32], // leaves - - // 0x800..0x10000 (corresponding to 3 byte utf-8 sequences) - pub r2: [u8; 992], // first level - pub r3: &'static [u64], // leaves - - // 0x10000..0x110000 (corresponding to 4 byte utf-8 sequences) - pub r4: [u8; 256], // first level - pub r5: &'static [u8], // second level - pub r6: &'static [u64], // leaves -} -impl BoolTrie { - pub fn lookup(&self, c: char) -> bool { - let c = c as u32; - if c < 0x800 { - trie_range_leaf(c, self.r1[(c >> 6) as usize]) - } else if c < 0x10000 { - let child = self.r2[(c >> 6) as usize - 0x20]; - trie_range_leaf(c, self.r3[child as usize]) - } else { - let child = self.r4[(c >> 12) as usize - 0x10]; - let leaf = self.r5[((child as usize) << 6) + ((c >> 6) as usize & 0x3f)]; - trie_range_leaf(c, self.r6[leaf as usize]) - } - } -} - -pub struct SmallBoolTrie { - pub(crate) r1: &'static [u8], // first level - pub(crate) r2: &'static [u64], // leaves -} - -impl SmallBoolTrie { - pub fn lookup(&self, c: char) -> bool { - let c = c as u32; - match self.r1.get((c >> 6) as usize) { - Some(&child) => trie_range_leaf(c, self.r2[child as usize]), - None => false, - } - } -} - -fn trie_range_leaf(c: u32, bitmap_chunk: u64) -> bool { - ((bitmap_chunk >> (c & 63)) & 1) != 0 -} diff --git a/src/libcore/unicode/tables.rs b/src/libcore/unicode/tables.rs deleted file mode 100644 index 3fa125e8fea15..0000000000000 --- a/src/libcore/unicode/tables.rs +++ /dev/null @@ -1,2235 +0,0 @@ -// NOTE: The following code was generated by "./unicode.py", do not edit directly - -#![allow(missing_docs, non_upper_case_globals, non_snake_case, clippy::unreadable_literal)] - -use crate::unicode::bool_trie::{BoolTrie, SmallBoolTrie}; -use crate::unicode::version::UnicodeVersion; - -/// The version of [Unicode](http://www.unicode.org/) that the Unicode parts of -/// `char` and `str` methods are based on. -#[unstable(feature = "unicode_version", issue = "49726")] -pub const UNICODE_VERSION: UnicodeVersion = - UnicodeVersion { major: 12, minor: 1, micro: 0, _priv: () }; -pub(crate) mod general_category { - #[rustfmt::skip] - const Cc_table: &super::SmallBoolTrie = &super::SmallBoolTrie { - r1: &[ - 0, 1, 0 - ], - r2: &[ - 0x00000000ffffffff, 0x8000000000000000 - ], - }; - - pub fn Cc(c: char) -> bool { - Cc_table.lookup(c) - } - - #[rustfmt::skip] - const N_table: &super::BoolTrie = &super::BoolTrie { - r1: [ - 0x03ff000000000000, 0x0000000000000000, 0x720c000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x000003ff00000000, 0x0000000000000000, 0x03ff000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x00000000000003ff - ], - r2: [ - 0, 0, 0, 0, 0, 1, 0, 2, 0, 1, 0, 1, 0, 3, 0, 4, 0, 5, 0, 1, 0, 6, 0, 1, 0, 7, 0, 7, 8, - 0, 0, 0, 0, 9, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 11, 0, 0, 0, 12, 7, 0, 0, 0, 0, 13, 0, 14, 0, 0, 15, 0, 0, 7, 16, 0, 0, 15, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 9, 0, 0, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 27, 0, 28, - 29, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, - 0, 0, 1, 0, 0, 0, 0, 31, 0, 0, 7, 9, 0, 0, 32, 0, 7, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0 - ], - r3: &[ - 0x0000000000000000, 0x0000ffc000000000, 0x03f0ffc000000000, 0x00fcffc000000000, - 0x0007ffc000000000, 0x7f00ffc000000000, 0x01ffffc07f000000, 0x0000000003ff0000, - 0x000fffff00000000, 0x00000000000003ff, 0x1ffffe0000000000, 0x0001c00000000000, - 0x03ff03ff00000000, 0x000000000000ffc0, 0x0000000007ff0000, 0x0000000003ff03ff, - 0x03ff000000000000, 0x03f1000000000000, 0xffffffffffff0000, 0x00000000000003e7, - 0xffffffff00000000, 0x000000000fffffff, 0xfffffc0000000000, 0xffc0000000000000, - 0x00000000000fffff, 0x2000000000000000, 0x070003fe00000080, 0x00000000003c0000, - 0x000003ff00000000, 0x00000000fffeff00, 0xfffe0000000003ff, 0x003f000000000000, - 0x03ff000003ff0000 - ], - r4: [ - 0, 1, 2, 3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 5, 6, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 - ], - r5: &[ - 0, 0, 0, 0, 1, 2, 3, 0, 0, 0, 0, 4, 5, 6, 0, 7, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 9, 10, 11, 12, 0, 13, 14, 0, 15, 16, 17, 0, 18, 19, 0, 0, 0, 0, 20, 21, 0, - 0, 0, 0, 22, 0, 0, 23, 24, 0, 0, 0, 25, 0, 21, 26, 0, 0, 27, 0, 0, 0, 21, 0, 0, 0, 0, 0, - 28, 0, 28, 0, 0, 0, 0, 0, 28, 0, 29, 30, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 32, 0, 0, 0, 28, 8, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 34, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 39, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 21, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 28, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 42, 43, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0 - ], - r6: &[ - 0x0000000000000000, 0x000fffffffffff80, 0x01ffffffffffffff, 0x0000000000000c00, - 0x0ffffffe00000000, 0x0000000f00000000, 0x0000000000000402, 0x00000000003e0000, - 0x000003ff00000000, 0xfe000000ff000000, 0x0000ff8000000000, 0xf800000000000000, - 0x000000000fc00000, 0x3000000000000000, 0xfffffffffffcffff, 0x60000000000001ff, - 0x00000000e0000000, 0x0000f80000000000, 0xff000000ff000000, 0x0000fe0000000000, - 0xfc00000000000000, 0x03ff000000000000, 0x7fffffff00000000, 0x0000007fe0000000, - 0x00000000001e0000, 0x0000fffffffc0000, 0xffc0000000000000, 0x001ffffe03ff0000, - 0x0000000003ff0000, 0x00000000000003ff, 0x0fff000000000000, 0x0007ffff00000000, - 0x00001fffffff0000, 0x00000000001fffff, 0xffffffffffffffff, 0x00007fffffffffff, - 0x00000003fbff0000, 0x00000000007fffff, 0x000fffff00000000, 0x01ffffff00000000, - 0xffffffffffffc000, 0x000000000000ff80, 0xfffe000000000000, 0x001eefffffffffff, - 0x3fffbffffffffffe, 0x0000000000001fff - ], - }; - - pub fn N(c: char) -> bool { - N_table.lookup(c) - } -} - -pub(crate) mod derived_property { - #[rustfmt::skip] - const Alphabetic_table: &super::BoolTrie = &super::BoolTrie { - r1: [ - 0x0000000000000000, 0x07fffffe07fffffe, 0x0420040000000000, 0xff7fffffff7fffff, - 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, - 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x0000501f0003ffc3, - 0x0000000000000000, 0xbcdf000000000020, 0xfffffffbffffd740, 0xffbfffffffffffff, - 0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffffffffc03, 0xffffffffffffffff, - 0xfffeffffffffffff, 0xffffffff027fffff, 0xbfff0000000001ff, 0x000787ffffff00b6, - 0xffffffff07ff0000, 0xffffc000feffffff, 0xffffffffffffffff, 0x9c00e1fe1fefffff, - 0xffffffffffff0000, 0xffffffffffffe000, 0x0003ffffffffffff, 0x043007fffffffc00 - ], - r2: [ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 36, 36, 36, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 36, 36, 36, 36, 36, 36, 36, 36, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 31, 63, 64, 65, 66, 67, 68, 69, 70, 36, 36, 36, 71, 36, 36, - 36, 36, 72, 73, 74, 75, 31, 76, 77, 31, 78, 79, 80, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 81, 82, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 83, 84, 36, 85, 86, 87, 88, 89, 90, 31, 31, 31, - 31, 31, 31, 31, 91, 44, 92, 93, 94, 36, 95, 96, 31, 31, 31, 31, 31, 31, 31, 31, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 55, 31, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 97, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 98, 99, 36, 36, 36, 36, 100, 101, 36, 97, 102, 36, 103, - 104, 105, 106, 36, 107, 108, 109, 110, 111, 67, 112, 113, 114, 115, 116, 36, 117, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 118, 119, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 36, 36, 36, 36, 36, 120, 36, 121, 122, 123, 124, 125, 36, 36, 36, 36, 126, 33, 127, 128, - 31, 129, 36, 130, 131, 132, 113, 133 - ], - r3: &[ - 0x00001ffffcffffff, 0x000007ff01ffffff, 0x3fdfffff00000000, 0xffff03f8fff00000, - 0xefffffffffffffff, 0xfffe000fffe1dfff, 0xe3c5fdfffff99fef, 0x1003000fb080599f, - 0xc36dfdfffff987ee, 0x003f00005e021987, 0xe3edfdfffffbbfee, 0x1e00000f00011bbf, - 0xe3edfdfffff99fee, 0x0002000fb0c0199f, 0xc3ffc718d63dc7ec, 0x0000000000811dc7, - 0xe3fffdfffffddfef, 0x0000000f07601ddf, 0xe3effdfffffddfef, 0x0006000f40601ddf, - 0xe7fffffffffddfef, 0xfc00000f80f05ddf, 0x2ffbfffffc7fffec, 0x000c0000ff5f807f, - 0x07fffffffffffffe, 0x000000000000207f, 0x3bffffaffffff7d6, 0x00000000f000205f, - 0x0000000000000001, 0xfffe1ffffffffeff, 0x1ffffffffeffff03, 0x0000000000000000, - 0xf97fffffffffffff, 0xffffffffffff0000, 0xffffffff3c00ffff, 0xf7ffffffffff20bf, - 0xffffffffffffffff, 0xffffffff3d7f3dff, 0x7f3dffffffff3dff, 0xffffffffff7fff3d, - 0xffffffffff3dffff, 0x0000000007ffffff, 0xffffffff0000ffff, 0x3f3fffffffffffff, - 0xfffffffffffffffe, 0xffff9fffffffffff, 0xffffffff07fffffe, 0x01ffc7ffffffffff, - 0x000fffff000fdfff, 0x000ddfff000fffff, 0xffcfffffffffffff, 0x00000000108001ff, - 0xffffffff00000000, 0x01ffffffffffffff, 0xffff07ffffffffff, 0x003fffffffffffff, - 0x01ff0fff7fffffff, 0x001f3fffffff0000, 0xffff0fffffffffff, 0x00000000000003ff, - 0xffffffff0fffffff, 0x001ffffe7fffffff, 0x0000008000000000, 0xffefffffffffffff, - 0x0000000000000fef, 0xfc00f3ffffffffff, 0x0003ffbfffffffff, 0x007fffffffffffff, - 0x3ffffffffc00e000, 0xe7ffffffffff01ff, 0x046fde0000000000, 0x001fff8000000000, - 0xffffffff3f3fffff, 0x3fffffffaaff3f3f, 0x5fdfffffffffffff, 0x1fdc1fff0fcf1fdc, - 0x8002000000000000, 0x000000001fff0000, 0xf3ffbd503e2ffc84, 0xffffffff000043e0, - 0x00000000000001ff, 0xffc0000000000000, 0x000003ffffffffff, 0xffff7fffffffffff, - 0xffffffff7fffffff, 0x000c781fffffffff, 0xffff20bfffffffff, 0x000080ffffffffff, - 0x7f7f7f7f007fffff, 0xffffffff7f7f7f7f, 0x0000800000000000, 0x1f3e03fe000000e0, - 0xfffffffee07fffff, 0xf7ffffffffffffff, 0xfffeffffffffffe0, 0x07ffffff00007fff, - 0xffff000000000000, 0x0000ffffffffffff, 0x0000000000001fff, 0x3fffffffffff0000, - 0x00000c00ffff1fff, 0x8ff07fffffffffff, 0xfffffffcff800000, 0xfffffffffffff9ff, - 0xff8000000000007c, 0x000000ffffffffbf, 0x000fffffffffffff, 0xe8fc00000000002f, - 0xffff07fffffffc00, 0x1fffffff0007ffff, 0xfff7ffffffffffff, 0x7c00ffff00008000, - 0xfc7fffff00003fff, 0x7fffffffffffffff, 0x003cffff38000005, 0xffff7f7f007e7e7e, - 0xffff00fff7ffffff, 0x000007ffffffffff, 0xffff000fffffffff, 0x0ffffffffffff87f, - 0xffff3fffffffffff, 0x0000000003ffffff, 0x5f7ffdffe0f8007f, 0xffffffffffffffdb, - 0x0003ffffffffffff, 0xfffffffffff80000, 0x3fffffffffffffff, 0xfffffffffffcffff, - 0x0fff0000000000ff, 0xffdf000000000000, 0x1fffffffffffffff, 0x07fffffe00000000, - 0xffffffc007fffffe, 0x000000001cfcfcfc - ], - r4: [ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 5, 9, 5, 10, 11, 12, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 13, 14, - 15, 7, 16, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 - ], - r5: &[ - 0, 1, 2, 3, 4, 5, 4, 4, 4, 4, 6, 7, 8, 9, 10, 11, 2, 2, 12, 13, 14, 15, 4, 4, 2, 2, 2, - 2, 16, 17, 4, 4, 18, 19, 20, 21, 22, 4, 23, 4, 24, 25, 26, 27, 28, 29, 30, 4, 2, 31, 32, - 32, 33, 4, 4, 4, 4, 4, 4, 4, 34, 35, 4, 36, 2, 35, 37, 38, 32, 39, 2, 40, 41, 4, 42, 43, - 44, 45, 4, 4, 2, 46, 2, 47, 4, 4, 48, 49, 50, 51, 52, 4, 53, 4, 4, 4, 54, 4, 55, 56, 4, - 4, 57, 58, 59, 60, 61, 54, 4, 4, 4, 4, 62, 63, 64, 4, 65, 66, 67, 4, 4, 4, 4, 36, 4, 4, - 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 68, 4, 2, 69, 2, 2, 2, 70, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 69, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 71, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 2, 2, 2, 2, 2, 2, 2, 2, 54, 20, 4, 72, 73, 74, 75, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, - 4, 4, 2, 76, 77, 78, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 79, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 32, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 20, 80, 2, 2, 2, 2, - 2, 81, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 82, 83, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 84, 85, 86, 87, 88, 2, 2, 2, 2, 89, 90, 91, 92, - 93, 94, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 95, 4, 4, 4, 96, 97, 4, 4, 4, 4, 4, 98, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 99, 2, 100, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 101, 102, 103, 4, 4, 4, 4, 4, 4, 4, 4, 4, 104, 105, 106, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 107, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, - 2, 2, 2, 10, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 108, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 109, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, - 110, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 - ], - r6: &[ - 0xb7ffff7fffffefff, 0x000000003fff3fff, 0xffffffffffffffff, 0x07ffffffffffffff, - 0x0000000000000000, 0x001fffffffffffff, 0xffffffff1fffffff, 0x000000000001ffff, - 0xffffe000ffffffff, 0x07ffffffffff07ff, 0xffffffff3fffffff, 0x00000000003eff0f, - 0xffff00003fffffff, 0x0fffffffff0fffff, 0xffff00ffffffffff, 0x0000000fffffffff, - 0x007fffffffffffff, 0x000000ff003fffff, 0x91bffffffffffd3f, 0x007fffff003fffff, - 0x000000007fffffff, 0x0037ffff00000000, 0x03ffffff003fffff, 0xc0ffffffffffffff, - 0x003ffffffeeff06f, 0x1fffffff00000000, 0x000000001fffffff, 0x0000001ffffffeff, - 0x003fffffffffffff, 0x0007ffff003fffff, 0x000000000003ffff, 0x00000000000001ff, - 0x0007ffffffffffff, 0x000000ffffffffff, 0xffff00801fffffff, 0x000000000000003f, - 0x007fffff00000000, 0x01fffffffffffffc, 0x000001ffffff0000, 0x0047ffffffff0070, - 0x000000001400001e, 0x409ffffffffbffff, 0xffff01ffbfffbd7f, 0x000001ffffffffff, - 0xe3edfdfffff99fef, 0x0000000fe081199f, 0x00000000800007bb, 0x00000000000000b3, - 0x7f3fffffffffffff, 0x000000003f000000, 0x7fffffffffffffff, 0x0000000000000011, - 0x013fffffffffffff, 0x000007ffe7ffffff, 0x01ffffffffffffff, 0xffffffff00000000, - 0x80000000ffffffff, 0xfffffcff00000000, 0x0000001afcffffff, 0x7fe7ffffffffffff, - 0xffffffffffff0000, 0x0000000020ffffff, 0x7f7ffffffffffdff, 0xfffc000000000001, - 0x007ffefffffcffff, 0xb47ffffffffffb7f, 0xfffffdbf000000cb, 0x00000000017b7fff, - 0x0000000003ffffff, 0x00007fffffffffff, 0x000000000000000f, 0x000000000000007f, - 0x00003fffffff0000, 0x0000ffffffffffff, 0xe0fffff80000000f, 0x000000000000ffff, - 0xffffffffffff87ff, 0x00000000ffff80ff, 0x0000000b00000000, 0x00ffffffffffffff, - 0xffff00f000070000, 0x0fffffffffffffff, 0x1fff07ffffffffff, 0x0000000043ff01ff, - 0xffffffffffdfffff, 0xebffde64dfffffff, 0xffffffffffffffef, 0x7bffffffdfdfe7bf, - 0xfffffffffffdfc5f, 0xffffff3fffffffff, 0xf7fffffff7fffffd, 0xffdfffffffdfffff, - 0xffff7fffffff7fff, 0xfffffdfffffffdff, 0x0000000000000ff7, 0x000007dbf9ffff7f, - 0x3f801fffffffffff, 0x0000000000004000, 0x00000fffffffffff, 0x000000000000001f, - 0x000000000000088f, 0x0af7fe96ffffffef, 0x5ef7f796aa96ea84, 0x0ffffbee0ffffbff, - 0xffff000000000000, 0xffff03ffffff03ff, 0x00000000000003ff, 0x00000000007fffff, - 0xffff0003ffffffff, 0x00000001ffffffff, 0x000000003fffffff - ], - }; - - pub fn Alphabetic(c: char) -> bool { - Alphabetic_table.lookup(c) - } - - #[rustfmt::skip] - const Case_Ignorable_table: &super::BoolTrie = &super::BoolTrie { - r1: [ - 0x0400408000000000, 0x0000000140000000, 0x0190a10000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0xffff000000000000, 0xffffffffffffffff, - 0xffffffffffffffff, 0x0430ffffffffffff, 0x00000000000000b0, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x00000000000003f8, 0x0000000000000000, - 0x0000000000000000, 0x0000000002000000, 0xbffffffffffe0000, 0x00100000000000b6, - 0x0000000017ff003f, 0x00010000fffff801, 0x0000000000000000, 0x00003dffbfc00000, - 0xffff000000028000, 0x00000000000007ff, 0x0001ffc000000000, 0x243ff80000000000 - ], - r2: [ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 10, 11, 12, 13, 14, 15, 16, 11, 17, 18, 19, 2, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 2, 2, 2, 2, 2, 2, 2, 2, 2, 33, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 34, 35, 36, 37, 38, 39, 40, 2, 41, 2, 2, 2, 42, 43, 44, 2, - 45, 46, 47, 48, 49, 50, 2, 51, 52, 53, 54, 55, 2, 2, 2, 2, 2, 2, 56, 57, 58, 59, 60, 61, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 62, 2, 63, 2, 64, 2, 65, 66, 2, 2, 2, 2, - 2, 2, 2, 67, 2, 68, 69, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 70, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 50, 2, 2, 2, 2, 71, 72, 73, 74, 75, 76, 77, 78, 79, 2, 2, 80, 81, - 82, 83, 84, 85, 86, 87, 88, 2, 89, 2, 90, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 91, 2, 92, 93, 2, 2, 2, 2, 2, 2, 2, 2, 94, 95, 2, 96, - 97, 98, 99, 100 - ], - r3: &[ - 0x00003fffffc00000, 0x000000000e000000, 0x0000000000000000, 0xfffffffffff80000, - 0x1400000000000007, 0x0002000c00fe21fe, 0x1000000000000002, 0x4000000c0000201e, - 0x1000000000000006, 0x0023000000023986, 0xfc00000c000021be, 0x9000000000000002, - 0x0000000c0040201e, 0x0000000000000004, 0x0000000000002001, 0xc000000000000011, - 0x0000000c00603dc1, 0x0000000c00003040, 0x1800000000000003, 0x0000000c0000201e, - 0x00000000005c0400, 0x07f2000000000000, 0x0000000000007fc0, 0x1ff2000000000000, - 0x0000000000003f40, 0x02a0000003000000, 0x7ffe000000000000, 0x1ffffffffeffe0df, - 0x0000000000000040, 0x66fde00000000000, 0x001e0001c3000000, 0x0000000020002064, - 0x1000000000000000, 0x00000000e0000000, 0x001c0000001c0000, 0x000c0000000c0000, - 0x3fb0000000000000, 0x00000000208ffe40, 0x0000000000007800, 0x0000000000000008, - 0x0000020000000060, 0x0e04018700000000, 0x0000000009800000, 0x9ff81fe57f400000, - 0x7fff008000000000, 0x17d000000000000f, 0x000ff80000000004, 0x00003b3c00000003, - 0x0003a34000000000, 0x00cff00000000000, 0x3f00000000000000, 0x031021fdfff70000, - 0xfffff00000000000, 0x010007ffffffffff, 0xfffffffff8000000, 0xfbffffffffffffff, - 0xa000000000000000, 0x6000e000e000e003, 0x00007c900300f800, 0x8002ffdf00000000, - 0x000000001fff0000, 0x0001ffffffff0000, 0x3000000000000000, 0x0003800000000000, - 0x8000800000000000, 0xffffffff00000000, 0x0000800000000000, 0x083e3c0000000020, - 0x000000007e000000, 0x7000000000000000, 0x0000000000200000, 0x0000000000001000, - 0xbff7800000000000, 0x00000000f0000000, 0x0003000000000000, 0x00000003ffffffff, - 0x0001000000000000, 0x0000000000000700, 0x0300000000000000, 0x0000006000000844, - 0x8003ffff00000030, 0x00003fc000000000, 0x000000000003ff80, 0x33c8000000000007, - 0x0000006000008000, 0x00667e0000000000, 0x1001000000001008, 0xc19d000000000000, - 0x0058300020000002, 0x00000000f8000000, 0x0000212000000000, 0x0000000040000000, - 0xfffc000000000000, 0x0000000000000003, 0x0000ffff0008ffff, 0x0000000000240000, - 0x8000000000000000, 0x4000000004004080, 0x0001000000000001, 0x00000000c0000000, - 0x0e00000800000000 - ], - r4: [ - 0, 1, 2, 3, 2, 2, 4, 2, 2, 2, 2, 5, 2, 6, 7, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 9, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 - ], - r5: &[ - 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, - 0, 0, 0, 7, 0, 0, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 0, 17, 18, 19, 0, 0, 20, 21, 22, - 23, 0, 0, 24, 25, 26, 27, 28, 0, 29, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 31, 32, 33, 34, 0, - 0, 0, 0, 0, 35, 0, 36, 0, 37, 38, 39, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 43, 44, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 46, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 50, 0, 0, - 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 52, 53, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 0, - 0, 0, 56, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 58, 0, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61, 62, 0, 0, 62, 62, 62, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ], - r6: &[ - 0x0000000000000000, 0x2000000000000000, 0x0000000100000000, 0x07c0000000000000, - 0x870000000000f06e, 0x0000006000000000, 0x000000f000000000, 0x000000000001ffc0, - 0xff00000000000002, 0x800000000000007f, 0x2678000000000003, 0x0000000000002000, - 0x001fef8000000007, 0x0008000000000000, 0x7fc0000000000003, 0x0000000000001e00, - 0x40d3800000000000, 0x000007f880000000, 0x1800000000000003, 0x001f1fc000000001, - 0xff00000000000000, 0x000000004000005c, 0x85f8000000000000, 0x000000000000000d, - 0xb03c000000000000, 0x0000000030000001, 0xa7f8000000000000, 0x0000000000000001, - 0x00bf280000000000, 0x00000fbce0000000, 0x06ff800000000000, 0x000000010cf00000, - 0x79f80000000007fe, 0x000000000e7e0080, 0x00000000037ffc00, 0xbf7f000000000000, - 0x006dfcfffffc0000, 0xb47e000000000000, 0x00000000000000bf, 0x0000000000a30000, - 0x0018000000000000, 0x01ff000000000000, 0x001f000000000000, 0x007f000000000000, - 0x000000000000000f, 0x0000000000008000, 0x00000000ffff8000, 0x0000000b00000000, - 0x0000000f60000000, 0xfff8038000000000, 0x00003c0000000fe7, 0x000000000000001c, - 0xf87fffffffffffff, 0x00201fffffffffff, 0x0000fffef8000010, 0x000007dbf9ffff7f, - 0x3fff000000000000, 0x0000f00000000000, 0x00000000007f0000, 0x0000000000000ff0, - 0xf800000000000000, 0xffffffff00000002, 0xffffffffffffffff, 0x0000ffffffffffff - ], - }; - - pub fn Case_Ignorable(c: char) -> bool { - Case_Ignorable_table.lookup(c) - } - - #[rustfmt::skip] - const Cased_table: &super::BoolTrie = &super::BoolTrie { - r1: [ - 0x0000000000000000, 0x07fffffe07fffffe, 0x0420040000000000, 0xff7fffffff7fffff, - 0xffffffffffffffff, 0xffffffffffffffff, 0xf7ffffffffffffff, 0xfffffffffffffff0, - 0xffffffffffffffff, 0xffffffffffffffff, 0x01ffffffffefffff, 0x0000001f00000003, - 0x0000000000000000, 0xbccf000000000020, 0xfffffffbffffd740, 0xffbfffffffffffff, - 0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffffffffc03, 0xffffffffffffffff, - 0xfffeffffffffffff, 0xffffffff007fffff, 0x00000000000001ff, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 - ], - r2: [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 5, 5, 5, - 0, 5, 5, 5, 5, 6, 7, 8, 9, 0, 10, 11, 0, 12, 13, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 17, 18, 5, 19, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 22, - 0, 23, 5, 24, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 27, 5, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 29, 30, 0, 0 - ], - r3: &[ - 0x0000000000000000, 0xffffffff00000000, 0xe7ffffffffff20bf, 0x3f3fffffffffffff, - 0xe7ffffffffff01ff, 0xffffffffffffffff, 0xffffffff3f3fffff, 0x3fffffffaaff3f3f, - 0x5fdfffffffffffff, 0x1fdc1fff0fcf1fdc, 0x8002000000000000, 0x000000001fff0000, - 0xf21fbd503e2ffc84, 0xffffffff000043e0, 0x0000000000000018, 0xffc0000000000000, - 0x000003ffffffffff, 0xffff7fffffffffff, 0xffffffff7fffffff, 0x000c781fffffffff, - 0x000020bfffffffff, 0x00003fffffffffff, 0x000000003fffffff, 0xfffffffc00000000, - 0xffffffffffff78ff, 0x070000000000007c, 0xffff000000000000, 0xffff00fff7ffffff, - 0x0000000000f8007f, 0x07fffffe00000000, 0x0000000007fffffe - ], - r4: [ - 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 4, 5, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 - ], - r5: &[ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 8, 9, 10, 11, 12, 1, 1, 1, 1, 13, 14, 15, 16, 17, - 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 20, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ], - r6: &[ - 0x0000000000000000, 0xffffffffffffffff, 0x000000000000ffff, 0xffff000000000000, - 0x0fffffffff0fffff, 0x0007ffffffffffff, 0xffffffff00000000, 0x00000000ffffffff, - 0xffffffffffdfffff, 0xebffde64dfffffff, 0xffffffffffffffef, 0x7bffffffdfdfe7bf, - 0xfffffffffffdfc5f, 0xffffff3fffffffff, 0xf7fffffff7fffffd, 0xffdfffffffdfffff, - 0xffff7fffffff7fff, 0xfffffdfffffffdff, 0x0000000000000ff7, 0x000000000000000f, - 0xffff03ffffff03ff, 0x00000000000003ff - ], - }; - - pub fn Cased(c: char) -> bool { - Cased_table.lookup(c) - } - - #[rustfmt::skip] - const Grapheme_Extend_table: &super::BoolTrie = &super::BoolTrie { - r1: [ - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0xffffffffffffffff, 0x0000ffffffffffff, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x00000000000003f8, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0xbffffffffffe0000, 0x00000000000000b6, - 0x0000000007ff0000, 0x00010000fffff800, 0x0000000000000000, 0x00003d9f9fc00000, - 0xffff000000020000, 0x00000000000007ff, 0x0001ffc000000000, 0x200ff80000000000 - ], - r2: [ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 2, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 33, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 34, 35, 36, 37, 38, 2, 39, 2, 40, 2, 2, 2, 41, 42, 43, 2, 44, - 45, 46, 47, 48, 2, 2, 49, 2, 2, 2, 50, 2, 2, 2, 2, 2, 2, 2, 2, 51, 2, 2, 52, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 53, 2, 54, 2, 55, 2, 2, 2, 2, 2, 2, 2, 2, 56, - 2, 57, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 58, 59, 60, 2, 2, 2, 2, 61, 2, 2, 62, 63, 64, 65, 66, 67, 68, - 69, 70, 2, 2, 2, 71, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 72, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 73, 2, 2, 2, 2, 2, 59, 2 - ], - r3: &[ - 0x00003eeffbc00000, 0x000000000e000000, 0x0000000000000000, 0xfffffffbfff80000, - 0x1400000000000007, 0x0000000c00fe21fe, 0x5000000000000002, 0x4000000c0080201e, - 0x1000000000000006, 0x0023000000023986, 0xfc00000c000021be, 0xd000000000000002, - 0x0000000c00c0201e, 0x4000000000000004, 0x0000000000802001, 0xc000000000000011, - 0x0000000c00603dc1, 0x9000000000000002, 0x0000000c00603044, 0x5800000000000003, - 0x0000000c0080201e, 0x00000000805c8400, 0x07f2000000000000, 0x0000000000007f80, - 0x1ff2000000000000, 0x0000000000003f00, 0x02a0000003000000, 0x7ffe000000000000, - 0x1ffffffffeffe0df, 0x0000000000000040, 0x66fde00000000000, 0x001e0001c3000000, - 0x0000000020002064, 0x00000000e0000000, 0x001c0000001c0000, 0x000c0000000c0000, - 0x3fb0000000000000, 0x00000000200ffe40, 0x0000000000003800, 0x0000020000000060, - 0x0e04018700000000, 0x0000000009800000, 0x9ff81fe57f400000, 0x7fff000000000000, - 0x17f000000000000f, 0x000ff80000000004, 0x00003b3c00000003, 0x0003a34000000000, - 0x00cff00000000000, 0x031021fdfff70000, 0xfbffffffffffffff, 0x0000000000001000, - 0x0001ffffffff0000, 0x0003800000000000, 0x8000000000000000, 0xffffffff00000000, - 0x0000fc0000000000, 0x0000000006000000, 0x3ff7800000000000, 0x00000000c0000000, - 0x0003000000000000, 0x0000006000000844, 0x8003ffff00000030, 0x00003fc000000000, - 0x000000000003ff80, 0x33c8000000000007, 0x0000002000000000, 0x00667e0000000000, - 0x1000000000001008, 0xc19d000000000000, 0x0040300000000002, 0x0000212000000000, - 0x0000000040000000, 0x0000ffff0000ffff - ], - r4: [ - 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 4, 2, 5, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 - ], - r5: &[ - 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, - 0, 0, 0, 7, 0, 0, 8, 9, 10, 0, 11, 12, 13, 14, 15, 0, 0, 16, 17, 18, 0, 0, 19, 20, 21, - 22, 0, 0, 23, 24, 25, 26, 27, 0, 28, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 30, 31, 32, 33, 0, - 0, 0, 0, 0, 34, 0, 35, 0, 36, 37, 38, 0, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 42, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 46, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 49, 50, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, 0, 41, 0, 0, 0, 0, 0, - 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 0, 54, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 56, 0, - 0, 56, 56, 56, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0 - ], - r6: &[ - 0x0000000000000000, 0x2000000000000000, 0x0000000100000000, 0x07c0000000000000, - 0x870000000000f06e, 0x0000006000000000, 0x000000f000000000, 0x000000000001ffc0, - 0xff00000000000002, 0x800000000000007f, 0x0678000000000003, 0x001fef8000000007, - 0x0008000000000000, 0x7fc0000000000003, 0x0000000000001e00, 0x40d3800000000000, - 0x000007f880000000, 0x5800000000000003, 0x001f1fc000800001, 0xff00000000000000, - 0x000000004000005c, 0xa5f9000000000000, 0x000000000000000d, 0xb03c800000000000, - 0x0000000030000001, 0xa7f8000000000000, 0x0000000000000001, 0x00bf280000000000, - 0x00000fbce0000000, 0x06ff800000000000, 0x000000010cf00000, 0x79f80000000007fe, - 0x000000000e7e0080, 0x00000000037ffc00, 0xbf7f000000000000, 0x006dfcfffffc0000, - 0xb47e000000000000, 0x00000000000000bf, 0x0000000000a30000, 0x0018000000000000, - 0x001f000000000000, 0x007f000000000000, 0x0000000000008000, 0x0000000000078000, - 0x0000000060000000, 0xf807c3a000000000, 0x00003c0000000fe7, 0x000000000000001c, - 0xf87fffffffffffff, 0x00201fffffffffff, 0x0000fffef8000010, 0x000007dbf9ffff7f, - 0x0000f00000000000, 0x00000000007f0000, 0x00000000000007f0, 0xffffffff00000000, - 0xffffffffffffffff, 0x0000ffffffffffff - ], - }; - - pub fn Grapheme_Extend(c: char) -> bool { - Grapheme_Extend_table.lookup(c) - } - - #[rustfmt::skip] - const Lowercase_table: &super::BoolTrie = &super::BoolTrie { - r1: [ - 0x0000000000000000, 0x07fffffe00000000, 0x0420040000000000, 0xff7fffff80000000, - 0x55aaaaaaaaaaaaaa, 0xd4aaaaaaaaaaab55, 0xe6512d2a4e243129, 0xaa29aaaab5555240, - 0x93faaaaaaaaaaaaa, 0xffffffffffffaa85, 0x01ffffffffefffff, 0x0000001f00000003, - 0x0000000000000000, 0x3c8a000000000020, 0xfffff00000010000, 0x192faaaaaae37fff, - 0xffff000000000000, 0xaaaaaaaaffffffff, 0xaaaaaaaaaaaaa802, 0xaaaaaaaaaaaad554, - 0x0000aaaaaaaaaaaa, 0xffffffff00000000, 0x00000000000001ff, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 - ], - r2: [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 4, 4, 4, - 0, 5, 5, 6, 5, 7, 8, 9, 10, 0, 11, 12, 0, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 17, 18, 5, 19, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 22, - 0, 23, 24, 25, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 27, 4, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0 - ], - r3: &[ - 0x0000000000000000, 0xe7ffffffffff0000, 0x3f00000000000000, 0x00000000000001ff, - 0xffffffffffffffff, 0xaaaaaaaaaaaaaaaa, 0xaaaaaaaabfeaaaaa, 0x00ff00ff003f00ff, - 0x3fff00ff00ff003f, 0x40df00ff00ff00ff, 0x00dc00ff00cf00dc, 0x8002000000000000, - 0x000000001fff0000, 0x321080000008c400, 0xffff0000000043c0, 0x0000000000000010, - 0x000003ffffff0000, 0xffff000000000000, 0x3fda15627fffffff, 0x0008501aaaaaaaaa, - 0x000020bfffffffff, 0x00002aaaaaaaaaaa, 0x000000003aaaaaaa, 0xaaabaaa800000000, - 0x95ffaaaaaaaaaaaa, 0xaaa082aaaaba50aa, 0x0700000000000008, 0xffff00fff7ffffff, - 0x0000000000f8007f, 0x0000000007fffffe - ], - r4: [ - 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 4, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 - ], - r5: &[ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ], - r6: &[ - 0x0000000000000000, 0xffffff0000000000, 0x000000000000ffff, 0x0fffffffff000000, - 0x0007ffffffffffff, 0x00000000ffffffff, 0xffffffff00000000, 0x000ffffffc000000, - 0x000000ffffdfc000, 0xebc000000ffffffc, 0xfffffc000000ffef, 0x00ffffffc000000f, - 0x00000ffffffc0000, 0xfc000000ffffffc0, 0xffffc000000fffff, 0x0ffffffc000000ff, - 0x0000ffffffc00000, 0x0000003ffffffc00, 0xf0000003f7fffffc, 0xffc000000fdfffff, - 0xffff0000003f7fff, 0xfffffc000000fdff, 0x0000000000000bf7, 0xfffffffc00000000, - 0x000000000000000f - ], - }; - - pub fn Lowercase(c: char) -> bool { - Lowercase_table.lookup(c) - } - - #[rustfmt::skip] - const Uppercase_table: &super::BoolTrie = &super::BoolTrie { - r1: [ - 0x0000000000000000, 0x0000000007fffffe, 0x0000000000000000, 0x000000007f7fffff, - 0xaa55555555555555, 0x2b555555555554aa, 0x11aed2d5b1dbced6, 0x55d255554aaaa490, - 0x6c05555555555555, 0x000000000000557a, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x8045000000000000, 0x00000ffbfffed740, 0xe6905555551c8000, - 0x0000ffffffffffff, 0x5555555500000000, 0x5555555555555401, 0x5555555555552aab, - 0xfffe555555555555, 0x00000000007fffff, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, - 0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 - ], - r2: [ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, - 0, 5, 5, 6, 5, 7, 8, 9, 10, 0, 0, 0, 0, 11, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, - 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 16, 17, 5, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 20, 0, - 21, 22, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 25, 0, 0, 0 - ], - r3: &[ - 0x0000000000000000, 0xffffffff00000000, 0x00000000000020bf, 0x003fffffffffffff, - 0xe7ffffffffff0000, 0x5555555555555555, 0x5555555540155555, 0xff00ff003f00ff00, - 0x0000ff00aa003f00, 0x0f00000000000000, 0x0f001f000f000f00, 0xc00f3d503e273884, - 0x0000ffff00000020, 0x0000000000000008, 0xffc0000000000000, 0x000000000000ffff, - 0x00007fffffffffff, 0xc025ea9d00000000, 0x0004280555555555, 0x0000155555555555, - 0x0000000005555555, 0x5554555400000000, 0x6a00555555555555, 0x555f7d5555452855, - 0x0000000000000074, 0x07fffffe00000000 - ], - r4: [ - 0, 1, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 4, 5, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 - ], - r5: &[ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 24, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - ], - r6: &[ - 0x0000000000000000, 0x000000ffffffffff, 0xffff000000000000, 0x00000000000fffff, - 0x0007ffffffffffff, 0xffffffff00000000, 0x00000000ffffffff, 0xfff0000003ffffff, - 0xffffff0000003fff, 0x003fde64d0000003, 0x000003ffffff0000, 0x7b0000001fdfe7b0, - 0xfffff0000001fc5f, 0x03ffffff0000003f, 0x00003ffffff00000, 0xf0000003ffffff00, - 0xffff0000003fffff, 0xffffff00000003ff, 0x07fffffc00000001, 0x001ffffff0000000, - 0x00007fffffc00000, 0x000001ffffff0000, 0x0000000000000400, 0x00000003ffffffff, - 0xffff03ffffff03ff, 0x00000000000003ff - ], - }; - - pub fn Uppercase(c: char) -> bool { - Uppercase_table.lookup(c) - } -} - -pub(crate) mod property { - #[rustfmt::skip] - const White_Space_table: &super::SmallBoolTrie = &super::SmallBoolTrie { - r1: &[ - 0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3 - ], - r2: &[ - 0x0000000100003e00, 0x0000000000000000, 0x0000000100000020, 0x0000000000000001, - 0x00008300000007ff, 0x0000000080000000 - ], - }; - - pub fn White_Space(c: char) -> bool { - White_Space_table.lookup(c) - } -} - -pub(crate) mod conversions { - pub fn to_lower(c: char) -> [char; 3] { - match bsearch_case_table(c, to_lowercase_table) { - None => [c, '\0', '\0'], - Some(index) => to_lowercase_table[index].1, - } - } - - pub fn to_upper(c: char) -> [char; 3] { - match bsearch_case_table(c, to_uppercase_table) { - None => [c, '\0', '\0'], - Some(index) => to_uppercase_table[index].1, - } - } - - fn bsearch_case_table(c: char, table: &[(char, [char; 3])]) -> Option { - table.binary_search_by(|&(key, _)| key.cmp(&c)).ok() - } - - #[rustfmt::skip] - const to_lowercase_table: &[(char, [char; 3])] = &[ - ('\u{41}', ['\u{61}', '\0', '\0']), ('\u{42}', ['\u{62}', '\0', '\0']), ('\u{43}', - ['\u{63}', '\0', '\0']), ('\u{44}', ['\u{64}', '\0', '\0']), ('\u{45}', ['\u{65}', '\0', - '\0']), ('\u{46}', ['\u{66}', '\0', '\0']), ('\u{47}', ['\u{67}', '\0', '\0']), ('\u{48}', - ['\u{68}', '\0', '\0']), ('\u{49}', ['\u{69}', '\0', '\0']), ('\u{4a}', ['\u{6a}', '\0', - '\0']), ('\u{4b}', ['\u{6b}', '\0', '\0']), ('\u{4c}', ['\u{6c}', '\0', '\0']), ('\u{4d}', - ['\u{6d}', '\0', '\0']), ('\u{4e}', ['\u{6e}', '\0', '\0']), ('\u{4f}', ['\u{6f}', '\0', - '\0']), ('\u{50}', ['\u{70}', '\0', '\0']), ('\u{51}', ['\u{71}', '\0', '\0']), ('\u{52}', - ['\u{72}', '\0', '\0']), ('\u{53}', ['\u{73}', '\0', '\0']), ('\u{54}', ['\u{74}', '\0', - '\0']), ('\u{55}', ['\u{75}', '\0', '\0']), ('\u{56}', ['\u{76}', '\0', '\0']), ('\u{57}', - ['\u{77}', '\0', '\0']), ('\u{58}', ['\u{78}', '\0', '\0']), ('\u{59}', ['\u{79}', '\0', - '\0']), ('\u{5a}', ['\u{7a}', '\0', '\0']), ('\u{c0}', ['\u{e0}', '\0', '\0']), ('\u{c1}', - ['\u{e1}', '\0', '\0']), ('\u{c2}', ['\u{e2}', '\0', '\0']), ('\u{c3}', ['\u{e3}', '\0', - '\0']), ('\u{c4}', ['\u{e4}', '\0', '\0']), ('\u{c5}', ['\u{e5}', '\0', '\0']), ('\u{c6}', - ['\u{e6}', '\0', '\0']), ('\u{c7}', ['\u{e7}', '\0', '\0']), ('\u{c8}', ['\u{e8}', '\0', - '\0']), ('\u{c9}', ['\u{e9}', '\0', '\0']), ('\u{ca}', ['\u{ea}', '\0', '\0']), ('\u{cb}', - ['\u{eb}', '\0', '\0']), ('\u{cc}', ['\u{ec}', '\0', '\0']), ('\u{cd}', ['\u{ed}', '\0', - '\0']), ('\u{ce}', ['\u{ee}', '\0', '\0']), ('\u{cf}', ['\u{ef}', '\0', '\0']), ('\u{d0}', - ['\u{f0}', '\0', '\0']), ('\u{d1}', ['\u{f1}', '\0', '\0']), ('\u{d2}', ['\u{f2}', '\0', - '\0']), ('\u{d3}', ['\u{f3}', '\0', '\0']), ('\u{d4}', ['\u{f4}', '\0', '\0']), ('\u{d5}', - ['\u{f5}', '\0', '\0']), ('\u{d6}', ['\u{f6}', '\0', '\0']), ('\u{d8}', ['\u{f8}', '\0', - '\0']), ('\u{d9}', ['\u{f9}', '\0', '\0']), ('\u{da}', ['\u{fa}', '\0', '\0']), ('\u{db}', - ['\u{fb}', '\0', '\0']), ('\u{dc}', ['\u{fc}', '\0', '\0']), ('\u{dd}', ['\u{fd}', '\0', - '\0']), ('\u{de}', ['\u{fe}', '\0', '\0']), ('\u{100}', ['\u{101}', '\0', '\0']), - ('\u{102}', ['\u{103}', '\0', '\0']), ('\u{104}', ['\u{105}', '\0', '\0']), ('\u{106}', - ['\u{107}', '\0', '\0']), ('\u{108}', ['\u{109}', '\0', '\0']), ('\u{10a}', ['\u{10b}', - '\0', '\0']), ('\u{10c}', ['\u{10d}', '\0', '\0']), ('\u{10e}', ['\u{10f}', '\0', '\0']), - ('\u{110}', ['\u{111}', '\0', '\0']), ('\u{112}', ['\u{113}', '\0', '\0']), ('\u{114}', - ['\u{115}', '\0', '\0']), ('\u{116}', ['\u{117}', '\0', '\0']), ('\u{118}', ['\u{119}', - '\0', '\0']), ('\u{11a}', ['\u{11b}', '\0', '\0']), ('\u{11c}', ['\u{11d}', '\0', '\0']), - ('\u{11e}', ['\u{11f}', '\0', '\0']), ('\u{120}', ['\u{121}', '\0', '\0']), ('\u{122}', - ['\u{123}', '\0', '\0']), ('\u{124}', ['\u{125}', '\0', '\0']), ('\u{126}', ['\u{127}', - '\0', '\0']), ('\u{128}', ['\u{129}', '\0', '\0']), ('\u{12a}', ['\u{12b}', '\0', '\0']), - ('\u{12c}', ['\u{12d}', '\0', '\0']), ('\u{12e}', ['\u{12f}', '\0', '\0']), ('\u{130}', - ['\u{69}', '\u{307}', '\0']), ('\u{132}', ['\u{133}', '\0', '\0']), ('\u{134}', ['\u{135}', - '\0', '\0']), ('\u{136}', ['\u{137}', '\0', '\0']), ('\u{139}', ['\u{13a}', '\0', '\0']), - ('\u{13b}', ['\u{13c}', '\0', '\0']), ('\u{13d}', ['\u{13e}', '\0', '\0']), ('\u{13f}', - ['\u{140}', '\0', '\0']), ('\u{141}', ['\u{142}', '\0', '\0']), ('\u{143}', ['\u{144}', - '\0', '\0']), ('\u{145}', ['\u{146}', '\0', '\0']), ('\u{147}', ['\u{148}', '\0', '\0']), - ('\u{14a}', ['\u{14b}', '\0', '\0']), ('\u{14c}', ['\u{14d}', '\0', '\0']), ('\u{14e}', - ['\u{14f}', '\0', '\0']), ('\u{150}', ['\u{151}', '\0', '\0']), ('\u{152}', ['\u{153}', - '\0', '\0']), ('\u{154}', ['\u{155}', '\0', '\0']), ('\u{156}', ['\u{157}', '\0', '\0']), - ('\u{158}', ['\u{159}', '\0', '\0']), ('\u{15a}', ['\u{15b}', '\0', '\0']), ('\u{15c}', - ['\u{15d}', '\0', '\0']), ('\u{15e}', ['\u{15f}', '\0', '\0']), ('\u{160}', ['\u{161}', - '\0', '\0']), ('\u{162}', ['\u{163}', '\0', '\0']), ('\u{164}', ['\u{165}', '\0', '\0']), - ('\u{166}', ['\u{167}', '\0', '\0']), ('\u{168}', ['\u{169}', '\0', '\0']), ('\u{16a}', - ['\u{16b}', '\0', '\0']), ('\u{16c}', ['\u{16d}', '\0', '\0']), ('\u{16e}', ['\u{16f}', - '\0', '\0']), ('\u{170}', ['\u{171}', '\0', '\0']), ('\u{172}', ['\u{173}', '\0', '\0']), - ('\u{174}', ['\u{175}', '\0', '\0']), ('\u{176}', ['\u{177}', '\0', '\0']), ('\u{178}', - ['\u{ff}', '\0', '\0']), ('\u{179}', ['\u{17a}', '\0', '\0']), ('\u{17b}', ['\u{17c}', '\0', - '\0']), ('\u{17d}', ['\u{17e}', '\0', '\0']), ('\u{181}', ['\u{253}', '\0', '\0']), - ('\u{182}', ['\u{183}', '\0', '\0']), ('\u{184}', ['\u{185}', '\0', '\0']), ('\u{186}', - ['\u{254}', '\0', '\0']), ('\u{187}', ['\u{188}', '\0', '\0']), ('\u{189}', ['\u{256}', - '\0', '\0']), ('\u{18a}', ['\u{257}', '\0', '\0']), ('\u{18b}', ['\u{18c}', '\0', '\0']), - ('\u{18e}', ['\u{1dd}', '\0', '\0']), ('\u{18f}', ['\u{259}', '\0', '\0']), ('\u{190}', - ['\u{25b}', '\0', '\0']), ('\u{191}', ['\u{192}', '\0', '\0']), ('\u{193}', ['\u{260}', - '\0', '\0']), ('\u{194}', ['\u{263}', '\0', '\0']), ('\u{196}', ['\u{269}', '\0', '\0']), - ('\u{197}', ['\u{268}', '\0', '\0']), ('\u{198}', ['\u{199}', '\0', '\0']), ('\u{19c}', - ['\u{26f}', '\0', '\0']), ('\u{19d}', ['\u{272}', '\0', '\0']), ('\u{19f}', ['\u{275}', - '\0', '\0']), ('\u{1a0}', ['\u{1a1}', '\0', '\0']), ('\u{1a2}', ['\u{1a3}', '\0', '\0']), - ('\u{1a4}', ['\u{1a5}', '\0', '\0']), ('\u{1a6}', ['\u{280}', '\0', '\0']), ('\u{1a7}', - ['\u{1a8}', '\0', '\0']), ('\u{1a9}', ['\u{283}', '\0', '\0']), ('\u{1ac}', ['\u{1ad}', - '\0', '\0']), ('\u{1ae}', ['\u{288}', '\0', '\0']), ('\u{1af}', ['\u{1b0}', '\0', '\0']), - ('\u{1b1}', ['\u{28a}', '\0', '\0']), ('\u{1b2}', ['\u{28b}', '\0', '\0']), ('\u{1b3}', - ['\u{1b4}', '\0', '\0']), ('\u{1b5}', ['\u{1b6}', '\0', '\0']), ('\u{1b7}', ['\u{292}', - '\0', '\0']), ('\u{1b8}', ['\u{1b9}', '\0', '\0']), ('\u{1bc}', ['\u{1bd}', '\0', '\0']), - ('\u{1c4}', ['\u{1c6}', '\0', '\0']), ('\u{1c5}', ['\u{1c6}', '\0', '\0']), ('\u{1c7}', - ['\u{1c9}', '\0', '\0']), ('\u{1c8}', ['\u{1c9}', '\0', '\0']), ('\u{1ca}', ['\u{1cc}', - '\0', '\0']), ('\u{1cb}', ['\u{1cc}', '\0', '\0']), ('\u{1cd}', ['\u{1ce}', '\0', '\0']), - ('\u{1cf}', ['\u{1d0}', '\0', '\0']), ('\u{1d1}', ['\u{1d2}', '\0', '\0']), ('\u{1d3}', - ['\u{1d4}', '\0', '\0']), ('\u{1d5}', ['\u{1d6}', '\0', '\0']), ('\u{1d7}', ['\u{1d8}', - '\0', '\0']), ('\u{1d9}', ['\u{1da}', '\0', '\0']), ('\u{1db}', ['\u{1dc}', '\0', '\0']), - ('\u{1de}', ['\u{1df}', '\0', '\0']), ('\u{1e0}', ['\u{1e1}', '\0', '\0']), ('\u{1e2}', - ['\u{1e3}', '\0', '\0']), ('\u{1e4}', ['\u{1e5}', '\0', '\0']), ('\u{1e6}', ['\u{1e7}', - '\0', '\0']), ('\u{1e8}', ['\u{1e9}', '\0', '\0']), ('\u{1ea}', ['\u{1eb}', '\0', '\0']), - ('\u{1ec}', ['\u{1ed}', '\0', '\0']), ('\u{1ee}', ['\u{1ef}', '\0', '\0']), ('\u{1f1}', - ['\u{1f3}', '\0', '\0']), ('\u{1f2}', ['\u{1f3}', '\0', '\0']), ('\u{1f4}', ['\u{1f5}', - '\0', '\0']), ('\u{1f6}', ['\u{195}', '\0', '\0']), ('\u{1f7}', ['\u{1bf}', '\0', '\0']), - ('\u{1f8}', ['\u{1f9}', '\0', '\0']), ('\u{1fa}', ['\u{1fb}', '\0', '\0']), ('\u{1fc}', - ['\u{1fd}', '\0', '\0']), ('\u{1fe}', ['\u{1ff}', '\0', '\0']), ('\u{200}', ['\u{201}', - '\0', '\0']), ('\u{202}', ['\u{203}', '\0', '\0']), ('\u{204}', ['\u{205}', '\0', '\0']), - ('\u{206}', ['\u{207}', '\0', '\0']), ('\u{208}', ['\u{209}', '\0', '\0']), ('\u{20a}', - ['\u{20b}', '\0', '\0']), ('\u{20c}', ['\u{20d}', '\0', '\0']), ('\u{20e}', ['\u{20f}', - '\0', '\0']), ('\u{210}', ['\u{211}', '\0', '\0']), ('\u{212}', ['\u{213}', '\0', '\0']), - ('\u{214}', ['\u{215}', '\0', '\0']), ('\u{216}', ['\u{217}', '\0', '\0']), ('\u{218}', - ['\u{219}', '\0', '\0']), ('\u{21a}', ['\u{21b}', '\0', '\0']), ('\u{21c}', ['\u{21d}', - '\0', '\0']), ('\u{21e}', ['\u{21f}', '\0', '\0']), ('\u{220}', ['\u{19e}', '\0', '\0']), - ('\u{222}', ['\u{223}', '\0', '\0']), ('\u{224}', ['\u{225}', '\0', '\0']), ('\u{226}', - ['\u{227}', '\0', '\0']), ('\u{228}', ['\u{229}', '\0', '\0']), ('\u{22a}', ['\u{22b}', - '\0', '\0']), ('\u{22c}', ['\u{22d}', '\0', '\0']), ('\u{22e}', ['\u{22f}', '\0', '\0']), - ('\u{230}', ['\u{231}', '\0', '\0']), ('\u{232}', ['\u{233}', '\0', '\0']), ('\u{23a}', - ['\u{2c65}', '\0', '\0']), ('\u{23b}', ['\u{23c}', '\0', '\0']), ('\u{23d}', ['\u{19a}', - '\0', '\0']), ('\u{23e}', ['\u{2c66}', '\0', '\0']), ('\u{241}', ['\u{242}', '\0', '\0']), - ('\u{243}', ['\u{180}', '\0', '\0']), ('\u{244}', ['\u{289}', '\0', '\0']), ('\u{245}', - ['\u{28c}', '\0', '\0']), ('\u{246}', ['\u{247}', '\0', '\0']), ('\u{248}', ['\u{249}', - '\0', '\0']), ('\u{24a}', ['\u{24b}', '\0', '\0']), ('\u{24c}', ['\u{24d}', '\0', '\0']), - ('\u{24e}', ['\u{24f}', '\0', '\0']), ('\u{370}', ['\u{371}', '\0', '\0']), ('\u{372}', - ['\u{373}', '\0', '\0']), ('\u{376}', ['\u{377}', '\0', '\0']), ('\u{37f}', ['\u{3f3}', - '\0', '\0']), ('\u{386}', ['\u{3ac}', '\0', '\0']), ('\u{388}', ['\u{3ad}', '\0', '\0']), - ('\u{389}', ['\u{3ae}', '\0', '\0']), ('\u{38a}', ['\u{3af}', '\0', '\0']), ('\u{38c}', - ['\u{3cc}', '\0', '\0']), ('\u{38e}', ['\u{3cd}', '\0', '\0']), ('\u{38f}', ['\u{3ce}', - '\0', '\0']), ('\u{391}', ['\u{3b1}', '\0', '\0']), ('\u{392}', ['\u{3b2}', '\0', '\0']), - ('\u{393}', ['\u{3b3}', '\0', '\0']), ('\u{394}', ['\u{3b4}', '\0', '\0']), ('\u{395}', - ['\u{3b5}', '\0', '\0']), ('\u{396}', ['\u{3b6}', '\0', '\0']), ('\u{397}', ['\u{3b7}', - '\0', '\0']), ('\u{398}', ['\u{3b8}', '\0', '\0']), ('\u{399}', ['\u{3b9}', '\0', '\0']), - ('\u{39a}', ['\u{3ba}', '\0', '\0']), ('\u{39b}', ['\u{3bb}', '\0', '\0']), ('\u{39c}', - ['\u{3bc}', '\0', '\0']), ('\u{39d}', ['\u{3bd}', '\0', '\0']), ('\u{39e}', ['\u{3be}', - '\0', '\0']), ('\u{39f}', ['\u{3bf}', '\0', '\0']), ('\u{3a0}', ['\u{3c0}', '\0', '\0']), - ('\u{3a1}', ['\u{3c1}', '\0', '\0']), ('\u{3a3}', ['\u{3c3}', '\0', '\0']), ('\u{3a4}', - ['\u{3c4}', '\0', '\0']), ('\u{3a5}', ['\u{3c5}', '\0', '\0']), ('\u{3a6}', ['\u{3c6}', - '\0', '\0']), ('\u{3a7}', ['\u{3c7}', '\0', '\0']), ('\u{3a8}', ['\u{3c8}', '\0', '\0']), - ('\u{3a9}', ['\u{3c9}', '\0', '\0']), ('\u{3aa}', ['\u{3ca}', '\0', '\0']), ('\u{3ab}', - ['\u{3cb}', '\0', '\0']), ('\u{3cf}', ['\u{3d7}', '\0', '\0']), ('\u{3d8}', ['\u{3d9}', - '\0', '\0']), ('\u{3da}', ['\u{3db}', '\0', '\0']), ('\u{3dc}', ['\u{3dd}', '\0', '\0']), - ('\u{3de}', ['\u{3df}', '\0', '\0']), ('\u{3e0}', ['\u{3e1}', '\0', '\0']), ('\u{3e2}', - ['\u{3e3}', '\0', '\0']), ('\u{3e4}', ['\u{3e5}', '\0', '\0']), ('\u{3e6}', ['\u{3e7}', - '\0', '\0']), ('\u{3e8}', ['\u{3e9}', '\0', '\0']), ('\u{3ea}', ['\u{3eb}', '\0', '\0']), - ('\u{3ec}', ['\u{3ed}', '\0', '\0']), ('\u{3ee}', ['\u{3ef}', '\0', '\0']), ('\u{3f4}', - ['\u{3b8}', '\0', '\0']), ('\u{3f7}', ['\u{3f8}', '\0', '\0']), ('\u{3f9}', ['\u{3f2}', - '\0', '\0']), ('\u{3fa}', ['\u{3fb}', '\0', '\0']), ('\u{3fd}', ['\u{37b}', '\0', '\0']), - ('\u{3fe}', ['\u{37c}', '\0', '\0']), ('\u{3ff}', ['\u{37d}', '\0', '\0']), ('\u{400}', - ['\u{450}', '\0', '\0']), ('\u{401}', ['\u{451}', '\0', '\0']), ('\u{402}', ['\u{452}', - '\0', '\0']), ('\u{403}', ['\u{453}', '\0', '\0']), ('\u{404}', ['\u{454}', '\0', '\0']), - ('\u{405}', ['\u{455}', '\0', '\0']), ('\u{406}', ['\u{456}', '\0', '\0']), ('\u{407}', - ['\u{457}', '\0', '\0']), ('\u{408}', ['\u{458}', '\0', '\0']), ('\u{409}', ['\u{459}', - '\0', '\0']), ('\u{40a}', ['\u{45a}', '\0', '\0']), ('\u{40b}', ['\u{45b}', '\0', '\0']), - ('\u{40c}', ['\u{45c}', '\0', '\0']), ('\u{40d}', ['\u{45d}', '\0', '\0']), ('\u{40e}', - ['\u{45e}', '\0', '\0']), ('\u{40f}', ['\u{45f}', '\0', '\0']), ('\u{410}', ['\u{430}', - '\0', '\0']), ('\u{411}', ['\u{431}', '\0', '\0']), ('\u{412}', ['\u{432}', '\0', '\0']), - ('\u{413}', ['\u{433}', '\0', '\0']), ('\u{414}', ['\u{434}', '\0', '\0']), ('\u{415}', - ['\u{435}', '\0', '\0']), ('\u{416}', ['\u{436}', '\0', '\0']), ('\u{417}', ['\u{437}', - '\0', '\0']), ('\u{418}', ['\u{438}', '\0', '\0']), ('\u{419}', ['\u{439}', '\0', '\0']), - ('\u{41a}', ['\u{43a}', '\0', '\0']), ('\u{41b}', ['\u{43b}', '\0', '\0']), ('\u{41c}', - ['\u{43c}', '\0', '\0']), ('\u{41d}', ['\u{43d}', '\0', '\0']), ('\u{41e}', ['\u{43e}', - '\0', '\0']), ('\u{41f}', ['\u{43f}', '\0', '\0']), ('\u{420}', ['\u{440}', '\0', '\0']), - ('\u{421}', ['\u{441}', '\0', '\0']), ('\u{422}', ['\u{442}', '\0', '\0']), ('\u{423}', - ['\u{443}', '\0', '\0']), ('\u{424}', ['\u{444}', '\0', '\0']), ('\u{425}', ['\u{445}', - '\0', '\0']), ('\u{426}', ['\u{446}', '\0', '\0']), ('\u{427}', ['\u{447}', '\0', '\0']), - ('\u{428}', ['\u{448}', '\0', '\0']), ('\u{429}', ['\u{449}', '\0', '\0']), ('\u{42a}', - ['\u{44a}', '\0', '\0']), ('\u{42b}', ['\u{44b}', '\0', '\0']), ('\u{42c}', ['\u{44c}', - '\0', '\0']), ('\u{42d}', ['\u{44d}', '\0', '\0']), ('\u{42e}', ['\u{44e}', '\0', '\0']), - ('\u{42f}', ['\u{44f}', '\0', '\0']), ('\u{460}', ['\u{461}', '\0', '\0']), ('\u{462}', - ['\u{463}', '\0', '\0']), ('\u{464}', ['\u{465}', '\0', '\0']), ('\u{466}', ['\u{467}', - '\0', '\0']), ('\u{468}', ['\u{469}', '\0', '\0']), ('\u{46a}', ['\u{46b}', '\0', '\0']), - ('\u{46c}', ['\u{46d}', '\0', '\0']), ('\u{46e}', ['\u{46f}', '\0', '\0']), ('\u{470}', - ['\u{471}', '\0', '\0']), ('\u{472}', ['\u{473}', '\0', '\0']), ('\u{474}', ['\u{475}', - '\0', '\0']), ('\u{476}', ['\u{477}', '\0', '\0']), ('\u{478}', ['\u{479}', '\0', '\0']), - ('\u{47a}', ['\u{47b}', '\0', '\0']), ('\u{47c}', ['\u{47d}', '\0', '\0']), ('\u{47e}', - ['\u{47f}', '\0', '\0']), ('\u{480}', ['\u{481}', '\0', '\0']), ('\u{48a}', ['\u{48b}', - '\0', '\0']), ('\u{48c}', ['\u{48d}', '\0', '\0']), ('\u{48e}', ['\u{48f}', '\0', '\0']), - ('\u{490}', ['\u{491}', '\0', '\0']), ('\u{492}', ['\u{493}', '\0', '\0']), ('\u{494}', - ['\u{495}', '\0', '\0']), ('\u{496}', ['\u{497}', '\0', '\0']), ('\u{498}', ['\u{499}', - '\0', '\0']), ('\u{49a}', ['\u{49b}', '\0', '\0']), ('\u{49c}', ['\u{49d}', '\0', '\0']), - ('\u{49e}', ['\u{49f}', '\0', '\0']), ('\u{4a0}', ['\u{4a1}', '\0', '\0']), ('\u{4a2}', - ['\u{4a3}', '\0', '\0']), ('\u{4a4}', ['\u{4a5}', '\0', '\0']), ('\u{4a6}', ['\u{4a7}', - '\0', '\0']), ('\u{4a8}', ['\u{4a9}', '\0', '\0']), ('\u{4aa}', ['\u{4ab}', '\0', '\0']), - ('\u{4ac}', ['\u{4ad}', '\0', '\0']), ('\u{4ae}', ['\u{4af}', '\0', '\0']), ('\u{4b0}', - ['\u{4b1}', '\0', '\0']), ('\u{4b2}', ['\u{4b3}', '\0', '\0']), ('\u{4b4}', ['\u{4b5}', - '\0', '\0']), ('\u{4b6}', ['\u{4b7}', '\0', '\0']), ('\u{4b8}', ['\u{4b9}', '\0', '\0']), - ('\u{4ba}', ['\u{4bb}', '\0', '\0']), ('\u{4bc}', ['\u{4bd}', '\0', '\0']), ('\u{4be}', - ['\u{4bf}', '\0', '\0']), ('\u{4c0}', ['\u{4cf}', '\0', '\0']), ('\u{4c1}', ['\u{4c2}', - '\0', '\0']), ('\u{4c3}', ['\u{4c4}', '\0', '\0']), ('\u{4c5}', ['\u{4c6}', '\0', '\0']), - ('\u{4c7}', ['\u{4c8}', '\0', '\0']), ('\u{4c9}', ['\u{4ca}', '\0', '\0']), ('\u{4cb}', - ['\u{4cc}', '\0', '\0']), ('\u{4cd}', ['\u{4ce}', '\0', '\0']), ('\u{4d0}', ['\u{4d1}', - '\0', '\0']), ('\u{4d2}', ['\u{4d3}', '\0', '\0']), ('\u{4d4}', ['\u{4d5}', '\0', '\0']), - ('\u{4d6}', ['\u{4d7}', '\0', '\0']), ('\u{4d8}', ['\u{4d9}', '\0', '\0']), ('\u{4da}', - ['\u{4db}', '\0', '\0']), ('\u{4dc}', ['\u{4dd}', '\0', '\0']), ('\u{4de}', ['\u{4df}', - '\0', '\0']), ('\u{4e0}', ['\u{4e1}', '\0', '\0']), ('\u{4e2}', ['\u{4e3}', '\0', '\0']), - ('\u{4e4}', ['\u{4e5}', '\0', '\0']), ('\u{4e6}', ['\u{4e7}', '\0', '\0']), ('\u{4e8}', - ['\u{4e9}', '\0', '\0']), ('\u{4ea}', ['\u{4eb}', '\0', '\0']), ('\u{4ec}', ['\u{4ed}', - '\0', '\0']), ('\u{4ee}', ['\u{4ef}', '\0', '\0']), ('\u{4f0}', ['\u{4f1}', '\0', '\0']), - ('\u{4f2}', ['\u{4f3}', '\0', '\0']), ('\u{4f4}', ['\u{4f5}', '\0', '\0']), ('\u{4f6}', - ['\u{4f7}', '\0', '\0']), ('\u{4f8}', ['\u{4f9}', '\0', '\0']), ('\u{4fa}', ['\u{4fb}', - '\0', '\0']), ('\u{4fc}', ['\u{4fd}', '\0', '\0']), ('\u{4fe}', ['\u{4ff}', '\0', '\0']), - ('\u{500}', ['\u{501}', '\0', '\0']), ('\u{502}', ['\u{503}', '\0', '\0']), ('\u{504}', - ['\u{505}', '\0', '\0']), ('\u{506}', ['\u{507}', '\0', '\0']), ('\u{508}', ['\u{509}', - '\0', '\0']), ('\u{50a}', ['\u{50b}', '\0', '\0']), ('\u{50c}', ['\u{50d}', '\0', '\0']), - ('\u{50e}', ['\u{50f}', '\0', '\0']), ('\u{510}', ['\u{511}', '\0', '\0']), ('\u{512}', - ['\u{513}', '\0', '\0']), ('\u{514}', ['\u{515}', '\0', '\0']), ('\u{516}', ['\u{517}', - '\0', '\0']), ('\u{518}', ['\u{519}', '\0', '\0']), ('\u{51a}', ['\u{51b}', '\0', '\0']), - ('\u{51c}', ['\u{51d}', '\0', '\0']), ('\u{51e}', ['\u{51f}', '\0', '\0']), ('\u{520}', - ['\u{521}', '\0', '\0']), ('\u{522}', ['\u{523}', '\0', '\0']), ('\u{524}', ['\u{525}', - '\0', '\0']), ('\u{526}', ['\u{527}', '\0', '\0']), ('\u{528}', ['\u{529}', '\0', '\0']), - ('\u{52a}', ['\u{52b}', '\0', '\0']), ('\u{52c}', ['\u{52d}', '\0', '\0']), ('\u{52e}', - ['\u{52f}', '\0', '\0']), ('\u{531}', ['\u{561}', '\0', '\0']), ('\u{532}', ['\u{562}', - '\0', '\0']), ('\u{533}', ['\u{563}', '\0', '\0']), ('\u{534}', ['\u{564}', '\0', '\0']), - ('\u{535}', ['\u{565}', '\0', '\0']), ('\u{536}', ['\u{566}', '\0', '\0']), ('\u{537}', - ['\u{567}', '\0', '\0']), ('\u{538}', ['\u{568}', '\0', '\0']), ('\u{539}', ['\u{569}', - '\0', '\0']), ('\u{53a}', ['\u{56a}', '\0', '\0']), ('\u{53b}', ['\u{56b}', '\0', '\0']), - ('\u{53c}', ['\u{56c}', '\0', '\0']), ('\u{53d}', ['\u{56d}', '\0', '\0']), ('\u{53e}', - ['\u{56e}', '\0', '\0']), ('\u{53f}', ['\u{56f}', '\0', '\0']), ('\u{540}', ['\u{570}', - '\0', '\0']), ('\u{541}', ['\u{571}', '\0', '\0']), ('\u{542}', ['\u{572}', '\0', '\0']), - ('\u{543}', ['\u{573}', '\0', '\0']), ('\u{544}', ['\u{574}', '\0', '\0']), ('\u{545}', - ['\u{575}', '\0', '\0']), ('\u{546}', ['\u{576}', '\0', '\0']), ('\u{547}', ['\u{577}', - '\0', '\0']), ('\u{548}', ['\u{578}', '\0', '\0']), ('\u{549}', ['\u{579}', '\0', '\0']), - ('\u{54a}', ['\u{57a}', '\0', '\0']), ('\u{54b}', ['\u{57b}', '\0', '\0']), ('\u{54c}', - ['\u{57c}', '\0', '\0']), ('\u{54d}', ['\u{57d}', '\0', '\0']), ('\u{54e}', ['\u{57e}', - '\0', '\0']), ('\u{54f}', ['\u{57f}', '\0', '\0']), ('\u{550}', ['\u{580}', '\0', '\0']), - ('\u{551}', ['\u{581}', '\0', '\0']), ('\u{552}', ['\u{582}', '\0', '\0']), ('\u{553}', - ['\u{583}', '\0', '\0']), ('\u{554}', ['\u{584}', '\0', '\0']), ('\u{555}', ['\u{585}', - '\0', '\0']), ('\u{556}', ['\u{586}', '\0', '\0']), ('\u{10a0}', ['\u{2d00}', '\0', '\0']), - ('\u{10a1}', ['\u{2d01}', '\0', '\0']), ('\u{10a2}', ['\u{2d02}', '\0', '\0']), ('\u{10a3}', - ['\u{2d03}', '\0', '\0']), ('\u{10a4}', ['\u{2d04}', '\0', '\0']), ('\u{10a5}', ['\u{2d05}', - '\0', '\0']), ('\u{10a6}', ['\u{2d06}', '\0', '\0']), ('\u{10a7}', ['\u{2d07}', '\0', - '\0']), ('\u{10a8}', ['\u{2d08}', '\0', '\0']), ('\u{10a9}', ['\u{2d09}', '\0', '\0']), - ('\u{10aa}', ['\u{2d0a}', '\0', '\0']), ('\u{10ab}', ['\u{2d0b}', '\0', '\0']), ('\u{10ac}', - ['\u{2d0c}', '\0', '\0']), ('\u{10ad}', ['\u{2d0d}', '\0', '\0']), ('\u{10ae}', ['\u{2d0e}', - '\0', '\0']), ('\u{10af}', ['\u{2d0f}', '\0', '\0']), ('\u{10b0}', ['\u{2d10}', '\0', - '\0']), ('\u{10b1}', ['\u{2d11}', '\0', '\0']), ('\u{10b2}', ['\u{2d12}', '\0', '\0']), - ('\u{10b3}', ['\u{2d13}', '\0', '\0']), ('\u{10b4}', ['\u{2d14}', '\0', '\0']), ('\u{10b5}', - ['\u{2d15}', '\0', '\0']), ('\u{10b6}', ['\u{2d16}', '\0', '\0']), ('\u{10b7}', ['\u{2d17}', - '\0', '\0']), ('\u{10b8}', ['\u{2d18}', '\0', '\0']), ('\u{10b9}', ['\u{2d19}', '\0', - '\0']), ('\u{10ba}', ['\u{2d1a}', '\0', '\0']), ('\u{10bb}', ['\u{2d1b}', '\0', '\0']), - ('\u{10bc}', ['\u{2d1c}', '\0', '\0']), ('\u{10bd}', ['\u{2d1d}', '\0', '\0']), ('\u{10be}', - ['\u{2d1e}', '\0', '\0']), ('\u{10bf}', ['\u{2d1f}', '\0', '\0']), ('\u{10c0}', ['\u{2d20}', - '\0', '\0']), ('\u{10c1}', ['\u{2d21}', '\0', '\0']), ('\u{10c2}', ['\u{2d22}', '\0', - '\0']), ('\u{10c3}', ['\u{2d23}', '\0', '\0']), ('\u{10c4}', ['\u{2d24}', '\0', '\0']), - ('\u{10c5}', ['\u{2d25}', '\0', '\0']), ('\u{10c7}', ['\u{2d27}', '\0', '\0']), ('\u{10cd}', - ['\u{2d2d}', '\0', '\0']), ('\u{13a0}', ['\u{ab70}', '\0', '\0']), ('\u{13a1}', ['\u{ab71}', - '\0', '\0']), ('\u{13a2}', ['\u{ab72}', '\0', '\0']), ('\u{13a3}', ['\u{ab73}', '\0', - '\0']), ('\u{13a4}', ['\u{ab74}', '\0', '\0']), ('\u{13a5}', ['\u{ab75}', '\0', '\0']), - ('\u{13a6}', ['\u{ab76}', '\0', '\0']), ('\u{13a7}', ['\u{ab77}', '\0', '\0']), ('\u{13a8}', - ['\u{ab78}', '\0', '\0']), ('\u{13a9}', ['\u{ab79}', '\0', '\0']), ('\u{13aa}', ['\u{ab7a}', - '\0', '\0']), ('\u{13ab}', ['\u{ab7b}', '\0', '\0']), ('\u{13ac}', ['\u{ab7c}', '\0', - '\0']), ('\u{13ad}', ['\u{ab7d}', '\0', '\0']), ('\u{13ae}', ['\u{ab7e}', '\0', '\0']), - ('\u{13af}', ['\u{ab7f}', '\0', '\0']), ('\u{13b0}', ['\u{ab80}', '\0', '\0']), ('\u{13b1}', - ['\u{ab81}', '\0', '\0']), ('\u{13b2}', ['\u{ab82}', '\0', '\0']), ('\u{13b3}', ['\u{ab83}', - '\0', '\0']), ('\u{13b4}', ['\u{ab84}', '\0', '\0']), ('\u{13b5}', ['\u{ab85}', '\0', - '\0']), ('\u{13b6}', ['\u{ab86}', '\0', '\0']), ('\u{13b7}', ['\u{ab87}', '\0', '\0']), - ('\u{13b8}', ['\u{ab88}', '\0', '\0']), ('\u{13b9}', ['\u{ab89}', '\0', '\0']), ('\u{13ba}', - ['\u{ab8a}', '\0', '\0']), ('\u{13bb}', ['\u{ab8b}', '\0', '\0']), ('\u{13bc}', ['\u{ab8c}', - '\0', '\0']), ('\u{13bd}', ['\u{ab8d}', '\0', '\0']), ('\u{13be}', ['\u{ab8e}', '\0', - '\0']), ('\u{13bf}', ['\u{ab8f}', '\0', '\0']), ('\u{13c0}', ['\u{ab90}', '\0', '\0']), - ('\u{13c1}', ['\u{ab91}', '\0', '\0']), ('\u{13c2}', ['\u{ab92}', '\0', '\0']), ('\u{13c3}', - ['\u{ab93}', '\0', '\0']), ('\u{13c4}', ['\u{ab94}', '\0', '\0']), ('\u{13c5}', ['\u{ab95}', - '\0', '\0']), ('\u{13c6}', ['\u{ab96}', '\0', '\0']), ('\u{13c7}', ['\u{ab97}', '\0', - '\0']), ('\u{13c8}', ['\u{ab98}', '\0', '\0']), ('\u{13c9}', ['\u{ab99}', '\0', '\0']), - ('\u{13ca}', ['\u{ab9a}', '\0', '\0']), ('\u{13cb}', ['\u{ab9b}', '\0', '\0']), ('\u{13cc}', - ['\u{ab9c}', '\0', '\0']), ('\u{13cd}', ['\u{ab9d}', '\0', '\0']), ('\u{13ce}', ['\u{ab9e}', - '\0', '\0']), ('\u{13cf}', ['\u{ab9f}', '\0', '\0']), ('\u{13d0}', ['\u{aba0}', '\0', - '\0']), ('\u{13d1}', ['\u{aba1}', '\0', '\0']), ('\u{13d2}', ['\u{aba2}', '\0', '\0']), - ('\u{13d3}', ['\u{aba3}', '\0', '\0']), ('\u{13d4}', ['\u{aba4}', '\0', '\0']), ('\u{13d5}', - ['\u{aba5}', '\0', '\0']), ('\u{13d6}', ['\u{aba6}', '\0', '\0']), ('\u{13d7}', ['\u{aba7}', - '\0', '\0']), ('\u{13d8}', ['\u{aba8}', '\0', '\0']), ('\u{13d9}', ['\u{aba9}', '\0', - '\0']), ('\u{13da}', ['\u{abaa}', '\0', '\0']), ('\u{13db}', ['\u{abab}', '\0', '\0']), - ('\u{13dc}', ['\u{abac}', '\0', '\0']), ('\u{13dd}', ['\u{abad}', '\0', '\0']), ('\u{13de}', - ['\u{abae}', '\0', '\0']), ('\u{13df}', ['\u{abaf}', '\0', '\0']), ('\u{13e0}', ['\u{abb0}', - '\0', '\0']), ('\u{13e1}', ['\u{abb1}', '\0', '\0']), ('\u{13e2}', ['\u{abb2}', '\0', - '\0']), ('\u{13e3}', ['\u{abb3}', '\0', '\0']), ('\u{13e4}', ['\u{abb4}', '\0', '\0']), - ('\u{13e5}', ['\u{abb5}', '\0', '\0']), ('\u{13e6}', ['\u{abb6}', '\0', '\0']), ('\u{13e7}', - ['\u{abb7}', '\0', '\0']), ('\u{13e8}', ['\u{abb8}', '\0', '\0']), ('\u{13e9}', ['\u{abb9}', - '\0', '\0']), ('\u{13ea}', ['\u{abba}', '\0', '\0']), ('\u{13eb}', ['\u{abbb}', '\0', - '\0']), ('\u{13ec}', ['\u{abbc}', '\0', '\0']), ('\u{13ed}', ['\u{abbd}', '\0', '\0']), - ('\u{13ee}', ['\u{abbe}', '\0', '\0']), ('\u{13ef}', ['\u{abbf}', '\0', '\0']), ('\u{13f0}', - ['\u{13f8}', '\0', '\0']), ('\u{13f1}', ['\u{13f9}', '\0', '\0']), ('\u{13f2}', ['\u{13fa}', - '\0', '\0']), ('\u{13f3}', ['\u{13fb}', '\0', '\0']), ('\u{13f4}', ['\u{13fc}', '\0', - '\0']), ('\u{13f5}', ['\u{13fd}', '\0', '\0']), ('\u{1c90}', ['\u{10d0}', '\0', '\0']), - ('\u{1c91}', ['\u{10d1}', '\0', '\0']), ('\u{1c92}', ['\u{10d2}', '\0', '\0']), ('\u{1c93}', - ['\u{10d3}', '\0', '\0']), ('\u{1c94}', ['\u{10d4}', '\0', '\0']), ('\u{1c95}', ['\u{10d5}', - '\0', '\0']), ('\u{1c96}', ['\u{10d6}', '\0', '\0']), ('\u{1c97}', ['\u{10d7}', '\0', - '\0']), ('\u{1c98}', ['\u{10d8}', '\0', '\0']), ('\u{1c99}', ['\u{10d9}', '\0', '\0']), - ('\u{1c9a}', ['\u{10da}', '\0', '\0']), ('\u{1c9b}', ['\u{10db}', '\0', '\0']), ('\u{1c9c}', - ['\u{10dc}', '\0', '\0']), ('\u{1c9d}', ['\u{10dd}', '\0', '\0']), ('\u{1c9e}', ['\u{10de}', - '\0', '\0']), ('\u{1c9f}', ['\u{10df}', '\0', '\0']), ('\u{1ca0}', ['\u{10e0}', '\0', - '\0']), ('\u{1ca1}', ['\u{10e1}', '\0', '\0']), ('\u{1ca2}', ['\u{10e2}', '\0', '\0']), - ('\u{1ca3}', ['\u{10e3}', '\0', '\0']), ('\u{1ca4}', ['\u{10e4}', '\0', '\0']), ('\u{1ca5}', - ['\u{10e5}', '\0', '\0']), ('\u{1ca6}', ['\u{10e6}', '\0', '\0']), ('\u{1ca7}', ['\u{10e7}', - '\0', '\0']), ('\u{1ca8}', ['\u{10e8}', '\0', '\0']), ('\u{1ca9}', ['\u{10e9}', '\0', - '\0']), ('\u{1caa}', ['\u{10ea}', '\0', '\0']), ('\u{1cab}', ['\u{10eb}', '\0', '\0']), - ('\u{1cac}', ['\u{10ec}', '\0', '\0']), ('\u{1cad}', ['\u{10ed}', '\0', '\0']), ('\u{1cae}', - ['\u{10ee}', '\0', '\0']), ('\u{1caf}', ['\u{10ef}', '\0', '\0']), ('\u{1cb0}', ['\u{10f0}', - '\0', '\0']), ('\u{1cb1}', ['\u{10f1}', '\0', '\0']), ('\u{1cb2}', ['\u{10f2}', '\0', - '\0']), ('\u{1cb3}', ['\u{10f3}', '\0', '\0']), ('\u{1cb4}', ['\u{10f4}', '\0', '\0']), - ('\u{1cb5}', ['\u{10f5}', '\0', '\0']), ('\u{1cb6}', ['\u{10f6}', '\0', '\0']), ('\u{1cb7}', - ['\u{10f7}', '\0', '\0']), ('\u{1cb8}', ['\u{10f8}', '\0', '\0']), ('\u{1cb9}', ['\u{10f9}', - '\0', '\0']), ('\u{1cba}', ['\u{10fa}', '\0', '\0']), ('\u{1cbd}', ['\u{10fd}', '\0', - '\0']), ('\u{1cbe}', ['\u{10fe}', '\0', '\0']), ('\u{1cbf}', ['\u{10ff}', '\0', '\0']), - ('\u{1e00}', ['\u{1e01}', '\0', '\0']), ('\u{1e02}', ['\u{1e03}', '\0', '\0']), ('\u{1e04}', - ['\u{1e05}', '\0', '\0']), ('\u{1e06}', ['\u{1e07}', '\0', '\0']), ('\u{1e08}', ['\u{1e09}', - '\0', '\0']), ('\u{1e0a}', ['\u{1e0b}', '\0', '\0']), ('\u{1e0c}', ['\u{1e0d}', '\0', - '\0']), ('\u{1e0e}', ['\u{1e0f}', '\0', '\0']), ('\u{1e10}', ['\u{1e11}', '\0', '\0']), - ('\u{1e12}', ['\u{1e13}', '\0', '\0']), ('\u{1e14}', ['\u{1e15}', '\0', '\0']), ('\u{1e16}', - ['\u{1e17}', '\0', '\0']), ('\u{1e18}', ['\u{1e19}', '\0', '\0']), ('\u{1e1a}', ['\u{1e1b}', - '\0', '\0']), ('\u{1e1c}', ['\u{1e1d}', '\0', '\0']), ('\u{1e1e}', ['\u{1e1f}', '\0', - '\0']), ('\u{1e20}', ['\u{1e21}', '\0', '\0']), ('\u{1e22}', ['\u{1e23}', '\0', '\0']), - ('\u{1e24}', ['\u{1e25}', '\0', '\0']), ('\u{1e26}', ['\u{1e27}', '\0', '\0']), ('\u{1e28}', - ['\u{1e29}', '\0', '\0']), ('\u{1e2a}', ['\u{1e2b}', '\0', '\0']), ('\u{1e2c}', ['\u{1e2d}', - '\0', '\0']), ('\u{1e2e}', ['\u{1e2f}', '\0', '\0']), ('\u{1e30}', ['\u{1e31}', '\0', - '\0']), ('\u{1e32}', ['\u{1e33}', '\0', '\0']), ('\u{1e34}', ['\u{1e35}', '\0', '\0']), - ('\u{1e36}', ['\u{1e37}', '\0', '\0']), ('\u{1e38}', ['\u{1e39}', '\0', '\0']), ('\u{1e3a}', - ['\u{1e3b}', '\0', '\0']), ('\u{1e3c}', ['\u{1e3d}', '\0', '\0']), ('\u{1e3e}', ['\u{1e3f}', - '\0', '\0']), ('\u{1e40}', ['\u{1e41}', '\0', '\0']), ('\u{1e42}', ['\u{1e43}', '\0', - '\0']), ('\u{1e44}', ['\u{1e45}', '\0', '\0']), ('\u{1e46}', ['\u{1e47}', '\0', '\0']), - ('\u{1e48}', ['\u{1e49}', '\0', '\0']), ('\u{1e4a}', ['\u{1e4b}', '\0', '\0']), ('\u{1e4c}', - ['\u{1e4d}', '\0', '\0']), ('\u{1e4e}', ['\u{1e4f}', '\0', '\0']), ('\u{1e50}', ['\u{1e51}', - '\0', '\0']), ('\u{1e52}', ['\u{1e53}', '\0', '\0']), ('\u{1e54}', ['\u{1e55}', '\0', - '\0']), ('\u{1e56}', ['\u{1e57}', '\0', '\0']), ('\u{1e58}', ['\u{1e59}', '\0', '\0']), - ('\u{1e5a}', ['\u{1e5b}', '\0', '\0']), ('\u{1e5c}', ['\u{1e5d}', '\0', '\0']), ('\u{1e5e}', - ['\u{1e5f}', '\0', '\0']), ('\u{1e60}', ['\u{1e61}', '\0', '\0']), ('\u{1e62}', ['\u{1e63}', - '\0', '\0']), ('\u{1e64}', ['\u{1e65}', '\0', '\0']), ('\u{1e66}', ['\u{1e67}', '\0', - '\0']), ('\u{1e68}', ['\u{1e69}', '\0', '\0']), ('\u{1e6a}', ['\u{1e6b}', '\0', '\0']), - ('\u{1e6c}', ['\u{1e6d}', '\0', '\0']), ('\u{1e6e}', ['\u{1e6f}', '\0', '\0']), ('\u{1e70}', - ['\u{1e71}', '\0', '\0']), ('\u{1e72}', ['\u{1e73}', '\0', '\0']), ('\u{1e74}', ['\u{1e75}', - '\0', '\0']), ('\u{1e76}', ['\u{1e77}', '\0', '\0']), ('\u{1e78}', ['\u{1e79}', '\0', - '\0']), ('\u{1e7a}', ['\u{1e7b}', '\0', '\0']), ('\u{1e7c}', ['\u{1e7d}', '\0', '\0']), - ('\u{1e7e}', ['\u{1e7f}', '\0', '\0']), ('\u{1e80}', ['\u{1e81}', '\0', '\0']), ('\u{1e82}', - ['\u{1e83}', '\0', '\0']), ('\u{1e84}', ['\u{1e85}', '\0', '\0']), ('\u{1e86}', ['\u{1e87}', - '\0', '\0']), ('\u{1e88}', ['\u{1e89}', '\0', '\0']), ('\u{1e8a}', ['\u{1e8b}', '\0', - '\0']), ('\u{1e8c}', ['\u{1e8d}', '\0', '\0']), ('\u{1e8e}', ['\u{1e8f}', '\0', '\0']), - ('\u{1e90}', ['\u{1e91}', '\0', '\0']), ('\u{1e92}', ['\u{1e93}', '\0', '\0']), ('\u{1e94}', - ['\u{1e95}', '\0', '\0']), ('\u{1e9e}', ['\u{df}', '\0', '\0']), ('\u{1ea0}', ['\u{1ea1}', - '\0', '\0']), ('\u{1ea2}', ['\u{1ea3}', '\0', '\0']), ('\u{1ea4}', ['\u{1ea5}', '\0', - '\0']), ('\u{1ea6}', ['\u{1ea7}', '\0', '\0']), ('\u{1ea8}', ['\u{1ea9}', '\0', '\0']), - ('\u{1eaa}', ['\u{1eab}', '\0', '\0']), ('\u{1eac}', ['\u{1ead}', '\0', '\0']), ('\u{1eae}', - ['\u{1eaf}', '\0', '\0']), ('\u{1eb0}', ['\u{1eb1}', '\0', '\0']), ('\u{1eb2}', ['\u{1eb3}', - '\0', '\0']), ('\u{1eb4}', ['\u{1eb5}', '\0', '\0']), ('\u{1eb6}', ['\u{1eb7}', '\0', - '\0']), ('\u{1eb8}', ['\u{1eb9}', '\0', '\0']), ('\u{1eba}', ['\u{1ebb}', '\0', '\0']), - ('\u{1ebc}', ['\u{1ebd}', '\0', '\0']), ('\u{1ebe}', ['\u{1ebf}', '\0', '\0']), ('\u{1ec0}', - ['\u{1ec1}', '\0', '\0']), ('\u{1ec2}', ['\u{1ec3}', '\0', '\0']), ('\u{1ec4}', ['\u{1ec5}', - '\0', '\0']), ('\u{1ec6}', ['\u{1ec7}', '\0', '\0']), ('\u{1ec8}', ['\u{1ec9}', '\0', - '\0']), ('\u{1eca}', ['\u{1ecb}', '\0', '\0']), ('\u{1ecc}', ['\u{1ecd}', '\0', '\0']), - ('\u{1ece}', ['\u{1ecf}', '\0', '\0']), ('\u{1ed0}', ['\u{1ed1}', '\0', '\0']), ('\u{1ed2}', - ['\u{1ed3}', '\0', '\0']), ('\u{1ed4}', ['\u{1ed5}', '\0', '\0']), ('\u{1ed6}', ['\u{1ed7}', - '\0', '\0']), ('\u{1ed8}', ['\u{1ed9}', '\0', '\0']), ('\u{1eda}', ['\u{1edb}', '\0', - '\0']), ('\u{1edc}', ['\u{1edd}', '\0', '\0']), ('\u{1ede}', ['\u{1edf}', '\0', '\0']), - ('\u{1ee0}', ['\u{1ee1}', '\0', '\0']), ('\u{1ee2}', ['\u{1ee3}', '\0', '\0']), ('\u{1ee4}', - ['\u{1ee5}', '\0', '\0']), ('\u{1ee6}', ['\u{1ee7}', '\0', '\0']), ('\u{1ee8}', ['\u{1ee9}', - '\0', '\0']), ('\u{1eea}', ['\u{1eeb}', '\0', '\0']), ('\u{1eec}', ['\u{1eed}', '\0', - '\0']), ('\u{1eee}', ['\u{1eef}', '\0', '\0']), ('\u{1ef0}', ['\u{1ef1}', '\0', '\0']), - ('\u{1ef2}', ['\u{1ef3}', '\0', '\0']), ('\u{1ef4}', ['\u{1ef5}', '\0', '\0']), ('\u{1ef6}', - ['\u{1ef7}', '\0', '\0']), ('\u{1ef8}', ['\u{1ef9}', '\0', '\0']), ('\u{1efa}', ['\u{1efb}', - '\0', '\0']), ('\u{1efc}', ['\u{1efd}', '\0', '\0']), ('\u{1efe}', ['\u{1eff}', '\0', - '\0']), ('\u{1f08}', ['\u{1f00}', '\0', '\0']), ('\u{1f09}', ['\u{1f01}', '\0', '\0']), - ('\u{1f0a}', ['\u{1f02}', '\0', '\0']), ('\u{1f0b}', ['\u{1f03}', '\0', '\0']), ('\u{1f0c}', - ['\u{1f04}', '\0', '\0']), ('\u{1f0d}', ['\u{1f05}', '\0', '\0']), ('\u{1f0e}', ['\u{1f06}', - '\0', '\0']), ('\u{1f0f}', ['\u{1f07}', '\0', '\0']), ('\u{1f18}', ['\u{1f10}', '\0', - '\0']), ('\u{1f19}', ['\u{1f11}', '\0', '\0']), ('\u{1f1a}', ['\u{1f12}', '\0', '\0']), - ('\u{1f1b}', ['\u{1f13}', '\0', '\0']), ('\u{1f1c}', ['\u{1f14}', '\0', '\0']), ('\u{1f1d}', - ['\u{1f15}', '\0', '\0']), ('\u{1f28}', ['\u{1f20}', '\0', '\0']), ('\u{1f29}', ['\u{1f21}', - '\0', '\0']), ('\u{1f2a}', ['\u{1f22}', '\0', '\0']), ('\u{1f2b}', ['\u{1f23}', '\0', - '\0']), ('\u{1f2c}', ['\u{1f24}', '\0', '\0']), ('\u{1f2d}', ['\u{1f25}', '\0', '\0']), - ('\u{1f2e}', ['\u{1f26}', '\0', '\0']), ('\u{1f2f}', ['\u{1f27}', '\0', '\0']), ('\u{1f38}', - ['\u{1f30}', '\0', '\0']), ('\u{1f39}', ['\u{1f31}', '\0', '\0']), ('\u{1f3a}', ['\u{1f32}', - '\0', '\0']), ('\u{1f3b}', ['\u{1f33}', '\0', '\0']), ('\u{1f3c}', ['\u{1f34}', '\0', - '\0']), ('\u{1f3d}', ['\u{1f35}', '\0', '\0']), ('\u{1f3e}', ['\u{1f36}', '\0', '\0']), - ('\u{1f3f}', ['\u{1f37}', '\0', '\0']), ('\u{1f48}', ['\u{1f40}', '\0', '\0']), ('\u{1f49}', - ['\u{1f41}', '\0', '\0']), ('\u{1f4a}', ['\u{1f42}', '\0', '\0']), ('\u{1f4b}', ['\u{1f43}', - '\0', '\0']), ('\u{1f4c}', ['\u{1f44}', '\0', '\0']), ('\u{1f4d}', ['\u{1f45}', '\0', - '\0']), ('\u{1f59}', ['\u{1f51}', '\0', '\0']), ('\u{1f5b}', ['\u{1f53}', '\0', '\0']), - ('\u{1f5d}', ['\u{1f55}', '\0', '\0']), ('\u{1f5f}', ['\u{1f57}', '\0', '\0']), ('\u{1f68}', - ['\u{1f60}', '\0', '\0']), ('\u{1f69}', ['\u{1f61}', '\0', '\0']), ('\u{1f6a}', ['\u{1f62}', - '\0', '\0']), ('\u{1f6b}', ['\u{1f63}', '\0', '\0']), ('\u{1f6c}', ['\u{1f64}', '\0', - '\0']), ('\u{1f6d}', ['\u{1f65}', '\0', '\0']), ('\u{1f6e}', ['\u{1f66}', '\0', '\0']), - ('\u{1f6f}', ['\u{1f67}', '\0', '\0']), ('\u{1f88}', ['\u{1f80}', '\0', '\0']), ('\u{1f89}', - ['\u{1f81}', '\0', '\0']), ('\u{1f8a}', ['\u{1f82}', '\0', '\0']), ('\u{1f8b}', ['\u{1f83}', - '\0', '\0']), ('\u{1f8c}', ['\u{1f84}', '\0', '\0']), ('\u{1f8d}', ['\u{1f85}', '\0', - '\0']), ('\u{1f8e}', ['\u{1f86}', '\0', '\0']), ('\u{1f8f}', ['\u{1f87}', '\0', '\0']), - ('\u{1f98}', ['\u{1f90}', '\0', '\0']), ('\u{1f99}', ['\u{1f91}', '\0', '\0']), ('\u{1f9a}', - ['\u{1f92}', '\0', '\0']), ('\u{1f9b}', ['\u{1f93}', '\0', '\0']), ('\u{1f9c}', ['\u{1f94}', - '\0', '\0']), ('\u{1f9d}', ['\u{1f95}', '\0', '\0']), ('\u{1f9e}', ['\u{1f96}', '\0', - '\0']), ('\u{1f9f}', ['\u{1f97}', '\0', '\0']), ('\u{1fa8}', ['\u{1fa0}', '\0', '\0']), - ('\u{1fa9}', ['\u{1fa1}', '\0', '\0']), ('\u{1faa}', ['\u{1fa2}', '\0', '\0']), ('\u{1fab}', - ['\u{1fa3}', '\0', '\0']), ('\u{1fac}', ['\u{1fa4}', '\0', '\0']), ('\u{1fad}', ['\u{1fa5}', - '\0', '\0']), ('\u{1fae}', ['\u{1fa6}', '\0', '\0']), ('\u{1faf}', ['\u{1fa7}', '\0', - '\0']), ('\u{1fb8}', ['\u{1fb0}', '\0', '\0']), ('\u{1fb9}', ['\u{1fb1}', '\0', '\0']), - ('\u{1fba}', ['\u{1f70}', '\0', '\0']), ('\u{1fbb}', ['\u{1f71}', '\0', '\0']), ('\u{1fbc}', - ['\u{1fb3}', '\0', '\0']), ('\u{1fc8}', ['\u{1f72}', '\0', '\0']), ('\u{1fc9}', ['\u{1f73}', - '\0', '\0']), ('\u{1fca}', ['\u{1f74}', '\0', '\0']), ('\u{1fcb}', ['\u{1f75}', '\0', - '\0']), ('\u{1fcc}', ['\u{1fc3}', '\0', '\0']), ('\u{1fd8}', ['\u{1fd0}', '\0', '\0']), - ('\u{1fd9}', ['\u{1fd1}', '\0', '\0']), ('\u{1fda}', ['\u{1f76}', '\0', '\0']), ('\u{1fdb}', - ['\u{1f77}', '\0', '\0']), ('\u{1fe8}', ['\u{1fe0}', '\0', '\0']), ('\u{1fe9}', ['\u{1fe1}', - '\0', '\0']), ('\u{1fea}', ['\u{1f7a}', '\0', '\0']), ('\u{1feb}', ['\u{1f7b}', '\0', - '\0']), ('\u{1fec}', ['\u{1fe5}', '\0', '\0']), ('\u{1ff8}', ['\u{1f78}', '\0', '\0']), - ('\u{1ff9}', ['\u{1f79}', '\0', '\0']), ('\u{1ffa}', ['\u{1f7c}', '\0', '\0']), ('\u{1ffb}', - ['\u{1f7d}', '\0', '\0']), ('\u{1ffc}', ['\u{1ff3}', '\0', '\0']), ('\u{2126}', ['\u{3c9}', - '\0', '\0']), ('\u{212a}', ['\u{6b}', '\0', '\0']), ('\u{212b}', ['\u{e5}', '\0', '\0']), - ('\u{2132}', ['\u{214e}', '\0', '\0']), ('\u{2160}', ['\u{2170}', '\0', '\0']), ('\u{2161}', - ['\u{2171}', '\0', '\0']), ('\u{2162}', ['\u{2172}', '\0', '\0']), ('\u{2163}', ['\u{2173}', - '\0', '\0']), ('\u{2164}', ['\u{2174}', '\0', '\0']), ('\u{2165}', ['\u{2175}', '\0', - '\0']), ('\u{2166}', ['\u{2176}', '\0', '\0']), ('\u{2167}', ['\u{2177}', '\0', '\0']), - ('\u{2168}', ['\u{2178}', '\0', '\0']), ('\u{2169}', ['\u{2179}', '\0', '\0']), ('\u{216a}', - ['\u{217a}', '\0', '\0']), ('\u{216b}', ['\u{217b}', '\0', '\0']), ('\u{216c}', ['\u{217c}', - '\0', '\0']), ('\u{216d}', ['\u{217d}', '\0', '\0']), ('\u{216e}', ['\u{217e}', '\0', - '\0']), ('\u{216f}', ['\u{217f}', '\0', '\0']), ('\u{2183}', ['\u{2184}', '\0', '\0']), - ('\u{24b6}', ['\u{24d0}', '\0', '\0']), ('\u{24b7}', ['\u{24d1}', '\0', '\0']), ('\u{24b8}', - ['\u{24d2}', '\0', '\0']), ('\u{24b9}', ['\u{24d3}', '\0', '\0']), ('\u{24ba}', ['\u{24d4}', - '\0', '\0']), ('\u{24bb}', ['\u{24d5}', '\0', '\0']), ('\u{24bc}', ['\u{24d6}', '\0', - '\0']), ('\u{24bd}', ['\u{24d7}', '\0', '\0']), ('\u{24be}', ['\u{24d8}', '\0', '\0']), - ('\u{24bf}', ['\u{24d9}', '\0', '\0']), ('\u{24c0}', ['\u{24da}', '\0', '\0']), ('\u{24c1}', - ['\u{24db}', '\0', '\0']), ('\u{24c2}', ['\u{24dc}', '\0', '\0']), ('\u{24c3}', ['\u{24dd}', - '\0', '\0']), ('\u{24c4}', ['\u{24de}', '\0', '\0']), ('\u{24c5}', ['\u{24df}', '\0', - '\0']), ('\u{24c6}', ['\u{24e0}', '\0', '\0']), ('\u{24c7}', ['\u{24e1}', '\0', '\0']), - ('\u{24c8}', ['\u{24e2}', '\0', '\0']), ('\u{24c9}', ['\u{24e3}', '\0', '\0']), ('\u{24ca}', - ['\u{24e4}', '\0', '\0']), ('\u{24cb}', ['\u{24e5}', '\0', '\0']), ('\u{24cc}', ['\u{24e6}', - '\0', '\0']), ('\u{24cd}', ['\u{24e7}', '\0', '\0']), ('\u{24ce}', ['\u{24e8}', '\0', - '\0']), ('\u{24cf}', ['\u{24e9}', '\0', '\0']), ('\u{2c00}', ['\u{2c30}', '\0', '\0']), - ('\u{2c01}', ['\u{2c31}', '\0', '\0']), ('\u{2c02}', ['\u{2c32}', '\0', '\0']), ('\u{2c03}', - ['\u{2c33}', '\0', '\0']), ('\u{2c04}', ['\u{2c34}', '\0', '\0']), ('\u{2c05}', ['\u{2c35}', - '\0', '\0']), ('\u{2c06}', ['\u{2c36}', '\0', '\0']), ('\u{2c07}', ['\u{2c37}', '\0', - '\0']), ('\u{2c08}', ['\u{2c38}', '\0', '\0']), ('\u{2c09}', ['\u{2c39}', '\0', '\0']), - ('\u{2c0a}', ['\u{2c3a}', '\0', '\0']), ('\u{2c0b}', ['\u{2c3b}', '\0', '\0']), ('\u{2c0c}', - ['\u{2c3c}', '\0', '\0']), ('\u{2c0d}', ['\u{2c3d}', '\0', '\0']), ('\u{2c0e}', ['\u{2c3e}', - '\0', '\0']), ('\u{2c0f}', ['\u{2c3f}', '\0', '\0']), ('\u{2c10}', ['\u{2c40}', '\0', - '\0']), ('\u{2c11}', ['\u{2c41}', '\0', '\0']), ('\u{2c12}', ['\u{2c42}', '\0', '\0']), - ('\u{2c13}', ['\u{2c43}', '\0', '\0']), ('\u{2c14}', ['\u{2c44}', '\0', '\0']), ('\u{2c15}', - ['\u{2c45}', '\0', '\0']), ('\u{2c16}', ['\u{2c46}', '\0', '\0']), ('\u{2c17}', ['\u{2c47}', - '\0', '\0']), ('\u{2c18}', ['\u{2c48}', '\0', '\0']), ('\u{2c19}', ['\u{2c49}', '\0', - '\0']), ('\u{2c1a}', ['\u{2c4a}', '\0', '\0']), ('\u{2c1b}', ['\u{2c4b}', '\0', '\0']), - ('\u{2c1c}', ['\u{2c4c}', '\0', '\0']), ('\u{2c1d}', ['\u{2c4d}', '\0', '\0']), ('\u{2c1e}', - ['\u{2c4e}', '\0', '\0']), ('\u{2c1f}', ['\u{2c4f}', '\0', '\0']), ('\u{2c20}', ['\u{2c50}', - '\0', '\0']), ('\u{2c21}', ['\u{2c51}', '\0', '\0']), ('\u{2c22}', ['\u{2c52}', '\0', - '\0']), ('\u{2c23}', ['\u{2c53}', '\0', '\0']), ('\u{2c24}', ['\u{2c54}', '\0', '\0']), - ('\u{2c25}', ['\u{2c55}', '\0', '\0']), ('\u{2c26}', ['\u{2c56}', '\0', '\0']), ('\u{2c27}', - ['\u{2c57}', '\0', '\0']), ('\u{2c28}', ['\u{2c58}', '\0', '\0']), ('\u{2c29}', ['\u{2c59}', - '\0', '\0']), ('\u{2c2a}', ['\u{2c5a}', '\0', '\0']), ('\u{2c2b}', ['\u{2c5b}', '\0', - '\0']), ('\u{2c2c}', ['\u{2c5c}', '\0', '\0']), ('\u{2c2d}', ['\u{2c5d}', '\0', '\0']), - ('\u{2c2e}', ['\u{2c5e}', '\0', '\0']), ('\u{2c60}', ['\u{2c61}', '\0', '\0']), ('\u{2c62}', - ['\u{26b}', '\0', '\0']), ('\u{2c63}', ['\u{1d7d}', '\0', '\0']), ('\u{2c64}', ['\u{27d}', - '\0', '\0']), ('\u{2c67}', ['\u{2c68}', '\0', '\0']), ('\u{2c69}', ['\u{2c6a}', '\0', - '\0']), ('\u{2c6b}', ['\u{2c6c}', '\0', '\0']), ('\u{2c6d}', ['\u{251}', '\0', '\0']), - ('\u{2c6e}', ['\u{271}', '\0', '\0']), ('\u{2c6f}', ['\u{250}', '\0', '\0']), ('\u{2c70}', - ['\u{252}', '\0', '\0']), ('\u{2c72}', ['\u{2c73}', '\0', '\0']), ('\u{2c75}', ['\u{2c76}', - '\0', '\0']), ('\u{2c7e}', ['\u{23f}', '\0', '\0']), ('\u{2c7f}', ['\u{240}', '\0', '\0']), - ('\u{2c80}', ['\u{2c81}', '\0', '\0']), ('\u{2c82}', ['\u{2c83}', '\0', '\0']), ('\u{2c84}', - ['\u{2c85}', '\0', '\0']), ('\u{2c86}', ['\u{2c87}', '\0', '\0']), ('\u{2c88}', ['\u{2c89}', - '\0', '\0']), ('\u{2c8a}', ['\u{2c8b}', '\0', '\0']), ('\u{2c8c}', ['\u{2c8d}', '\0', - '\0']), ('\u{2c8e}', ['\u{2c8f}', '\0', '\0']), ('\u{2c90}', ['\u{2c91}', '\0', '\0']), - ('\u{2c92}', ['\u{2c93}', '\0', '\0']), ('\u{2c94}', ['\u{2c95}', '\0', '\0']), ('\u{2c96}', - ['\u{2c97}', '\0', '\0']), ('\u{2c98}', ['\u{2c99}', '\0', '\0']), ('\u{2c9a}', ['\u{2c9b}', - '\0', '\0']), ('\u{2c9c}', ['\u{2c9d}', '\0', '\0']), ('\u{2c9e}', ['\u{2c9f}', '\0', - '\0']), ('\u{2ca0}', ['\u{2ca1}', '\0', '\0']), ('\u{2ca2}', ['\u{2ca3}', '\0', '\0']), - ('\u{2ca4}', ['\u{2ca5}', '\0', '\0']), ('\u{2ca6}', ['\u{2ca7}', '\0', '\0']), ('\u{2ca8}', - ['\u{2ca9}', '\0', '\0']), ('\u{2caa}', ['\u{2cab}', '\0', '\0']), ('\u{2cac}', ['\u{2cad}', - '\0', '\0']), ('\u{2cae}', ['\u{2caf}', '\0', '\0']), ('\u{2cb0}', ['\u{2cb1}', '\0', - '\0']), ('\u{2cb2}', ['\u{2cb3}', '\0', '\0']), ('\u{2cb4}', ['\u{2cb5}', '\0', '\0']), - ('\u{2cb6}', ['\u{2cb7}', '\0', '\0']), ('\u{2cb8}', ['\u{2cb9}', '\0', '\0']), ('\u{2cba}', - ['\u{2cbb}', '\0', '\0']), ('\u{2cbc}', ['\u{2cbd}', '\0', '\0']), ('\u{2cbe}', ['\u{2cbf}', - '\0', '\0']), ('\u{2cc0}', ['\u{2cc1}', '\0', '\0']), ('\u{2cc2}', ['\u{2cc3}', '\0', - '\0']), ('\u{2cc4}', ['\u{2cc5}', '\0', '\0']), ('\u{2cc6}', ['\u{2cc7}', '\0', '\0']), - ('\u{2cc8}', ['\u{2cc9}', '\0', '\0']), ('\u{2cca}', ['\u{2ccb}', '\0', '\0']), ('\u{2ccc}', - ['\u{2ccd}', '\0', '\0']), ('\u{2cce}', ['\u{2ccf}', '\0', '\0']), ('\u{2cd0}', ['\u{2cd1}', - '\0', '\0']), ('\u{2cd2}', ['\u{2cd3}', '\0', '\0']), ('\u{2cd4}', ['\u{2cd5}', '\0', - '\0']), ('\u{2cd6}', ['\u{2cd7}', '\0', '\0']), ('\u{2cd8}', ['\u{2cd9}', '\0', '\0']), - ('\u{2cda}', ['\u{2cdb}', '\0', '\0']), ('\u{2cdc}', ['\u{2cdd}', '\0', '\0']), ('\u{2cde}', - ['\u{2cdf}', '\0', '\0']), ('\u{2ce0}', ['\u{2ce1}', '\0', '\0']), ('\u{2ce2}', ['\u{2ce3}', - '\0', '\0']), ('\u{2ceb}', ['\u{2cec}', '\0', '\0']), ('\u{2ced}', ['\u{2cee}', '\0', - '\0']), ('\u{2cf2}', ['\u{2cf3}', '\0', '\0']), ('\u{a640}', ['\u{a641}', '\0', '\0']), - ('\u{a642}', ['\u{a643}', '\0', '\0']), ('\u{a644}', ['\u{a645}', '\0', '\0']), ('\u{a646}', - ['\u{a647}', '\0', '\0']), ('\u{a648}', ['\u{a649}', '\0', '\0']), ('\u{a64a}', ['\u{a64b}', - '\0', '\0']), ('\u{a64c}', ['\u{a64d}', '\0', '\0']), ('\u{a64e}', ['\u{a64f}', '\0', - '\0']), ('\u{a650}', ['\u{a651}', '\0', '\0']), ('\u{a652}', ['\u{a653}', '\0', '\0']), - ('\u{a654}', ['\u{a655}', '\0', '\0']), ('\u{a656}', ['\u{a657}', '\0', '\0']), ('\u{a658}', - ['\u{a659}', '\0', '\0']), ('\u{a65a}', ['\u{a65b}', '\0', '\0']), ('\u{a65c}', ['\u{a65d}', - '\0', '\0']), ('\u{a65e}', ['\u{a65f}', '\0', '\0']), ('\u{a660}', ['\u{a661}', '\0', - '\0']), ('\u{a662}', ['\u{a663}', '\0', '\0']), ('\u{a664}', ['\u{a665}', '\0', '\0']), - ('\u{a666}', ['\u{a667}', '\0', '\0']), ('\u{a668}', ['\u{a669}', '\0', '\0']), ('\u{a66a}', - ['\u{a66b}', '\0', '\0']), ('\u{a66c}', ['\u{a66d}', '\0', '\0']), ('\u{a680}', ['\u{a681}', - '\0', '\0']), ('\u{a682}', ['\u{a683}', '\0', '\0']), ('\u{a684}', ['\u{a685}', '\0', - '\0']), ('\u{a686}', ['\u{a687}', '\0', '\0']), ('\u{a688}', ['\u{a689}', '\0', '\0']), - ('\u{a68a}', ['\u{a68b}', '\0', '\0']), ('\u{a68c}', ['\u{a68d}', '\0', '\0']), ('\u{a68e}', - ['\u{a68f}', '\0', '\0']), ('\u{a690}', ['\u{a691}', '\0', '\0']), ('\u{a692}', ['\u{a693}', - '\0', '\0']), ('\u{a694}', ['\u{a695}', '\0', '\0']), ('\u{a696}', ['\u{a697}', '\0', - '\0']), ('\u{a698}', ['\u{a699}', '\0', '\0']), ('\u{a69a}', ['\u{a69b}', '\0', '\0']), - ('\u{a722}', ['\u{a723}', '\0', '\0']), ('\u{a724}', ['\u{a725}', '\0', '\0']), ('\u{a726}', - ['\u{a727}', '\0', '\0']), ('\u{a728}', ['\u{a729}', '\0', '\0']), ('\u{a72a}', ['\u{a72b}', - '\0', '\0']), ('\u{a72c}', ['\u{a72d}', '\0', '\0']), ('\u{a72e}', ['\u{a72f}', '\0', - '\0']), ('\u{a732}', ['\u{a733}', '\0', '\0']), ('\u{a734}', ['\u{a735}', '\0', '\0']), - ('\u{a736}', ['\u{a737}', '\0', '\0']), ('\u{a738}', ['\u{a739}', '\0', '\0']), ('\u{a73a}', - ['\u{a73b}', '\0', '\0']), ('\u{a73c}', ['\u{a73d}', '\0', '\0']), ('\u{a73e}', ['\u{a73f}', - '\0', '\0']), ('\u{a740}', ['\u{a741}', '\0', '\0']), ('\u{a742}', ['\u{a743}', '\0', - '\0']), ('\u{a744}', ['\u{a745}', '\0', '\0']), ('\u{a746}', ['\u{a747}', '\0', '\0']), - ('\u{a748}', ['\u{a749}', '\0', '\0']), ('\u{a74a}', ['\u{a74b}', '\0', '\0']), ('\u{a74c}', - ['\u{a74d}', '\0', '\0']), ('\u{a74e}', ['\u{a74f}', '\0', '\0']), ('\u{a750}', ['\u{a751}', - '\0', '\0']), ('\u{a752}', ['\u{a753}', '\0', '\0']), ('\u{a754}', ['\u{a755}', '\0', - '\0']), ('\u{a756}', ['\u{a757}', '\0', '\0']), ('\u{a758}', ['\u{a759}', '\0', '\0']), - ('\u{a75a}', ['\u{a75b}', '\0', '\0']), ('\u{a75c}', ['\u{a75d}', '\0', '\0']), ('\u{a75e}', - ['\u{a75f}', '\0', '\0']), ('\u{a760}', ['\u{a761}', '\0', '\0']), ('\u{a762}', ['\u{a763}', - '\0', '\0']), ('\u{a764}', ['\u{a765}', '\0', '\0']), ('\u{a766}', ['\u{a767}', '\0', - '\0']), ('\u{a768}', ['\u{a769}', '\0', '\0']), ('\u{a76a}', ['\u{a76b}', '\0', '\0']), - ('\u{a76c}', ['\u{a76d}', '\0', '\0']), ('\u{a76e}', ['\u{a76f}', '\0', '\0']), ('\u{a779}', - ['\u{a77a}', '\0', '\0']), ('\u{a77b}', ['\u{a77c}', '\0', '\0']), ('\u{a77d}', ['\u{1d79}', - '\0', '\0']), ('\u{a77e}', ['\u{a77f}', '\0', '\0']), ('\u{a780}', ['\u{a781}', '\0', - '\0']), ('\u{a782}', ['\u{a783}', '\0', '\0']), ('\u{a784}', ['\u{a785}', '\0', '\0']), - ('\u{a786}', ['\u{a787}', '\0', '\0']), ('\u{a78b}', ['\u{a78c}', '\0', '\0']), ('\u{a78d}', - ['\u{265}', '\0', '\0']), ('\u{a790}', ['\u{a791}', '\0', '\0']), ('\u{a792}', ['\u{a793}', - '\0', '\0']), ('\u{a796}', ['\u{a797}', '\0', '\0']), ('\u{a798}', ['\u{a799}', '\0', - '\0']), ('\u{a79a}', ['\u{a79b}', '\0', '\0']), ('\u{a79c}', ['\u{a79d}', '\0', '\0']), - ('\u{a79e}', ['\u{a79f}', '\0', '\0']), ('\u{a7a0}', ['\u{a7a1}', '\0', '\0']), ('\u{a7a2}', - ['\u{a7a3}', '\0', '\0']), ('\u{a7a4}', ['\u{a7a5}', '\0', '\0']), ('\u{a7a6}', ['\u{a7a7}', - '\0', '\0']), ('\u{a7a8}', ['\u{a7a9}', '\0', '\0']), ('\u{a7aa}', ['\u{266}', '\0', '\0']), - ('\u{a7ab}', ['\u{25c}', '\0', '\0']), ('\u{a7ac}', ['\u{261}', '\0', '\0']), ('\u{a7ad}', - ['\u{26c}', '\0', '\0']), ('\u{a7ae}', ['\u{26a}', '\0', '\0']), ('\u{a7b0}', ['\u{29e}', - '\0', '\0']), ('\u{a7b1}', ['\u{287}', '\0', '\0']), ('\u{a7b2}', ['\u{29d}', '\0', '\0']), - ('\u{a7b3}', ['\u{ab53}', '\0', '\0']), ('\u{a7b4}', ['\u{a7b5}', '\0', '\0']), ('\u{a7b6}', - ['\u{a7b7}', '\0', '\0']), ('\u{a7b8}', ['\u{a7b9}', '\0', '\0']), ('\u{a7ba}', ['\u{a7bb}', - '\0', '\0']), ('\u{a7bc}', ['\u{a7bd}', '\0', '\0']), ('\u{a7be}', ['\u{a7bf}', '\0', - '\0']), ('\u{a7c2}', ['\u{a7c3}', '\0', '\0']), ('\u{a7c4}', ['\u{a794}', '\0', '\0']), - ('\u{a7c5}', ['\u{282}', '\0', '\0']), ('\u{a7c6}', ['\u{1d8e}', '\0', '\0']), ('\u{ff21}', - ['\u{ff41}', '\0', '\0']), ('\u{ff22}', ['\u{ff42}', '\0', '\0']), ('\u{ff23}', ['\u{ff43}', - '\0', '\0']), ('\u{ff24}', ['\u{ff44}', '\0', '\0']), ('\u{ff25}', ['\u{ff45}', '\0', - '\0']), ('\u{ff26}', ['\u{ff46}', '\0', '\0']), ('\u{ff27}', ['\u{ff47}', '\0', '\0']), - ('\u{ff28}', ['\u{ff48}', '\0', '\0']), ('\u{ff29}', ['\u{ff49}', '\0', '\0']), ('\u{ff2a}', - ['\u{ff4a}', '\0', '\0']), ('\u{ff2b}', ['\u{ff4b}', '\0', '\0']), ('\u{ff2c}', ['\u{ff4c}', - '\0', '\0']), ('\u{ff2d}', ['\u{ff4d}', '\0', '\0']), ('\u{ff2e}', ['\u{ff4e}', '\0', - '\0']), ('\u{ff2f}', ['\u{ff4f}', '\0', '\0']), ('\u{ff30}', ['\u{ff50}', '\0', '\0']), - ('\u{ff31}', ['\u{ff51}', '\0', '\0']), ('\u{ff32}', ['\u{ff52}', '\0', '\0']), ('\u{ff33}', - ['\u{ff53}', '\0', '\0']), ('\u{ff34}', ['\u{ff54}', '\0', '\0']), ('\u{ff35}', ['\u{ff55}', - '\0', '\0']), ('\u{ff36}', ['\u{ff56}', '\0', '\0']), ('\u{ff37}', ['\u{ff57}', '\0', - '\0']), ('\u{ff38}', ['\u{ff58}', '\0', '\0']), ('\u{ff39}', ['\u{ff59}', '\0', '\0']), - ('\u{ff3a}', ['\u{ff5a}', '\0', '\0']), ('\u{10400}', ['\u{10428}', '\0', '\0']), - ('\u{10401}', ['\u{10429}', '\0', '\0']), ('\u{10402}', ['\u{1042a}', '\0', '\0']), - ('\u{10403}', ['\u{1042b}', '\0', '\0']), ('\u{10404}', ['\u{1042c}', '\0', '\0']), - ('\u{10405}', ['\u{1042d}', '\0', '\0']), ('\u{10406}', ['\u{1042e}', '\0', '\0']), - ('\u{10407}', ['\u{1042f}', '\0', '\0']), ('\u{10408}', ['\u{10430}', '\0', '\0']), - ('\u{10409}', ['\u{10431}', '\0', '\0']), ('\u{1040a}', ['\u{10432}', '\0', '\0']), - ('\u{1040b}', ['\u{10433}', '\0', '\0']), ('\u{1040c}', ['\u{10434}', '\0', '\0']), - ('\u{1040d}', ['\u{10435}', '\0', '\0']), ('\u{1040e}', ['\u{10436}', '\0', '\0']), - ('\u{1040f}', ['\u{10437}', '\0', '\0']), ('\u{10410}', ['\u{10438}', '\0', '\0']), - ('\u{10411}', ['\u{10439}', '\0', '\0']), ('\u{10412}', ['\u{1043a}', '\0', '\0']), - ('\u{10413}', ['\u{1043b}', '\0', '\0']), ('\u{10414}', ['\u{1043c}', '\0', '\0']), - ('\u{10415}', ['\u{1043d}', '\0', '\0']), ('\u{10416}', ['\u{1043e}', '\0', '\0']), - ('\u{10417}', ['\u{1043f}', '\0', '\0']), ('\u{10418}', ['\u{10440}', '\0', '\0']), - ('\u{10419}', ['\u{10441}', '\0', '\0']), ('\u{1041a}', ['\u{10442}', '\0', '\0']), - ('\u{1041b}', ['\u{10443}', '\0', '\0']), ('\u{1041c}', ['\u{10444}', '\0', '\0']), - ('\u{1041d}', ['\u{10445}', '\0', '\0']), ('\u{1041e}', ['\u{10446}', '\0', '\0']), - ('\u{1041f}', ['\u{10447}', '\0', '\0']), ('\u{10420}', ['\u{10448}', '\0', '\0']), - ('\u{10421}', ['\u{10449}', '\0', '\0']), ('\u{10422}', ['\u{1044a}', '\0', '\0']), - ('\u{10423}', ['\u{1044b}', '\0', '\0']), ('\u{10424}', ['\u{1044c}', '\0', '\0']), - ('\u{10425}', ['\u{1044d}', '\0', '\0']), ('\u{10426}', ['\u{1044e}', '\0', '\0']), - ('\u{10427}', ['\u{1044f}', '\0', '\0']), ('\u{104b0}', ['\u{104d8}', '\0', '\0']), - ('\u{104b1}', ['\u{104d9}', '\0', '\0']), ('\u{104b2}', ['\u{104da}', '\0', '\0']), - ('\u{104b3}', ['\u{104db}', '\0', '\0']), ('\u{104b4}', ['\u{104dc}', '\0', '\0']), - ('\u{104b5}', ['\u{104dd}', '\0', '\0']), ('\u{104b6}', ['\u{104de}', '\0', '\0']), - ('\u{104b7}', ['\u{104df}', '\0', '\0']), ('\u{104b8}', ['\u{104e0}', '\0', '\0']), - ('\u{104b9}', ['\u{104e1}', '\0', '\0']), ('\u{104ba}', ['\u{104e2}', '\0', '\0']), - ('\u{104bb}', ['\u{104e3}', '\0', '\0']), ('\u{104bc}', ['\u{104e4}', '\0', '\0']), - ('\u{104bd}', ['\u{104e5}', '\0', '\0']), ('\u{104be}', ['\u{104e6}', '\0', '\0']), - ('\u{104bf}', ['\u{104e7}', '\0', '\0']), ('\u{104c0}', ['\u{104e8}', '\0', '\0']), - ('\u{104c1}', ['\u{104e9}', '\0', '\0']), ('\u{104c2}', ['\u{104ea}', '\0', '\0']), - ('\u{104c3}', ['\u{104eb}', '\0', '\0']), ('\u{104c4}', ['\u{104ec}', '\0', '\0']), - ('\u{104c5}', ['\u{104ed}', '\0', '\0']), ('\u{104c6}', ['\u{104ee}', '\0', '\0']), - ('\u{104c7}', ['\u{104ef}', '\0', '\0']), ('\u{104c8}', ['\u{104f0}', '\0', '\0']), - ('\u{104c9}', ['\u{104f1}', '\0', '\0']), ('\u{104ca}', ['\u{104f2}', '\0', '\0']), - ('\u{104cb}', ['\u{104f3}', '\0', '\0']), ('\u{104cc}', ['\u{104f4}', '\0', '\0']), - ('\u{104cd}', ['\u{104f5}', '\0', '\0']), ('\u{104ce}', ['\u{104f6}', '\0', '\0']), - ('\u{104cf}', ['\u{104f7}', '\0', '\0']), ('\u{104d0}', ['\u{104f8}', '\0', '\0']), - ('\u{104d1}', ['\u{104f9}', '\0', '\0']), ('\u{104d2}', ['\u{104fa}', '\0', '\0']), - ('\u{104d3}', ['\u{104fb}', '\0', '\0']), ('\u{10c80}', ['\u{10cc0}', '\0', '\0']), - ('\u{10c81}', ['\u{10cc1}', '\0', '\0']), ('\u{10c82}', ['\u{10cc2}', '\0', '\0']), - ('\u{10c83}', ['\u{10cc3}', '\0', '\0']), ('\u{10c84}', ['\u{10cc4}', '\0', '\0']), - ('\u{10c85}', ['\u{10cc5}', '\0', '\0']), ('\u{10c86}', ['\u{10cc6}', '\0', '\0']), - ('\u{10c87}', ['\u{10cc7}', '\0', '\0']), ('\u{10c88}', ['\u{10cc8}', '\0', '\0']), - ('\u{10c89}', ['\u{10cc9}', '\0', '\0']), ('\u{10c8a}', ['\u{10cca}', '\0', '\0']), - ('\u{10c8b}', ['\u{10ccb}', '\0', '\0']), ('\u{10c8c}', ['\u{10ccc}', '\0', '\0']), - ('\u{10c8d}', ['\u{10ccd}', '\0', '\0']), ('\u{10c8e}', ['\u{10cce}', '\0', '\0']), - ('\u{10c8f}', ['\u{10ccf}', '\0', '\0']), ('\u{10c90}', ['\u{10cd0}', '\0', '\0']), - ('\u{10c91}', ['\u{10cd1}', '\0', '\0']), ('\u{10c92}', ['\u{10cd2}', '\0', '\0']), - ('\u{10c93}', ['\u{10cd3}', '\0', '\0']), ('\u{10c94}', ['\u{10cd4}', '\0', '\0']), - ('\u{10c95}', ['\u{10cd5}', '\0', '\0']), ('\u{10c96}', ['\u{10cd6}', '\0', '\0']), - ('\u{10c97}', ['\u{10cd7}', '\0', '\0']), ('\u{10c98}', ['\u{10cd8}', '\0', '\0']), - ('\u{10c99}', ['\u{10cd9}', '\0', '\0']), ('\u{10c9a}', ['\u{10cda}', '\0', '\0']), - ('\u{10c9b}', ['\u{10cdb}', '\0', '\0']), ('\u{10c9c}', ['\u{10cdc}', '\0', '\0']), - ('\u{10c9d}', ['\u{10cdd}', '\0', '\0']), ('\u{10c9e}', ['\u{10cde}', '\0', '\0']), - ('\u{10c9f}', ['\u{10cdf}', '\0', '\0']), ('\u{10ca0}', ['\u{10ce0}', '\0', '\0']), - ('\u{10ca1}', ['\u{10ce1}', '\0', '\0']), ('\u{10ca2}', ['\u{10ce2}', '\0', '\0']), - ('\u{10ca3}', ['\u{10ce3}', '\0', '\0']), ('\u{10ca4}', ['\u{10ce4}', '\0', '\0']), - ('\u{10ca5}', ['\u{10ce5}', '\0', '\0']), ('\u{10ca6}', ['\u{10ce6}', '\0', '\0']), - ('\u{10ca7}', ['\u{10ce7}', '\0', '\0']), ('\u{10ca8}', ['\u{10ce8}', '\0', '\0']), - ('\u{10ca9}', ['\u{10ce9}', '\0', '\0']), ('\u{10caa}', ['\u{10cea}', '\0', '\0']), - ('\u{10cab}', ['\u{10ceb}', '\0', '\0']), ('\u{10cac}', ['\u{10cec}', '\0', '\0']), - ('\u{10cad}', ['\u{10ced}', '\0', '\0']), ('\u{10cae}', ['\u{10cee}', '\0', '\0']), - ('\u{10caf}', ['\u{10cef}', '\0', '\0']), ('\u{10cb0}', ['\u{10cf0}', '\0', '\0']), - ('\u{10cb1}', ['\u{10cf1}', '\0', '\0']), ('\u{10cb2}', ['\u{10cf2}', '\0', '\0']), - ('\u{118a0}', ['\u{118c0}', '\0', '\0']), ('\u{118a1}', ['\u{118c1}', '\0', '\0']), - ('\u{118a2}', ['\u{118c2}', '\0', '\0']), ('\u{118a3}', ['\u{118c3}', '\0', '\0']), - ('\u{118a4}', ['\u{118c4}', '\0', '\0']), ('\u{118a5}', ['\u{118c5}', '\0', '\0']), - ('\u{118a6}', ['\u{118c6}', '\0', '\0']), ('\u{118a7}', ['\u{118c7}', '\0', '\0']), - ('\u{118a8}', ['\u{118c8}', '\0', '\0']), ('\u{118a9}', ['\u{118c9}', '\0', '\0']), - ('\u{118aa}', ['\u{118ca}', '\0', '\0']), ('\u{118ab}', ['\u{118cb}', '\0', '\0']), - ('\u{118ac}', ['\u{118cc}', '\0', '\0']), ('\u{118ad}', ['\u{118cd}', '\0', '\0']), - ('\u{118ae}', ['\u{118ce}', '\0', '\0']), ('\u{118af}', ['\u{118cf}', '\0', '\0']), - ('\u{118b0}', ['\u{118d0}', '\0', '\0']), ('\u{118b1}', ['\u{118d1}', '\0', '\0']), - ('\u{118b2}', ['\u{118d2}', '\0', '\0']), ('\u{118b3}', ['\u{118d3}', '\0', '\0']), - ('\u{118b4}', ['\u{118d4}', '\0', '\0']), ('\u{118b5}', ['\u{118d5}', '\0', '\0']), - ('\u{118b6}', ['\u{118d6}', '\0', '\0']), ('\u{118b7}', ['\u{118d7}', '\0', '\0']), - ('\u{118b8}', ['\u{118d8}', '\0', '\0']), ('\u{118b9}', ['\u{118d9}', '\0', '\0']), - ('\u{118ba}', ['\u{118da}', '\0', '\0']), ('\u{118bb}', ['\u{118db}', '\0', '\0']), - ('\u{118bc}', ['\u{118dc}', '\0', '\0']), ('\u{118bd}', ['\u{118dd}', '\0', '\0']), - ('\u{118be}', ['\u{118de}', '\0', '\0']), ('\u{118bf}', ['\u{118df}', '\0', '\0']), - ('\u{16e40}', ['\u{16e60}', '\0', '\0']), ('\u{16e41}', ['\u{16e61}', '\0', '\0']), - ('\u{16e42}', ['\u{16e62}', '\0', '\0']), ('\u{16e43}', ['\u{16e63}', '\0', '\0']), - ('\u{16e44}', ['\u{16e64}', '\0', '\0']), ('\u{16e45}', ['\u{16e65}', '\0', '\0']), - ('\u{16e46}', ['\u{16e66}', '\0', '\0']), ('\u{16e47}', ['\u{16e67}', '\0', '\0']), - ('\u{16e48}', ['\u{16e68}', '\0', '\0']), ('\u{16e49}', ['\u{16e69}', '\0', '\0']), - ('\u{16e4a}', ['\u{16e6a}', '\0', '\0']), ('\u{16e4b}', ['\u{16e6b}', '\0', '\0']), - ('\u{16e4c}', ['\u{16e6c}', '\0', '\0']), ('\u{16e4d}', ['\u{16e6d}', '\0', '\0']), - ('\u{16e4e}', ['\u{16e6e}', '\0', '\0']), ('\u{16e4f}', ['\u{16e6f}', '\0', '\0']), - ('\u{16e50}', ['\u{16e70}', '\0', '\0']), ('\u{16e51}', ['\u{16e71}', '\0', '\0']), - ('\u{16e52}', ['\u{16e72}', '\0', '\0']), ('\u{16e53}', ['\u{16e73}', '\0', '\0']), - ('\u{16e54}', ['\u{16e74}', '\0', '\0']), ('\u{16e55}', ['\u{16e75}', '\0', '\0']), - ('\u{16e56}', ['\u{16e76}', '\0', '\0']), ('\u{16e57}', ['\u{16e77}', '\0', '\0']), - ('\u{16e58}', ['\u{16e78}', '\0', '\0']), ('\u{16e59}', ['\u{16e79}', '\0', '\0']), - ('\u{16e5a}', ['\u{16e7a}', '\0', '\0']), ('\u{16e5b}', ['\u{16e7b}', '\0', '\0']), - ('\u{16e5c}', ['\u{16e7c}', '\0', '\0']), ('\u{16e5d}', ['\u{16e7d}', '\0', '\0']), - ('\u{16e5e}', ['\u{16e7e}', '\0', '\0']), ('\u{16e5f}', ['\u{16e7f}', '\0', '\0']), - ('\u{1e900}', ['\u{1e922}', '\0', '\0']), ('\u{1e901}', ['\u{1e923}', '\0', '\0']), - ('\u{1e902}', ['\u{1e924}', '\0', '\0']), ('\u{1e903}', ['\u{1e925}', '\0', '\0']), - ('\u{1e904}', ['\u{1e926}', '\0', '\0']), ('\u{1e905}', ['\u{1e927}', '\0', '\0']), - ('\u{1e906}', ['\u{1e928}', '\0', '\0']), ('\u{1e907}', ['\u{1e929}', '\0', '\0']), - ('\u{1e908}', ['\u{1e92a}', '\0', '\0']), ('\u{1e909}', ['\u{1e92b}', '\0', '\0']), - ('\u{1e90a}', ['\u{1e92c}', '\0', '\0']), ('\u{1e90b}', ['\u{1e92d}', '\0', '\0']), - ('\u{1e90c}', ['\u{1e92e}', '\0', '\0']), ('\u{1e90d}', ['\u{1e92f}', '\0', '\0']), - ('\u{1e90e}', ['\u{1e930}', '\0', '\0']), ('\u{1e90f}', ['\u{1e931}', '\0', '\0']), - ('\u{1e910}', ['\u{1e932}', '\0', '\0']), ('\u{1e911}', ['\u{1e933}', '\0', '\0']), - ('\u{1e912}', ['\u{1e934}', '\0', '\0']), ('\u{1e913}', ['\u{1e935}', '\0', '\0']), - ('\u{1e914}', ['\u{1e936}', '\0', '\0']), ('\u{1e915}', ['\u{1e937}', '\0', '\0']), - ('\u{1e916}', ['\u{1e938}', '\0', '\0']), ('\u{1e917}', ['\u{1e939}', '\0', '\0']), - ('\u{1e918}', ['\u{1e93a}', '\0', '\0']), ('\u{1e919}', ['\u{1e93b}', '\0', '\0']), - ('\u{1e91a}', ['\u{1e93c}', '\0', '\0']), ('\u{1e91b}', ['\u{1e93d}', '\0', '\0']), - ('\u{1e91c}', ['\u{1e93e}', '\0', '\0']), ('\u{1e91d}', ['\u{1e93f}', '\0', '\0']), - ('\u{1e91e}', ['\u{1e940}', '\0', '\0']), ('\u{1e91f}', ['\u{1e941}', '\0', '\0']), - ('\u{1e920}', ['\u{1e942}', '\0', '\0']), ('\u{1e921}', ['\u{1e943}', '\0', '\0']) - ]; - - #[rustfmt::skip] - const to_uppercase_table: &[(char, [char; 3])] = &[ - ('\u{61}', ['\u{41}', '\0', '\0']), ('\u{62}', ['\u{42}', '\0', '\0']), ('\u{63}', - ['\u{43}', '\0', '\0']), ('\u{64}', ['\u{44}', '\0', '\0']), ('\u{65}', ['\u{45}', '\0', - '\0']), ('\u{66}', ['\u{46}', '\0', '\0']), ('\u{67}', ['\u{47}', '\0', '\0']), ('\u{68}', - ['\u{48}', '\0', '\0']), ('\u{69}', ['\u{49}', '\0', '\0']), ('\u{6a}', ['\u{4a}', '\0', - '\0']), ('\u{6b}', ['\u{4b}', '\0', '\0']), ('\u{6c}', ['\u{4c}', '\0', '\0']), ('\u{6d}', - ['\u{4d}', '\0', '\0']), ('\u{6e}', ['\u{4e}', '\0', '\0']), ('\u{6f}', ['\u{4f}', '\0', - '\0']), ('\u{70}', ['\u{50}', '\0', '\0']), ('\u{71}', ['\u{51}', '\0', '\0']), ('\u{72}', - ['\u{52}', '\0', '\0']), ('\u{73}', ['\u{53}', '\0', '\0']), ('\u{74}', ['\u{54}', '\0', - '\0']), ('\u{75}', ['\u{55}', '\0', '\0']), ('\u{76}', ['\u{56}', '\0', '\0']), ('\u{77}', - ['\u{57}', '\0', '\0']), ('\u{78}', ['\u{58}', '\0', '\0']), ('\u{79}', ['\u{59}', '\0', - '\0']), ('\u{7a}', ['\u{5a}', '\0', '\0']), ('\u{b5}', ['\u{39c}', '\0', '\0']), ('\u{df}', - ['\u{53}', '\u{53}', '\0']), ('\u{e0}', ['\u{c0}', '\0', '\0']), ('\u{e1}', ['\u{c1}', '\0', - '\0']), ('\u{e2}', ['\u{c2}', '\0', '\0']), ('\u{e3}', ['\u{c3}', '\0', '\0']), ('\u{e4}', - ['\u{c4}', '\0', '\0']), ('\u{e5}', ['\u{c5}', '\0', '\0']), ('\u{e6}', ['\u{c6}', '\0', - '\0']), ('\u{e7}', ['\u{c7}', '\0', '\0']), ('\u{e8}', ['\u{c8}', '\0', '\0']), ('\u{e9}', - ['\u{c9}', '\0', '\0']), ('\u{ea}', ['\u{ca}', '\0', '\0']), ('\u{eb}', ['\u{cb}', '\0', - '\0']), ('\u{ec}', ['\u{cc}', '\0', '\0']), ('\u{ed}', ['\u{cd}', '\0', '\0']), ('\u{ee}', - ['\u{ce}', '\0', '\0']), ('\u{ef}', ['\u{cf}', '\0', '\0']), ('\u{f0}', ['\u{d0}', '\0', - '\0']), ('\u{f1}', ['\u{d1}', '\0', '\0']), ('\u{f2}', ['\u{d2}', '\0', '\0']), ('\u{f3}', - ['\u{d3}', '\0', '\0']), ('\u{f4}', ['\u{d4}', '\0', '\0']), ('\u{f5}', ['\u{d5}', '\0', - '\0']), ('\u{f6}', ['\u{d6}', '\0', '\0']), ('\u{f8}', ['\u{d8}', '\0', '\0']), ('\u{f9}', - ['\u{d9}', '\0', '\0']), ('\u{fa}', ['\u{da}', '\0', '\0']), ('\u{fb}', ['\u{db}', '\0', - '\0']), ('\u{fc}', ['\u{dc}', '\0', '\0']), ('\u{fd}', ['\u{dd}', '\0', '\0']), ('\u{fe}', - ['\u{de}', '\0', '\0']), ('\u{ff}', ['\u{178}', '\0', '\0']), ('\u{101}', ['\u{100}', '\0', - '\0']), ('\u{103}', ['\u{102}', '\0', '\0']), ('\u{105}', ['\u{104}', '\0', '\0']), - ('\u{107}', ['\u{106}', '\0', '\0']), ('\u{109}', ['\u{108}', '\0', '\0']), ('\u{10b}', - ['\u{10a}', '\0', '\0']), ('\u{10d}', ['\u{10c}', '\0', '\0']), ('\u{10f}', ['\u{10e}', - '\0', '\0']), ('\u{111}', ['\u{110}', '\0', '\0']), ('\u{113}', ['\u{112}', '\0', '\0']), - ('\u{115}', ['\u{114}', '\0', '\0']), ('\u{117}', ['\u{116}', '\0', '\0']), ('\u{119}', - ['\u{118}', '\0', '\0']), ('\u{11b}', ['\u{11a}', '\0', '\0']), ('\u{11d}', ['\u{11c}', - '\0', '\0']), ('\u{11f}', ['\u{11e}', '\0', '\0']), ('\u{121}', ['\u{120}', '\0', '\0']), - ('\u{123}', ['\u{122}', '\0', '\0']), ('\u{125}', ['\u{124}', '\0', '\0']), ('\u{127}', - ['\u{126}', '\0', '\0']), ('\u{129}', ['\u{128}', '\0', '\0']), ('\u{12b}', ['\u{12a}', - '\0', '\0']), ('\u{12d}', ['\u{12c}', '\0', '\0']), ('\u{12f}', ['\u{12e}', '\0', '\0']), - ('\u{131}', ['\u{49}', '\0', '\0']), ('\u{133}', ['\u{132}', '\0', '\0']), ('\u{135}', - ['\u{134}', '\0', '\0']), ('\u{137}', ['\u{136}', '\0', '\0']), ('\u{13a}', ['\u{139}', - '\0', '\0']), ('\u{13c}', ['\u{13b}', '\0', '\0']), ('\u{13e}', ['\u{13d}', '\0', '\0']), - ('\u{140}', ['\u{13f}', '\0', '\0']), ('\u{142}', ['\u{141}', '\0', '\0']), ('\u{144}', - ['\u{143}', '\0', '\0']), ('\u{146}', ['\u{145}', '\0', '\0']), ('\u{148}', ['\u{147}', - '\0', '\0']), ('\u{149}', ['\u{2bc}', '\u{4e}', '\0']), ('\u{14b}', ['\u{14a}', '\0', - '\0']), ('\u{14d}', ['\u{14c}', '\0', '\0']), ('\u{14f}', ['\u{14e}', '\0', '\0']), - ('\u{151}', ['\u{150}', '\0', '\0']), ('\u{153}', ['\u{152}', '\0', '\0']), ('\u{155}', - ['\u{154}', '\0', '\0']), ('\u{157}', ['\u{156}', '\0', '\0']), ('\u{159}', ['\u{158}', - '\0', '\0']), ('\u{15b}', ['\u{15a}', '\0', '\0']), ('\u{15d}', ['\u{15c}', '\0', '\0']), - ('\u{15f}', ['\u{15e}', '\0', '\0']), ('\u{161}', ['\u{160}', '\0', '\0']), ('\u{163}', - ['\u{162}', '\0', '\0']), ('\u{165}', ['\u{164}', '\0', '\0']), ('\u{167}', ['\u{166}', - '\0', '\0']), ('\u{169}', ['\u{168}', '\0', '\0']), ('\u{16b}', ['\u{16a}', '\0', '\0']), - ('\u{16d}', ['\u{16c}', '\0', '\0']), ('\u{16f}', ['\u{16e}', '\0', '\0']), ('\u{171}', - ['\u{170}', '\0', '\0']), ('\u{173}', ['\u{172}', '\0', '\0']), ('\u{175}', ['\u{174}', - '\0', '\0']), ('\u{177}', ['\u{176}', '\0', '\0']), ('\u{17a}', ['\u{179}', '\0', '\0']), - ('\u{17c}', ['\u{17b}', '\0', '\0']), ('\u{17e}', ['\u{17d}', '\0', '\0']), ('\u{17f}', - ['\u{53}', '\0', '\0']), ('\u{180}', ['\u{243}', '\0', '\0']), ('\u{183}', ['\u{182}', '\0', - '\0']), ('\u{185}', ['\u{184}', '\0', '\0']), ('\u{188}', ['\u{187}', '\0', '\0']), - ('\u{18c}', ['\u{18b}', '\0', '\0']), ('\u{192}', ['\u{191}', '\0', '\0']), ('\u{195}', - ['\u{1f6}', '\0', '\0']), ('\u{199}', ['\u{198}', '\0', '\0']), ('\u{19a}', ['\u{23d}', - '\0', '\0']), ('\u{19e}', ['\u{220}', '\0', '\0']), ('\u{1a1}', ['\u{1a0}', '\0', '\0']), - ('\u{1a3}', ['\u{1a2}', '\0', '\0']), ('\u{1a5}', ['\u{1a4}', '\0', '\0']), ('\u{1a8}', - ['\u{1a7}', '\0', '\0']), ('\u{1ad}', ['\u{1ac}', '\0', '\0']), ('\u{1b0}', ['\u{1af}', - '\0', '\0']), ('\u{1b4}', ['\u{1b3}', '\0', '\0']), ('\u{1b6}', ['\u{1b5}', '\0', '\0']), - ('\u{1b9}', ['\u{1b8}', '\0', '\0']), ('\u{1bd}', ['\u{1bc}', '\0', '\0']), ('\u{1bf}', - ['\u{1f7}', '\0', '\0']), ('\u{1c5}', ['\u{1c4}', '\0', '\0']), ('\u{1c6}', ['\u{1c4}', - '\0', '\0']), ('\u{1c8}', ['\u{1c7}', '\0', '\0']), ('\u{1c9}', ['\u{1c7}', '\0', '\0']), - ('\u{1cb}', ['\u{1ca}', '\0', '\0']), ('\u{1cc}', ['\u{1ca}', '\0', '\0']), ('\u{1ce}', - ['\u{1cd}', '\0', '\0']), ('\u{1d0}', ['\u{1cf}', '\0', '\0']), ('\u{1d2}', ['\u{1d1}', - '\0', '\0']), ('\u{1d4}', ['\u{1d3}', '\0', '\0']), ('\u{1d6}', ['\u{1d5}', '\0', '\0']), - ('\u{1d8}', ['\u{1d7}', '\0', '\0']), ('\u{1da}', ['\u{1d9}', '\0', '\0']), ('\u{1dc}', - ['\u{1db}', '\0', '\0']), ('\u{1dd}', ['\u{18e}', '\0', '\0']), ('\u{1df}', ['\u{1de}', - '\0', '\0']), ('\u{1e1}', ['\u{1e0}', '\0', '\0']), ('\u{1e3}', ['\u{1e2}', '\0', '\0']), - ('\u{1e5}', ['\u{1e4}', '\0', '\0']), ('\u{1e7}', ['\u{1e6}', '\0', '\0']), ('\u{1e9}', - ['\u{1e8}', '\0', '\0']), ('\u{1eb}', ['\u{1ea}', '\0', '\0']), ('\u{1ed}', ['\u{1ec}', - '\0', '\0']), ('\u{1ef}', ['\u{1ee}', '\0', '\0']), ('\u{1f0}', ['\u{4a}', '\u{30c}', - '\0']), ('\u{1f2}', ['\u{1f1}', '\0', '\0']), ('\u{1f3}', ['\u{1f1}', '\0', '\0']), - ('\u{1f5}', ['\u{1f4}', '\0', '\0']), ('\u{1f9}', ['\u{1f8}', '\0', '\0']), ('\u{1fb}', - ['\u{1fa}', '\0', '\0']), ('\u{1fd}', ['\u{1fc}', '\0', '\0']), ('\u{1ff}', ['\u{1fe}', - '\0', '\0']), ('\u{201}', ['\u{200}', '\0', '\0']), ('\u{203}', ['\u{202}', '\0', '\0']), - ('\u{205}', ['\u{204}', '\0', '\0']), ('\u{207}', ['\u{206}', '\0', '\0']), ('\u{209}', - ['\u{208}', '\0', '\0']), ('\u{20b}', ['\u{20a}', '\0', '\0']), ('\u{20d}', ['\u{20c}', - '\0', '\0']), ('\u{20f}', ['\u{20e}', '\0', '\0']), ('\u{211}', ['\u{210}', '\0', '\0']), - ('\u{213}', ['\u{212}', '\0', '\0']), ('\u{215}', ['\u{214}', '\0', '\0']), ('\u{217}', - ['\u{216}', '\0', '\0']), ('\u{219}', ['\u{218}', '\0', '\0']), ('\u{21b}', ['\u{21a}', - '\0', '\0']), ('\u{21d}', ['\u{21c}', '\0', '\0']), ('\u{21f}', ['\u{21e}', '\0', '\0']), - ('\u{223}', ['\u{222}', '\0', '\0']), ('\u{225}', ['\u{224}', '\0', '\0']), ('\u{227}', - ['\u{226}', '\0', '\0']), ('\u{229}', ['\u{228}', '\0', '\0']), ('\u{22b}', ['\u{22a}', - '\0', '\0']), ('\u{22d}', ['\u{22c}', '\0', '\0']), ('\u{22f}', ['\u{22e}', '\0', '\0']), - ('\u{231}', ['\u{230}', '\0', '\0']), ('\u{233}', ['\u{232}', '\0', '\0']), ('\u{23c}', - ['\u{23b}', '\0', '\0']), ('\u{23f}', ['\u{2c7e}', '\0', '\0']), ('\u{240}', ['\u{2c7f}', - '\0', '\0']), ('\u{242}', ['\u{241}', '\0', '\0']), ('\u{247}', ['\u{246}', '\0', '\0']), - ('\u{249}', ['\u{248}', '\0', '\0']), ('\u{24b}', ['\u{24a}', '\0', '\0']), ('\u{24d}', - ['\u{24c}', '\0', '\0']), ('\u{24f}', ['\u{24e}', '\0', '\0']), ('\u{250}', ['\u{2c6f}', - '\0', '\0']), ('\u{251}', ['\u{2c6d}', '\0', '\0']), ('\u{252}', ['\u{2c70}', '\0', '\0']), - ('\u{253}', ['\u{181}', '\0', '\0']), ('\u{254}', ['\u{186}', '\0', '\0']), ('\u{256}', - ['\u{189}', '\0', '\0']), ('\u{257}', ['\u{18a}', '\0', '\0']), ('\u{259}', ['\u{18f}', - '\0', '\0']), ('\u{25b}', ['\u{190}', '\0', '\0']), ('\u{25c}', ['\u{a7ab}', '\0', '\0']), - ('\u{260}', ['\u{193}', '\0', '\0']), ('\u{261}', ['\u{a7ac}', '\0', '\0']), ('\u{263}', - ['\u{194}', '\0', '\0']), ('\u{265}', ['\u{a78d}', '\0', '\0']), ('\u{266}', ['\u{a7aa}', - '\0', '\0']), ('\u{268}', ['\u{197}', '\0', '\0']), ('\u{269}', ['\u{196}', '\0', '\0']), - ('\u{26a}', ['\u{a7ae}', '\0', '\0']), ('\u{26b}', ['\u{2c62}', '\0', '\0']), ('\u{26c}', - ['\u{a7ad}', '\0', '\0']), ('\u{26f}', ['\u{19c}', '\0', '\0']), ('\u{271}', ['\u{2c6e}', - '\0', '\0']), ('\u{272}', ['\u{19d}', '\0', '\0']), ('\u{275}', ['\u{19f}', '\0', '\0']), - ('\u{27d}', ['\u{2c64}', '\0', '\0']), ('\u{280}', ['\u{1a6}', '\0', '\0']), ('\u{282}', - ['\u{a7c5}', '\0', '\0']), ('\u{283}', ['\u{1a9}', '\0', '\0']), ('\u{287}', ['\u{a7b1}', - '\0', '\0']), ('\u{288}', ['\u{1ae}', '\0', '\0']), ('\u{289}', ['\u{244}', '\0', '\0']), - ('\u{28a}', ['\u{1b1}', '\0', '\0']), ('\u{28b}', ['\u{1b2}', '\0', '\0']), ('\u{28c}', - ['\u{245}', '\0', '\0']), ('\u{292}', ['\u{1b7}', '\0', '\0']), ('\u{29d}', ['\u{a7b2}', - '\0', '\0']), ('\u{29e}', ['\u{a7b0}', '\0', '\0']), ('\u{345}', ['\u{399}', '\0', '\0']), - ('\u{371}', ['\u{370}', '\0', '\0']), ('\u{373}', ['\u{372}', '\0', '\0']), ('\u{377}', - ['\u{376}', '\0', '\0']), ('\u{37b}', ['\u{3fd}', '\0', '\0']), ('\u{37c}', ['\u{3fe}', - '\0', '\0']), ('\u{37d}', ['\u{3ff}', '\0', '\0']), ('\u{390}', ['\u{399}', '\u{308}', - '\u{301}']), ('\u{3ac}', ['\u{386}', '\0', '\0']), ('\u{3ad}', ['\u{388}', '\0', '\0']), - ('\u{3ae}', ['\u{389}', '\0', '\0']), ('\u{3af}', ['\u{38a}', '\0', '\0']), ('\u{3b0}', - ['\u{3a5}', '\u{308}', '\u{301}']), ('\u{3b1}', ['\u{391}', '\0', '\0']), ('\u{3b2}', - ['\u{392}', '\0', '\0']), ('\u{3b3}', ['\u{393}', '\0', '\0']), ('\u{3b4}', ['\u{394}', - '\0', '\0']), ('\u{3b5}', ['\u{395}', '\0', '\0']), ('\u{3b6}', ['\u{396}', '\0', '\0']), - ('\u{3b7}', ['\u{397}', '\0', '\0']), ('\u{3b8}', ['\u{398}', '\0', '\0']), ('\u{3b9}', - ['\u{399}', '\0', '\0']), ('\u{3ba}', ['\u{39a}', '\0', '\0']), ('\u{3bb}', ['\u{39b}', - '\0', '\0']), ('\u{3bc}', ['\u{39c}', '\0', '\0']), ('\u{3bd}', ['\u{39d}', '\0', '\0']), - ('\u{3be}', ['\u{39e}', '\0', '\0']), ('\u{3bf}', ['\u{39f}', '\0', '\0']), ('\u{3c0}', - ['\u{3a0}', '\0', '\0']), ('\u{3c1}', ['\u{3a1}', '\0', '\0']), ('\u{3c2}', ['\u{3a3}', - '\0', '\0']), ('\u{3c3}', ['\u{3a3}', '\0', '\0']), ('\u{3c4}', ['\u{3a4}', '\0', '\0']), - ('\u{3c5}', ['\u{3a5}', '\0', '\0']), ('\u{3c6}', ['\u{3a6}', '\0', '\0']), ('\u{3c7}', - ['\u{3a7}', '\0', '\0']), ('\u{3c8}', ['\u{3a8}', '\0', '\0']), ('\u{3c9}', ['\u{3a9}', - '\0', '\0']), ('\u{3ca}', ['\u{3aa}', '\0', '\0']), ('\u{3cb}', ['\u{3ab}', '\0', '\0']), - ('\u{3cc}', ['\u{38c}', '\0', '\0']), ('\u{3cd}', ['\u{38e}', '\0', '\0']), ('\u{3ce}', - ['\u{38f}', '\0', '\0']), ('\u{3d0}', ['\u{392}', '\0', '\0']), ('\u{3d1}', ['\u{398}', - '\0', '\0']), ('\u{3d5}', ['\u{3a6}', '\0', '\0']), ('\u{3d6}', ['\u{3a0}', '\0', '\0']), - ('\u{3d7}', ['\u{3cf}', '\0', '\0']), ('\u{3d9}', ['\u{3d8}', '\0', '\0']), ('\u{3db}', - ['\u{3da}', '\0', '\0']), ('\u{3dd}', ['\u{3dc}', '\0', '\0']), ('\u{3df}', ['\u{3de}', - '\0', '\0']), ('\u{3e1}', ['\u{3e0}', '\0', '\0']), ('\u{3e3}', ['\u{3e2}', '\0', '\0']), - ('\u{3e5}', ['\u{3e4}', '\0', '\0']), ('\u{3e7}', ['\u{3e6}', '\0', '\0']), ('\u{3e9}', - ['\u{3e8}', '\0', '\0']), ('\u{3eb}', ['\u{3ea}', '\0', '\0']), ('\u{3ed}', ['\u{3ec}', - '\0', '\0']), ('\u{3ef}', ['\u{3ee}', '\0', '\0']), ('\u{3f0}', ['\u{39a}', '\0', '\0']), - ('\u{3f1}', ['\u{3a1}', '\0', '\0']), ('\u{3f2}', ['\u{3f9}', '\0', '\0']), ('\u{3f3}', - ['\u{37f}', '\0', '\0']), ('\u{3f5}', ['\u{395}', '\0', '\0']), ('\u{3f8}', ['\u{3f7}', - '\0', '\0']), ('\u{3fb}', ['\u{3fa}', '\0', '\0']), ('\u{430}', ['\u{410}', '\0', '\0']), - ('\u{431}', ['\u{411}', '\0', '\0']), ('\u{432}', ['\u{412}', '\0', '\0']), ('\u{433}', - ['\u{413}', '\0', '\0']), ('\u{434}', ['\u{414}', '\0', '\0']), ('\u{435}', ['\u{415}', - '\0', '\0']), ('\u{436}', ['\u{416}', '\0', '\0']), ('\u{437}', ['\u{417}', '\0', '\0']), - ('\u{438}', ['\u{418}', '\0', '\0']), ('\u{439}', ['\u{419}', '\0', '\0']), ('\u{43a}', - ['\u{41a}', '\0', '\0']), ('\u{43b}', ['\u{41b}', '\0', '\0']), ('\u{43c}', ['\u{41c}', - '\0', '\0']), ('\u{43d}', ['\u{41d}', '\0', '\0']), ('\u{43e}', ['\u{41e}', '\0', '\0']), - ('\u{43f}', ['\u{41f}', '\0', '\0']), ('\u{440}', ['\u{420}', '\0', '\0']), ('\u{441}', - ['\u{421}', '\0', '\0']), ('\u{442}', ['\u{422}', '\0', '\0']), ('\u{443}', ['\u{423}', - '\0', '\0']), ('\u{444}', ['\u{424}', '\0', '\0']), ('\u{445}', ['\u{425}', '\0', '\0']), - ('\u{446}', ['\u{426}', '\0', '\0']), ('\u{447}', ['\u{427}', '\0', '\0']), ('\u{448}', - ['\u{428}', '\0', '\0']), ('\u{449}', ['\u{429}', '\0', '\0']), ('\u{44a}', ['\u{42a}', - '\0', '\0']), ('\u{44b}', ['\u{42b}', '\0', '\0']), ('\u{44c}', ['\u{42c}', '\0', '\0']), - ('\u{44d}', ['\u{42d}', '\0', '\0']), ('\u{44e}', ['\u{42e}', '\0', '\0']), ('\u{44f}', - ['\u{42f}', '\0', '\0']), ('\u{450}', ['\u{400}', '\0', '\0']), ('\u{451}', ['\u{401}', - '\0', '\0']), ('\u{452}', ['\u{402}', '\0', '\0']), ('\u{453}', ['\u{403}', '\0', '\0']), - ('\u{454}', ['\u{404}', '\0', '\0']), ('\u{455}', ['\u{405}', '\0', '\0']), ('\u{456}', - ['\u{406}', '\0', '\0']), ('\u{457}', ['\u{407}', '\0', '\0']), ('\u{458}', ['\u{408}', - '\0', '\0']), ('\u{459}', ['\u{409}', '\0', '\0']), ('\u{45a}', ['\u{40a}', '\0', '\0']), - ('\u{45b}', ['\u{40b}', '\0', '\0']), ('\u{45c}', ['\u{40c}', '\0', '\0']), ('\u{45d}', - ['\u{40d}', '\0', '\0']), ('\u{45e}', ['\u{40e}', '\0', '\0']), ('\u{45f}', ['\u{40f}', - '\0', '\0']), ('\u{461}', ['\u{460}', '\0', '\0']), ('\u{463}', ['\u{462}', '\0', '\0']), - ('\u{465}', ['\u{464}', '\0', '\0']), ('\u{467}', ['\u{466}', '\0', '\0']), ('\u{469}', - ['\u{468}', '\0', '\0']), ('\u{46b}', ['\u{46a}', '\0', '\0']), ('\u{46d}', ['\u{46c}', - '\0', '\0']), ('\u{46f}', ['\u{46e}', '\0', '\0']), ('\u{471}', ['\u{470}', '\0', '\0']), - ('\u{473}', ['\u{472}', '\0', '\0']), ('\u{475}', ['\u{474}', '\0', '\0']), ('\u{477}', - ['\u{476}', '\0', '\0']), ('\u{479}', ['\u{478}', '\0', '\0']), ('\u{47b}', ['\u{47a}', - '\0', '\0']), ('\u{47d}', ['\u{47c}', '\0', '\0']), ('\u{47f}', ['\u{47e}', '\0', '\0']), - ('\u{481}', ['\u{480}', '\0', '\0']), ('\u{48b}', ['\u{48a}', '\0', '\0']), ('\u{48d}', - ['\u{48c}', '\0', '\0']), ('\u{48f}', ['\u{48e}', '\0', '\0']), ('\u{491}', ['\u{490}', - '\0', '\0']), ('\u{493}', ['\u{492}', '\0', '\0']), ('\u{495}', ['\u{494}', '\0', '\0']), - ('\u{497}', ['\u{496}', '\0', '\0']), ('\u{499}', ['\u{498}', '\0', '\0']), ('\u{49b}', - ['\u{49a}', '\0', '\0']), ('\u{49d}', ['\u{49c}', '\0', '\0']), ('\u{49f}', ['\u{49e}', - '\0', '\0']), ('\u{4a1}', ['\u{4a0}', '\0', '\0']), ('\u{4a3}', ['\u{4a2}', '\0', '\0']), - ('\u{4a5}', ['\u{4a4}', '\0', '\0']), ('\u{4a7}', ['\u{4a6}', '\0', '\0']), ('\u{4a9}', - ['\u{4a8}', '\0', '\0']), ('\u{4ab}', ['\u{4aa}', '\0', '\0']), ('\u{4ad}', ['\u{4ac}', - '\0', '\0']), ('\u{4af}', ['\u{4ae}', '\0', '\0']), ('\u{4b1}', ['\u{4b0}', '\0', '\0']), - ('\u{4b3}', ['\u{4b2}', '\0', '\0']), ('\u{4b5}', ['\u{4b4}', '\0', '\0']), ('\u{4b7}', - ['\u{4b6}', '\0', '\0']), ('\u{4b9}', ['\u{4b8}', '\0', '\0']), ('\u{4bb}', ['\u{4ba}', - '\0', '\0']), ('\u{4bd}', ['\u{4bc}', '\0', '\0']), ('\u{4bf}', ['\u{4be}', '\0', '\0']), - ('\u{4c2}', ['\u{4c1}', '\0', '\0']), ('\u{4c4}', ['\u{4c3}', '\0', '\0']), ('\u{4c6}', - ['\u{4c5}', '\0', '\0']), ('\u{4c8}', ['\u{4c7}', '\0', '\0']), ('\u{4ca}', ['\u{4c9}', - '\0', '\0']), ('\u{4cc}', ['\u{4cb}', '\0', '\0']), ('\u{4ce}', ['\u{4cd}', '\0', '\0']), - ('\u{4cf}', ['\u{4c0}', '\0', '\0']), ('\u{4d1}', ['\u{4d0}', '\0', '\0']), ('\u{4d3}', - ['\u{4d2}', '\0', '\0']), ('\u{4d5}', ['\u{4d4}', '\0', '\0']), ('\u{4d7}', ['\u{4d6}', - '\0', '\0']), ('\u{4d9}', ['\u{4d8}', '\0', '\0']), ('\u{4db}', ['\u{4da}', '\0', '\0']), - ('\u{4dd}', ['\u{4dc}', '\0', '\0']), ('\u{4df}', ['\u{4de}', '\0', '\0']), ('\u{4e1}', - ['\u{4e0}', '\0', '\0']), ('\u{4e3}', ['\u{4e2}', '\0', '\0']), ('\u{4e5}', ['\u{4e4}', - '\0', '\0']), ('\u{4e7}', ['\u{4e6}', '\0', '\0']), ('\u{4e9}', ['\u{4e8}', '\0', '\0']), - ('\u{4eb}', ['\u{4ea}', '\0', '\0']), ('\u{4ed}', ['\u{4ec}', '\0', '\0']), ('\u{4ef}', - ['\u{4ee}', '\0', '\0']), ('\u{4f1}', ['\u{4f0}', '\0', '\0']), ('\u{4f3}', ['\u{4f2}', - '\0', '\0']), ('\u{4f5}', ['\u{4f4}', '\0', '\0']), ('\u{4f7}', ['\u{4f6}', '\0', '\0']), - ('\u{4f9}', ['\u{4f8}', '\0', '\0']), ('\u{4fb}', ['\u{4fa}', '\0', '\0']), ('\u{4fd}', - ['\u{4fc}', '\0', '\0']), ('\u{4ff}', ['\u{4fe}', '\0', '\0']), ('\u{501}', ['\u{500}', - '\0', '\0']), ('\u{503}', ['\u{502}', '\0', '\0']), ('\u{505}', ['\u{504}', '\0', '\0']), - ('\u{507}', ['\u{506}', '\0', '\0']), ('\u{509}', ['\u{508}', '\0', '\0']), ('\u{50b}', - ['\u{50a}', '\0', '\0']), ('\u{50d}', ['\u{50c}', '\0', '\0']), ('\u{50f}', ['\u{50e}', - '\0', '\0']), ('\u{511}', ['\u{510}', '\0', '\0']), ('\u{513}', ['\u{512}', '\0', '\0']), - ('\u{515}', ['\u{514}', '\0', '\0']), ('\u{517}', ['\u{516}', '\0', '\0']), ('\u{519}', - ['\u{518}', '\0', '\0']), ('\u{51b}', ['\u{51a}', '\0', '\0']), ('\u{51d}', ['\u{51c}', - '\0', '\0']), ('\u{51f}', ['\u{51e}', '\0', '\0']), ('\u{521}', ['\u{520}', '\0', '\0']), - ('\u{523}', ['\u{522}', '\0', '\0']), ('\u{525}', ['\u{524}', '\0', '\0']), ('\u{527}', - ['\u{526}', '\0', '\0']), ('\u{529}', ['\u{528}', '\0', '\0']), ('\u{52b}', ['\u{52a}', - '\0', '\0']), ('\u{52d}', ['\u{52c}', '\0', '\0']), ('\u{52f}', ['\u{52e}', '\0', '\0']), - ('\u{561}', ['\u{531}', '\0', '\0']), ('\u{562}', ['\u{532}', '\0', '\0']), ('\u{563}', - ['\u{533}', '\0', '\0']), ('\u{564}', ['\u{534}', '\0', '\0']), ('\u{565}', ['\u{535}', - '\0', '\0']), ('\u{566}', ['\u{536}', '\0', '\0']), ('\u{567}', ['\u{537}', '\0', '\0']), - ('\u{568}', ['\u{538}', '\0', '\0']), ('\u{569}', ['\u{539}', '\0', '\0']), ('\u{56a}', - ['\u{53a}', '\0', '\0']), ('\u{56b}', ['\u{53b}', '\0', '\0']), ('\u{56c}', ['\u{53c}', - '\0', '\0']), ('\u{56d}', ['\u{53d}', '\0', '\0']), ('\u{56e}', ['\u{53e}', '\0', '\0']), - ('\u{56f}', ['\u{53f}', '\0', '\0']), ('\u{570}', ['\u{540}', '\0', '\0']), ('\u{571}', - ['\u{541}', '\0', '\0']), ('\u{572}', ['\u{542}', '\0', '\0']), ('\u{573}', ['\u{543}', - '\0', '\0']), ('\u{574}', ['\u{544}', '\0', '\0']), ('\u{575}', ['\u{545}', '\0', '\0']), - ('\u{576}', ['\u{546}', '\0', '\0']), ('\u{577}', ['\u{547}', '\0', '\0']), ('\u{578}', - ['\u{548}', '\0', '\0']), ('\u{579}', ['\u{549}', '\0', '\0']), ('\u{57a}', ['\u{54a}', - '\0', '\0']), ('\u{57b}', ['\u{54b}', '\0', '\0']), ('\u{57c}', ['\u{54c}', '\0', '\0']), - ('\u{57d}', ['\u{54d}', '\0', '\0']), ('\u{57e}', ['\u{54e}', '\0', '\0']), ('\u{57f}', - ['\u{54f}', '\0', '\0']), ('\u{580}', ['\u{550}', '\0', '\0']), ('\u{581}', ['\u{551}', - '\0', '\0']), ('\u{582}', ['\u{552}', '\0', '\0']), ('\u{583}', ['\u{553}', '\0', '\0']), - ('\u{584}', ['\u{554}', '\0', '\0']), ('\u{585}', ['\u{555}', '\0', '\0']), ('\u{586}', - ['\u{556}', '\0', '\0']), ('\u{587}', ['\u{535}', '\u{552}', '\0']), ('\u{10d0}', - ['\u{1c90}', '\0', '\0']), ('\u{10d1}', ['\u{1c91}', '\0', '\0']), ('\u{10d2}', ['\u{1c92}', - '\0', '\0']), ('\u{10d3}', ['\u{1c93}', '\0', '\0']), ('\u{10d4}', ['\u{1c94}', '\0', - '\0']), ('\u{10d5}', ['\u{1c95}', '\0', '\0']), ('\u{10d6}', ['\u{1c96}', '\0', '\0']), - ('\u{10d7}', ['\u{1c97}', '\0', '\0']), ('\u{10d8}', ['\u{1c98}', '\0', '\0']), ('\u{10d9}', - ['\u{1c99}', '\0', '\0']), ('\u{10da}', ['\u{1c9a}', '\0', '\0']), ('\u{10db}', ['\u{1c9b}', - '\0', '\0']), ('\u{10dc}', ['\u{1c9c}', '\0', '\0']), ('\u{10dd}', ['\u{1c9d}', '\0', - '\0']), ('\u{10de}', ['\u{1c9e}', '\0', '\0']), ('\u{10df}', ['\u{1c9f}', '\0', '\0']), - ('\u{10e0}', ['\u{1ca0}', '\0', '\0']), ('\u{10e1}', ['\u{1ca1}', '\0', '\0']), ('\u{10e2}', - ['\u{1ca2}', '\0', '\0']), ('\u{10e3}', ['\u{1ca3}', '\0', '\0']), ('\u{10e4}', ['\u{1ca4}', - '\0', '\0']), ('\u{10e5}', ['\u{1ca5}', '\0', '\0']), ('\u{10e6}', ['\u{1ca6}', '\0', - '\0']), ('\u{10e7}', ['\u{1ca7}', '\0', '\0']), ('\u{10e8}', ['\u{1ca8}', '\0', '\0']), - ('\u{10e9}', ['\u{1ca9}', '\0', '\0']), ('\u{10ea}', ['\u{1caa}', '\0', '\0']), ('\u{10eb}', - ['\u{1cab}', '\0', '\0']), ('\u{10ec}', ['\u{1cac}', '\0', '\0']), ('\u{10ed}', ['\u{1cad}', - '\0', '\0']), ('\u{10ee}', ['\u{1cae}', '\0', '\0']), ('\u{10ef}', ['\u{1caf}', '\0', - '\0']), ('\u{10f0}', ['\u{1cb0}', '\0', '\0']), ('\u{10f1}', ['\u{1cb1}', '\0', '\0']), - ('\u{10f2}', ['\u{1cb2}', '\0', '\0']), ('\u{10f3}', ['\u{1cb3}', '\0', '\0']), ('\u{10f4}', - ['\u{1cb4}', '\0', '\0']), ('\u{10f5}', ['\u{1cb5}', '\0', '\0']), ('\u{10f6}', ['\u{1cb6}', - '\0', '\0']), ('\u{10f7}', ['\u{1cb7}', '\0', '\0']), ('\u{10f8}', ['\u{1cb8}', '\0', - '\0']), ('\u{10f9}', ['\u{1cb9}', '\0', '\0']), ('\u{10fa}', ['\u{1cba}', '\0', '\0']), - ('\u{10fd}', ['\u{1cbd}', '\0', '\0']), ('\u{10fe}', ['\u{1cbe}', '\0', '\0']), ('\u{10ff}', - ['\u{1cbf}', '\0', '\0']), ('\u{13f8}', ['\u{13f0}', '\0', '\0']), ('\u{13f9}', ['\u{13f1}', - '\0', '\0']), ('\u{13fa}', ['\u{13f2}', '\0', '\0']), ('\u{13fb}', ['\u{13f3}', '\0', - '\0']), ('\u{13fc}', ['\u{13f4}', '\0', '\0']), ('\u{13fd}', ['\u{13f5}', '\0', '\0']), - ('\u{1c80}', ['\u{412}', '\0', '\0']), ('\u{1c81}', ['\u{414}', '\0', '\0']), ('\u{1c82}', - ['\u{41e}', '\0', '\0']), ('\u{1c83}', ['\u{421}', '\0', '\0']), ('\u{1c84}', ['\u{422}', - '\0', '\0']), ('\u{1c85}', ['\u{422}', '\0', '\0']), ('\u{1c86}', ['\u{42a}', '\0', '\0']), - ('\u{1c87}', ['\u{462}', '\0', '\0']), ('\u{1c88}', ['\u{a64a}', '\0', '\0']), ('\u{1d79}', - ['\u{a77d}', '\0', '\0']), ('\u{1d7d}', ['\u{2c63}', '\0', '\0']), ('\u{1d8e}', ['\u{a7c6}', - '\0', '\0']), ('\u{1e01}', ['\u{1e00}', '\0', '\0']), ('\u{1e03}', ['\u{1e02}', '\0', - '\0']), ('\u{1e05}', ['\u{1e04}', '\0', '\0']), ('\u{1e07}', ['\u{1e06}', '\0', '\0']), - ('\u{1e09}', ['\u{1e08}', '\0', '\0']), ('\u{1e0b}', ['\u{1e0a}', '\0', '\0']), ('\u{1e0d}', - ['\u{1e0c}', '\0', '\0']), ('\u{1e0f}', ['\u{1e0e}', '\0', '\0']), ('\u{1e11}', ['\u{1e10}', - '\0', '\0']), ('\u{1e13}', ['\u{1e12}', '\0', '\0']), ('\u{1e15}', ['\u{1e14}', '\0', - '\0']), ('\u{1e17}', ['\u{1e16}', '\0', '\0']), ('\u{1e19}', ['\u{1e18}', '\0', '\0']), - ('\u{1e1b}', ['\u{1e1a}', '\0', '\0']), ('\u{1e1d}', ['\u{1e1c}', '\0', '\0']), ('\u{1e1f}', - ['\u{1e1e}', '\0', '\0']), ('\u{1e21}', ['\u{1e20}', '\0', '\0']), ('\u{1e23}', ['\u{1e22}', - '\0', '\0']), ('\u{1e25}', ['\u{1e24}', '\0', '\0']), ('\u{1e27}', ['\u{1e26}', '\0', - '\0']), ('\u{1e29}', ['\u{1e28}', '\0', '\0']), ('\u{1e2b}', ['\u{1e2a}', '\0', '\0']), - ('\u{1e2d}', ['\u{1e2c}', '\0', '\0']), ('\u{1e2f}', ['\u{1e2e}', '\0', '\0']), ('\u{1e31}', - ['\u{1e30}', '\0', '\0']), ('\u{1e33}', ['\u{1e32}', '\0', '\0']), ('\u{1e35}', ['\u{1e34}', - '\0', '\0']), ('\u{1e37}', ['\u{1e36}', '\0', '\0']), ('\u{1e39}', ['\u{1e38}', '\0', - '\0']), ('\u{1e3b}', ['\u{1e3a}', '\0', '\0']), ('\u{1e3d}', ['\u{1e3c}', '\0', '\0']), - ('\u{1e3f}', ['\u{1e3e}', '\0', '\0']), ('\u{1e41}', ['\u{1e40}', '\0', '\0']), ('\u{1e43}', - ['\u{1e42}', '\0', '\0']), ('\u{1e45}', ['\u{1e44}', '\0', '\0']), ('\u{1e47}', ['\u{1e46}', - '\0', '\0']), ('\u{1e49}', ['\u{1e48}', '\0', '\0']), ('\u{1e4b}', ['\u{1e4a}', '\0', - '\0']), ('\u{1e4d}', ['\u{1e4c}', '\0', '\0']), ('\u{1e4f}', ['\u{1e4e}', '\0', '\0']), - ('\u{1e51}', ['\u{1e50}', '\0', '\0']), ('\u{1e53}', ['\u{1e52}', '\0', '\0']), ('\u{1e55}', - ['\u{1e54}', '\0', '\0']), ('\u{1e57}', ['\u{1e56}', '\0', '\0']), ('\u{1e59}', ['\u{1e58}', - '\0', '\0']), ('\u{1e5b}', ['\u{1e5a}', '\0', '\0']), ('\u{1e5d}', ['\u{1e5c}', '\0', - '\0']), ('\u{1e5f}', ['\u{1e5e}', '\0', '\0']), ('\u{1e61}', ['\u{1e60}', '\0', '\0']), - ('\u{1e63}', ['\u{1e62}', '\0', '\0']), ('\u{1e65}', ['\u{1e64}', '\0', '\0']), ('\u{1e67}', - ['\u{1e66}', '\0', '\0']), ('\u{1e69}', ['\u{1e68}', '\0', '\0']), ('\u{1e6b}', ['\u{1e6a}', - '\0', '\0']), ('\u{1e6d}', ['\u{1e6c}', '\0', '\0']), ('\u{1e6f}', ['\u{1e6e}', '\0', - '\0']), ('\u{1e71}', ['\u{1e70}', '\0', '\0']), ('\u{1e73}', ['\u{1e72}', '\0', '\0']), - ('\u{1e75}', ['\u{1e74}', '\0', '\0']), ('\u{1e77}', ['\u{1e76}', '\0', '\0']), ('\u{1e79}', - ['\u{1e78}', '\0', '\0']), ('\u{1e7b}', ['\u{1e7a}', '\0', '\0']), ('\u{1e7d}', ['\u{1e7c}', - '\0', '\0']), ('\u{1e7f}', ['\u{1e7e}', '\0', '\0']), ('\u{1e81}', ['\u{1e80}', '\0', - '\0']), ('\u{1e83}', ['\u{1e82}', '\0', '\0']), ('\u{1e85}', ['\u{1e84}', '\0', '\0']), - ('\u{1e87}', ['\u{1e86}', '\0', '\0']), ('\u{1e89}', ['\u{1e88}', '\0', '\0']), ('\u{1e8b}', - ['\u{1e8a}', '\0', '\0']), ('\u{1e8d}', ['\u{1e8c}', '\0', '\0']), ('\u{1e8f}', ['\u{1e8e}', - '\0', '\0']), ('\u{1e91}', ['\u{1e90}', '\0', '\0']), ('\u{1e93}', ['\u{1e92}', '\0', - '\0']), ('\u{1e95}', ['\u{1e94}', '\0', '\0']), ('\u{1e96}', ['\u{48}', '\u{331}', '\0']), - ('\u{1e97}', ['\u{54}', '\u{308}', '\0']), ('\u{1e98}', ['\u{57}', '\u{30a}', '\0']), - ('\u{1e99}', ['\u{59}', '\u{30a}', '\0']), ('\u{1e9a}', ['\u{41}', '\u{2be}', '\0']), - ('\u{1e9b}', ['\u{1e60}', '\0', '\0']), ('\u{1ea1}', ['\u{1ea0}', '\0', '\0']), ('\u{1ea3}', - ['\u{1ea2}', '\0', '\0']), ('\u{1ea5}', ['\u{1ea4}', '\0', '\0']), ('\u{1ea7}', ['\u{1ea6}', - '\0', '\0']), ('\u{1ea9}', ['\u{1ea8}', '\0', '\0']), ('\u{1eab}', ['\u{1eaa}', '\0', - '\0']), ('\u{1ead}', ['\u{1eac}', '\0', '\0']), ('\u{1eaf}', ['\u{1eae}', '\0', '\0']), - ('\u{1eb1}', ['\u{1eb0}', '\0', '\0']), ('\u{1eb3}', ['\u{1eb2}', '\0', '\0']), ('\u{1eb5}', - ['\u{1eb4}', '\0', '\0']), ('\u{1eb7}', ['\u{1eb6}', '\0', '\0']), ('\u{1eb9}', ['\u{1eb8}', - '\0', '\0']), ('\u{1ebb}', ['\u{1eba}', '\0', '\0']), ('\u{1ebd}', ['\u{1ebc}', '\0', - '\0']), ('\u{1ebf}', ['\u{1ebe}', '\0', '\0']), ('\u{1ec1}', ['\u{1ec0}', '\0', '\0']), - ('\u{1ec3}', ['\u{1ec2}', '\0', '\0']), ('\u{1ec5}', ['\u{1ec4}', '\0', '\0']), ('\u{1ec7}', - ['\u{1ec6}', '\0', '\0']), ('\u{1ec9}', ['\u{1ec8}', '\0', '\0']), ('\u{1ecb}', ['\u{1eca}', - '\0', '\0']), ('\u{1ecd}', ['\u{1ecc}', '\0', '\0']), ('\u{1ecf}', ['\u{1ece}', '\0', - '\0']), ('\u{1ed1}', ['\u{1ed0}', '\0', '\0']), ('\u{1ed3}', ['\u{1ed2}', '\0', '\0']), - ('\u{1ed5}', ['\u{1ed4}', '\0', '\0']), ('\u{1ed7}', ['\u{1ed6}', '\0', '\0']), ('\u{1ed9}', - ['\u{1ed8}', '\0', '\0']), ('\u{1edb}', ['\u{1eda}', '\0', '\0']), ('\u{1edd}', ['\u{1edc}', - '\0', '\0']), ('\u{1edf}', ['\u{1ede}', '\0', '\0']), ('\u{1ee1}', ['\u{1ee0}', '\0', - '\0']), ('\u{1ee3}', ['\u{1ee2}', '\0', '\0']), ('\u{1ee5}', ['\u{1ee4}', '\0', '\0']), - ('\u{1ee7}', ['\u{1ee6}', '\0', '\0']), ('\u{1ee9}', ['\u{1ee8}', '\0', '\0']), ('\u{1eeb}', - ['\u{1eea}', '\0', '\0']), ('\u{1eed}', ['\u{1eec}', '\0', '\0']), ('\u{1eef}', ['\u{1eee}', - '\0', '\0']), ('\u{1ef1}', ['\u{1ef0}', '\0', '\0']), ('\u{1ef3}', ['\u{1ef2}', '\0', - '\0']), ('\u{1ef5}', ['\u{1ef4}', '\0', '\0']), ('\u{1ef7}', ['\u{1ef6}', '\0', '\0']), - ('\u{1ef9}', ['\u{1ef8}', '\0', '\0']), ('\u{1efb}', ['\u{1efa}', '\0', '\0']), ('\u{1efd}', - ['\u{1efc}', '\0', '\0']), ('\u{1eff}', ['\u{1efe}', '\0', '\0']), ('\u{1f00}', ['\u{1f08}', - '\0', '\0']), ('\u{1f01}', ['\u{1f09}', '\0', '\0']), ('\u{1f02}', ['\u{1f0a}', '\0', - '\0']), ('\u{1f03}', ['\u{1f0b}', '\0', '\0']), ('\u{1f04}', ['\u{1f0c}', '\0', '\0']), - ('\u{1f05}', ['\u{1f0d}', '\0', '\0']), ('\u{1f06}', ['\u{1f0e}', '\0', '\0']), ('\u{1f07}', - ['\u{1f0f}', '\0', '\0']), ('\u{1f10}', ['\u{1f18}', '\0', '\0']), ('\u{1f11}', ['\u{1f19}', - '\0', '\0']), ('\u{1f12}', ['\u{1f1a}', '\0', '\0']), ('\u{1f13}', ['\u{1f1b}', '\0', - '\0']), ('\u{1f14}', ['\u{1f1c}', '\0', '\0']), ('\u{1f15}', ['\u{1f1d}', '\0', '\0']), - ('\u{1f20}', ['\u{1f28}', '\0', '\0']), ('\u{1f21}', ['\u{1f29}', '\0', '\0']), ('\u{1f22}', - ['\u{1f2a}', '\0', '\0']), ('\u{1f23}', ['\u{1f2b}', '\0', '\0']), ('\u{1f24}', ['\u{1f2c}', - '\0', '\0']), ('\u{1f25}', ['\u{1f2d}', '\0', '\0']), ('\u{1f26}', ['\u{1f2e}', '\0', - '\0']), ('\u{1f27}', ['\u{1f2f}', '\0', '\0']), ('\u{1f30}', ['\u{1f38}', '\0', '\0']), - ('\u{1f31}', ['\u{1f39}', '\0', '\0']), ('\u{1f32}', ['\u{1f3a}', '\0', '\0']), ('\u{1f33}', - ['\u{1f3b}', '\0', '\0']), ('\u{1f34}', ['\u{1f3c}', '\0', '\0']), ('\u{1f35}', ['\u{1f3d}', - '\0', '\0']), ('\u{1f36}', ['\u{1f3e}', '\0', '\0']), ('\u{1f37}', ['\u{1f3f}', '\0', - '\0']), ('\u{1f40}', ['\u{1f48}', '\0', '\0']), ('\u{1f41}', ['\u{1f49}', '\0', '\0']), - ('\u{1f42}', ['\u{1f4a}', '\0', '\0']), ('\u{1f43}', ['\u{1f4b}', '\0', '\0']), ('\u{1f44}', - ['\u{1f4c}', '\0', '\0']), ('\u{1f45}', ['\u{1f4d}', '\0', '\0']), ('\u{1f50}', ['\u{3a5}', - '\u{313}', '\0']), ('\u{1f51}', ['\u{1f59}', '\0', '\0']), ('\u{1f52}', ['\u{3a5}', - '\u{313}', '\u{300}']), ('\u{1f53}', ['\u{1f5b}', '\0', '\0']), ('\u{1f54}', ['\u{3a5}', - '\u{313}', '\u{301}']), ('\u{1f55}', ['\u{1f5d}', '\0', '\0']), ('\u{1f56}', ['\u{3a5}', - '\u{313}', '\u{342}']), ('\u{1f57}', ['\u{1f5f}', '\0', '\0']), ('\u{1f60}', ['\u{1f68}', - '\0', '\0']), ('\u{1f61}', ['\u{1f69}', '\0', '\0']), ('\u{1f62}', ['\u{1f6a}', '\0', - '\0']), ('\u{1f63}', ['\u{1f6b}', '\0', '\0']), ('\u{1f64}', ['\u{1f6c}', '\0', '\0']), - ('\u{1f65}', ['\u{1f6d}', '\0', '\0']), ('\u{1f66}', ['\u{1f6e}', '\0', '\0']), ('\u{1f67}', - ['\u{1f6f}', '\0', '\0']), ('\u{1f70}', ['\u{1fba}', '\0', '\0']), ('\u{1f71}', ['\u{1fbb}', - '\0', '\0']), ('\u{1f72}', ['\u{1fc8}', '\0', '\0']), ('\u{1f73}', ['\u{1fc9}', '\0', - '\0']), ('\u{1f74}', ['\u{1fca}', '\0', '\0']), ('\u{1f75}', ['\u{1fcb}', '\0', '\0']), - ('\u{1f76}', ['\u{1fda}', '\0', '\0']), ('\u{1f77}', ['\u{1fdb}', '\0', '\0']), ('\u{1f78}', - ['\u{1ff8}', '\0', '\0']), ('\u{1f79}', ['\u{1ff9}', '\0', '\0']), ('\u{1f7a}', ['\u{1fea}', - '\0', '\0']), ('\u{1f7b}', ['\u{1feb}', '\0', '\0']), ('\u{1f7c}', ['\u{1ffa}', '\0', - '\0']), ('\u{1f7d}', ['\u{1ffb}', '\0', '\0']), ('\u{1f80}', ['\u{1f08}', '\u{399}', '\0']), - ('\u{1f81}', ['\u{1f09}', '\u{399}', '\0']), ('\u{1f82}', ['\u{1f0a}', '\u{399}', '\0']), - ('\u{1f83}', ['\u{1f0b}', '\u{399}', '\0']), ('\u{1f84}', ['\u{1f0c}', '\u{399}', '\0']), - ('\u{1f85}', ['\u{1f0d}', '\u{399}', '\0']), ('\u{1f86}', ['\u{1f0e}', '\u{399}', '\0']), - ('\u{1f87}', ['\u{1f0f}', '\u{399}', '\0']), ('\u{1f88}', ['\u{1f08}', '\u{399}', '\0']), - ('\u{1f89}', ['\u{1f09}', '\u{399}', '\0']), ('\u{1f8a}', ['\u{1f0a}', '\u{399}', '\0']), - ('\u{1f8b}', ['\u{1f0b}', '\u{399}', '\0']), ('\u{1f8c}', ['\u{1f0c}', '\u{399}', '\0']), - ('\u{1f8d}', ['\u{1f0d}', '\u{399}', '\0']), ('\u{1f8e}', ['\u{1f0e}', '\u{399}', '\0']), - ('\u{1f8f}', ['\u{1f0f}', '\u{399}', '\0']), ('\u{1f90}', ['\u{1f28}', '\u{399}', '\0']), - ('\u{1f91}', ['\u{1f29}', '\u{399}', '\0']), ('\u{1f92}', ['\u{1f2a}', '\u{399}', '\0']), - ('\u{1f93}', ['\u{1f2b}', '\u{399}', '\0']), ('\u{1f94}', ['\u{1f2c}', '\u{399}', '\0']), - ('\u{1f95}', ['\u{1f2d}', '\u{399}', '\0']), ('\u{1f96}', ['\u{1f2e}', '\u{399}', '\0']), - ('\u{1f97}', ['\u{1f2f}', '\u{399}', '\0']), ('\u{1f98}', ['\u{1f28}', '\u{399}', '\0']), - ('\u{1f99}', ['\u{1f29}', '\u{399}', '\0']), ('\u{1f9a}', ['\u{1f2a}', '\u{399}', '\0']), - ('\u{1f9b}', ['\u{1f2b}', '\u{399}', '\0']), ('\u{1f9c}', ['\u{1f2c}', '\u{399}', '\0']), - ('\u{1f9d}', ['\u{1f2d}', '\u{399}', '\0']), ('\u{1f9e}', ['\u{1f2e}', '\u{399}', '\0']), - ('\u{1f9f}', ['\u{1f2f}', '\u{399}', '\0']), ('\u{1fa0}', ['\u{1f68}', '\u{399}', '\0']), - ('\u{1fa1}', ['\u{1f69}', '\u{399}', '\0']), ('\u{1fa2}', ['\u{1f6a}', '\u{399}', '\0']), - ('\u{1fa3}', ['\u{1f6b}', '\u{399}', '\0']), ('\u{1fa4}', ['\u{1f6c}', '\u{399}', '\0']), - ('\u{1fa5}', ['\u{1f6d}', '\u{399}', '\0']), ('\u{1fa6}', ['\u{1f6e}', '\u{399}', '\0']), - ('\u{1fa7}', ['\u{1f6f}', '\u{399}', '\0']), ('\u{1fa8}', ['\u{1f68}', '\u{399}', '\0']), - ('\u{1fa9}', ['\u{1f69}', '\u{399}', '\0']), ('\u{1faa}', ['\u{1f6a}', '\u{399}', '\0']), - ('\u{1fab}', ['\u{1f6b}', '\u{399}', '\0']), ('\u{1fac}', ['\u{1f6c}', '\u{399}', '\0']), - ('\u{1fad}', ['\u{1f6d}', '\u{399}', '\0']), ('\u{1fae}', ['\u{1f6e}', '\u{399}', '\0']), - ('\u{1faf}', ['\u{1f6f}', '\u{399}', '\0']), ('\u{1fb0}', ['\u{1fb8}', '\0', '\0']), - ('\u{1fb1}', ['\u{1fb9}', '\0', '\0']), ('\u{1fb2}', ['\u{1fba}', '\u{399}', '\0']), - ('\u{1fb3}', ['\u{391}', '\u{399}', '\0']), ('\u{1fb4}', ['\u{386}', '\u{399}', '\0']), - ('\u{1fb6}', ['\u{391}', '\u{342}', '\0']), ('\u{1fb7}', ['\u{391}', '\u{342}', '\u{399}']), - ('\u{1fbc}', ['\u{391}', '\u{399}', '\0']), ('\u{1fbe}', ['\u{399}', '\0', '\0']), - ('\u{1fc2}', ['\u{1fca}', '\u{399}', '\0']), ('\u{1fc3}', ['\u{397}', '\u{399}', '\0']), - ('\u{1fc4}', ['\u{389}', '\u{399}', '\0']), ('\u{1fc6}', ['\u{397}', '\u{342}', '\0']), - ('\u{1fc7}', ['\u{397}', '\u{342}', '\u{399}']), ('\u{1fcc}', ['\u{397}', '\u{399}', '\0']), - ('\u{1fd0}', ['\u{1fd8}', '\0', '\0']), ('\u{1fd1}', ['\u{1fd9}', '\0', '\0']), ('\u{1fd2}', - ['\u{399}', '\u{308}', '\u{300}']), ('\u{1fd3}', ['\u{399}', '\u{308}', '\u{301}']), - ('\u{1fd6}', ['\u{399}', '\u{342}', '\0']), ('\u{1fd7}', ['\u{399}', '\u{308}', '\u{342}']), - ('\u{1fe0}', ['\u{1fe8}', '\0', '\0']), ('\u{1fe1}', ['\u{1fe9}', '\0', '\0']), ('\u{1fe2}', - ['\u{3a5}', '\u{308}', '\u{300}']), ('\u{1fe3}', ['\u{3a5}', '\u{308}', '\u{301}']), - ('\u{1fe4}', ['\u{3a1}', '\u{313}', '\0']), ('\u{1fe5}', ['\u{1fec}', '\0', '\0']), - ('\u{1fe6}', ['\u{3a5}', '\u{342}', '\0']), ('\u{1fe7}', ['\u{3a5}', '\u{308}', '\u{342}']), - ('\u{1ff2}', ['\u{1ffa}', '\u{399}', '\0']), ('\u{1ff3}', ['\u{3a9}', '\u{399}', '\0']), - ('\u{1ff4}', ['\u{38f}', '\u{399}', '\0']), ('\u{1ff6}', ['\u{3a9}', '\u{342}', '\0']), - ('\u{1ff7}', ['\u{3a9}', '\u{342}', '\u{399}']), ('\u{1ffc}', ['\u{3a9}', '\u{399}', '\0']), - ('\u{214e}', ['\u{2132}', '\0', '\0']), ('\u{2170}', ['\u{2160}', '\0', '\0']), ('\u{2171}', - ['\u{2161}', '\0', '\0']), ('\u{2172}', ['\u{2162}', '\0', '\0']), ('\u{2173}', ['\u{2163}', - '\0', '\0']), ('\u{2174}', ['\u{2164}', '\0', '\0']), ('\u{2175}', ['\u{2165}', '\0', - '\0']), ('\u{2176}', ['\u{2166}', '\0', '\0']), ('\u{2177}', ['\u{2167}', '\0', '\0']), - ('\u{2178}', ['\u{2168}', '\0', '\0']), ('\u{2179}', ['\u{2169}', '\0', '\0']), ('\u{217a}', - ['\u{216a}', '\0', '\0']), ('\u{217b}', ['\u{216b}', '\0', '\0']), ('\u{217c}', ['\u{216c}', - '\0', '\0']), ('\u{217d}', ['\u{216d}', '\0', '\0']), ('\u{217e}', ['\u{216e}', '\0', - '\0']), ('\u{217f}', ['\u{216f}', '\0', '\0']), ('\u{2184}', ['\u{2183}', '\0', '\0']), - ('\u{24d0}', ['\u{24b6}', '\0', '\0']), ('\u{24d1}', ['\u{24b7}', '\0', '\0']), ('\u{24d2}', - ['\u{24b8}', '\0', '\0']), ('\u{24d3}', ['\u{24b9}', '\0', '\0']), ('\u{24d4}', ['\u{24ba}', - '\0', '\0']), ('\u{24d5}', ['\u{24bb}', '\0', '\0']), ('\u{24d6}', ['\u{24bc}', '\0', - '\0']), ('\u{24d7}', ['\u{24bd}', '\0', '\0']), ('\u{24d8}', ['\u{24be}', '\0', '\0']), - ('\u{24d9}', ['\u{24bf}', '\0', '\0']), ('\u{24da}', ['\u{24c0}', '\0', '\0']), ('\u{24db}', - ['\u{24c1}', '\0', '\0']), ('\u{24dc}', ['\u{24c2}', '\0', '\0']), ('\u{24dd}', ['\u{24c3}', - '\0', '\0']), ('\u{24de}', ['\u{24c4}', '\0', '\0']), ('\u{24df}', ['\u{24c5}', '\0', - '\0']), ('\u{24e0}', ['\u{24c6}', '\0', '\0']), ('\u{24e1}', ['\u{24c7}', '\0', '\0']), - ('\u{24e2}', ['\u{24c8}', '\0', '\0']), ('\u{24e3}', ['\u{24c9}', '\0', '\0']), ('\u{24e4}', - ['\u{24ca}', '\0', '\0']), ('\u{24e5}', ['\u{24cb}', '\0', '\0']), ('\u{24e6}', ['\u{24cc}', - '\0', '\0']), ('\u{24e7}', ['\u{24cd}', '\0', '\0']), ('\u{24e8}', ['\u{24ce}', '\0', - '\0']), ('\u{24e9}', ['\u{24cf}', '\0', '\0']), ('\u{2c30}', ['\u{2c00}', '\0', '\0']), - ('\u{2c31}', ['\u{2c01}', '\0', '\0']), ('\u{2c32}', ['\u{2c02}', '\0', '\0']), ('\u{2c33}', - ['\u{2c03}', '\0', '\0']), ('\u{2c34}', ['\u{2c04}', '\0', '\0']), ('\u{2c35}', ['\u{2c05}', - '\0', '\0']), ('\u{2c36}', ['\u{2c06}', '\0', '\0']), ('\u{2c37}', ['\u{2c07}', '\0', - '\0']), ('\u{2c38}', ['\u{2c08}', '\0', '\0']), ('\u{2c39}', ['\u{2c09}', '\0', '\0']), - ('\u{2c3a}', ['\u{2c0a}', '\0', '\0']), ('\u{2c3b}', ['\u{2c0b}', '\0', '\0']), ('\u{2c3c}', - ['\u{2c0c}', '\0', '\0']), ('\u{2c3d}', ['\u{2c0d}', '\0', '\0']), ('\u{2c3e}', ['\u{2c0e}', - '\0', '\0']), ('\u{2c3f}', ['\u{2c0f}', '\0', '\0']), ('\u{2c40}', ['\u{2c10}', '\0', - '\0']), ('\u{2c41}', ['\u{2c11}', '\0', '\0']), ('\u{2c42}', ['\u{2c12}', '\0', '\0']), - ('\u{2c43}', ['\u{2c13}', '\0', '\0']), ('\u{2c44}', ['\u{2c14}', '\0', '\0']), ('\u{2c45}', - ['\u{2c15}', '\0', '\0']), ('\u{2c46}', ['\u{2c16}', '\0', '\0']), ('\u{2c47}', ['\u{2c17}', - '\0', '\0']), ('\u{2c48}', ['\u{2c18}', '\0', '\0']), ('\u{2c49}', ['\u{2c19}', '\0', - '\0']), ('\u{2c4a}', ['\u{2c1a}', '\0', '\0']), ('\u{2c4b}', ['\u{2c1b}', '\0', '\0']), - ('\u{2c4c}', ['\u{2c1c}', '\0', '\0']), ('\u{2c4d}', ['\u{2c1d}', '\0', '\0']), ('\u{2c4e}', - ['\u{2c1e}', '\0', '\0']), ('\u{2c4f}', ['\u{2c1f}', '\0', '\0']), ('\u{2c50}', ['\u{2c20}', - '\0', '\0']), ('\u{2c51}', ['\u{2c21}', '\0', '\0']), ('\u{2c52}', ['\u{2c22}', '\0', - '\0']), ('\u{2c53}', ['\u{2c23}', '\0', '\0']), ('\u{2c54}', ['\u{2c24}', '\0', '\0']), - ('\u{2c55}', ['\u{2c25}', '\0', '\0']), ('\u{2c56}', ['\u{2c26}', '\0', '\0']), ('\u{2c57}', - ['\u{2c27}', '\0', '\0']), ('\u{2c58}', ['\u{2c28}', '\0', '\0']), ('\u{2c59}', ['\u{2c29}', - '\0', '\0']), ('\u{2c5a}', ['\u{2c2a}', '\0', '\0']), ('\u{2c5b}', ['\u{2c2b}', '\0', - '\0']), ('\u{2c5c}', ['\u{2c2c}', '\0', '\0']), ('\u{2c5d}', ['\u{2c2d}', '\0', '\0']), - ('\u{2c5e}', ['\u{2c2e}', '\0', '\0']), ('\u{2c61}', ['\u{2c60}', '\0', '\0']), ('\u{2c65}', - ['\u{23a}', '\0', '\0']), ('\u{2c66}', ['\u{23e}', '\0', '\0']), ('\u{2c68}', ['\u{2c67}', - '\0', '\0']), ('\u{2c6a}', ['\u{2c69}', '\0', '\0']), ('\u{2c6c}', ['\u{2c6b}', '\0', - '\0']), ('\u{2c73}', ['\u{2c72}', '\0', '\0']), ('\u{2c76}', ['\u{2c75}', '\0', '\0']), - ('\u{2c81}', ['\u{2c80}', '\0', '\0']), ('\u{2c83}', ['\u{2c82}', '\0', '\0']), ('\u{2c85}', - ['\u{2c84}', '\0', '\0']), ('\u{2c87}', ['\u{2c86}', '\0', '\0']), ('\u{2c89}', ['\u{2c88}', - '\0', '\0']), ('\u{2c8b}', ['\u{2c8a}', '\0', '\0']), ('\u{2c8d}', ['\u{2c8c}', '\0', - '\0']), ('\u{2c8f}', ['\u{2c8e}', '\0', '\0']), ('\u{2c91}', ['\u{2c90}', '\0', '\0']), - ('\u{2c93}', ['\u{2c92}', '\0', '\0']), ('\u{2c95}', ['\u{2c94}', '\0', '\0']), ('\u{2c97}', - ['\u{2c96}', '\0', '\0']), ('\u{2c99}', ['\u{2c98}', '\0', '\0']), ('\u{2c9b}', ['\u{2c9a}', - '\0', '\0']), ('\u{2c9d}', ['\u{2c9c}', '\0', '\0']), ('\u{2c9f}', ['\u{2c9e}', '\0', - '\0']), ('\u{2ca1}', ['\u{2ca0}', '\0', '\0']), ('\u{2ca3}', ['\u{2ca2}', '\0', '\0']), - ('\u{2ca5}', ['\u{2ca4}', '\0', '\0']), ('\u{2ca7}', ['\u{2ca6}', '\0', '\0']), ('\u{2ca9}', - ['\u{2ca8}', '\0', '\0']), ('\u{2cab}', ['\u{2caa}', '\0', '\0']), ('\u{2cad}', ['\u{2cac}', - '\0', '\0']), ('\u{2caf}', ['\u{2cae}', '\0', '\0']), ('\u{2cb1}', ['\u{2cb0}', '\0', - '\0']), ('\u{2cb3}', ['\u{2cb2}', '\0', '\0']), ('\u{2cb5}', ['\u{2cb4}', '\0', '\0']), - ('\u{2cb7}', ['\u{2cb6}', '\0', '\0']), ('\u{2cb9}', ['\u{2cb8}', '\0', '\0']), ('\u{2cbb}', - ['\u{2cba}', '\0', '\0']), ('\u{2cbd}', ['\u{2cbc}', '\0', '\0']), ('\u{2cbf}', ['\u{2cbe}', - '\0', '\0']), ('\u{2cc1}', ['\u{2cc0}', '\0', '\0']), ('\u{2cc3}', ['\u{2cc2}', '\0', - '\0']), ('\u{2cc5}', ['\u{2cc4}', '\0', '\0']), ('\u{2cc7}', ['\u{2cc6}', '\0', '\0']), - ('\u{2cc9}', ['\u{2cc8}', '\0', '\0']), ('\u{2ccb}', ['\u{2cca}', '\0', '\0']), ('\u{2ccd}', - ['\u{2ccc}', '\0', '\0']), ('\u{2ccf}', ['\u{2cce}', '\0', '\0']), ('\u{2cd1}', ['\u{2cd0}', - '\0', '\0']), ('\u{2cd3}', ['\u{2cd2}', '\0', '\0']), ('\u{2cd5}', ['\u{2cd4}', '\0', - '\0']), ('\u{2cd7}', ['\u{2cd6}', '\0', '\0']), ('\u{2cd9}', ['\u{2cd8}', '\0', '\0']), - ('\u{2cdb}', ['\u{2cda}', '\0', '\0']), ('\u{2cdd}', ['\u{2cdc}', '\0', '\0']), ('\u{2cdf}', - ['\u{2cde}', '\0', '\0']), ('\u{2ce1}', ['\u{2ce0}', '\0', '\0']), ('\u{2ce3}', ['\u{2ce2}', - '\0', '\0']), ('\u{2cec}', ['\u{2ceb}', '\0', '\0']), ('\u{2cee}', ['\u{2ced}', '\0', - '\0']), ('\u{2cf3}', ['\u{2cf2}', '\0', '\0']), ('\u{2d00}', ['\u{10a0}', '\0', '\0']), - ('\u{2d01}', ['\u{10a1}', '\0', '\0']), ('\u{2d02}', ['\u{10a2}', '\0', '\0']), ('\u{2d03}', - ['\u{10a3}', '\0', '\0']), ('\u{2d04}', ['\u{10a4}', '\0', '\0']), ('\u{2d05}', ['\u{10a5}', - '\0', '\0']), ('\u{2d06}', ['\u{10a6}', '\0', '\0']), ('\u{2d07}', ['\u{10a7}', '\0', - '\0']), ('\u{2d08}', ['\u{10a8}', '\0', '\0']), ('\u{2d09}', ['\u{10a9}', '\0', '\0']), - ('\u{2d0a}', ['\u{10aa}', '\0', '\0']), ('\u{2d0b}', ['\u{10ab}', '\0', '\0']), ('\u{2d0c}', - ['\u{10ac}', '\0', '\0']), ('\u{2d0d}', ['\u{10ad}', '\0', '\0']), ('\u{2d0e}', ['\u{10ae}', - '\0', '\0']), ('\u{2d0f}', ['\u{10af}', '\0', '\0']), ('\u{2d10}', ['\u{10b0}', '\0', - '\0']), ('\u{2d11}', ['\u{10b1}', '\0', '\0']), ('\u{2d12}', ['\u{10b2}', '\0', '\0']), - ('\u{2d13}', ['\u{10b3}', '\0', '\0']), ('\u{2d14}', ['\u{10b4}', '\0', '\0']), ('\u{2d15}', - ['\u{10b5}', '\0', '\0']), ('\u{2d16}', ['\u{10b6}', '\0', '\0']), ('\u{2d17}', ['\u{10b7}', - '\0', '\0']), ('\u{2d18}', ['\u{10b8}', '\0', '\0']), ('\u{2d19}', ['\u{10b9}', '\0', - '\0']), ('\u{2d1a}', ['\u{10ba}', '\0', '\0']), ('\u{2d1b}', ['\u{10bb}', '\0', '\0']), - ('\u{2d1c}', ['\u{10bc}', '\0', '\0']), ('\u{2d1d}', ['\u{10bd}', '\0', '\0']), ('\u{2d1e}', - ['\u{10be}', '\0', '\0']), ('\u{2d1f}', ['\u{10bf}', '\0', '\0']), ('\u{2d20}', ['\u{10c0}', - '\0', '\0']), ('\u{2d21}', ['\u{10c1}', '\0', '\0']), ('\u{2d22}', ['\u{10c2}', '\0', - '\0']), ('\u{2d23}', ['\u{10c3}', '\0', '\0']), ('\u{2d24}', ['\u{10c4}', '\0', '\0']), - ('\u{2d25}', ['\u{10c5}', '\0', '\0']), ('\u{2d27}', ['\u{10c7}', '\0', '\0']), ('\u{2d2d}', - ['\u{10cd}', '\0', '\0']), ('\u{a641}', ['\u{a640}', '\0', '\0']), ('\u{a643}', ['\u{a642}', - '\0', '\0']), ('\u{a645}', ['\u{a644}', '\0', '\0']), ('\u{a647}', ['\u{a646}', '\0', - '\0']), ('\u{a649}', ['\u{a648}', '\0', '\0']), ('\u{a64b}', ['\u{a64a}', '\0', '\0']), - ('\u{a64d}', ['\u{a64c}', '\0', '\0']), ('\u{a64f}', ['\u{a64e}', '\0', '\0']), ('\u{a651}', - ['\u{a650}', '\0', '\0']), ('\u{a653}', ['\u{a652}', '\0', '\0']), ('\u{a655}', ['\u{a654}', - '\0', '\0']), ('\u{a657}', ['\u{a656}', '\0', '\0']), ('\u{a659}', ['\u{a658}', '\0', - '\0']), ('\u{a65b}', ['\u{a65a}', '\0', '\0']), ('\u{a65d}', ['\u{a65c}', '\0', '\0']), - ('\u{a65f}', ['\u{a65e}', '\0', '\0']), ('\u{a661}', ['\u{a660}', '\0', '\0']), ('\u{a663}', - ['\u{a662}', '\0', '\0']), ('\u{a665}', ['\u{a664}', '\0', '\0']), ('\u{a667}', ['\u{a666}', - '\0', '\0']), ('\u{a669}', ['\u{a668}', '\0', '\0']), ('\u{a66b}', ['\u{a66a}', '\0', - '\0']), ('\u{a66d}', ['\u{a66c}', '\0', '\0']), ('\u{a681}', ['\u{a680}', '\0', '\0']), - ('\u{a683}', ['\u{a682}', '\0', '\0']), ('\u{a685}', ['\u{a684}', '\0', '\0']), ('\u{a687}', - ['\u{a686}', '\0', '\0']), ('\u{a689}', ['\u{a688}', '\0', '\0']), ('\u{a68b}', ['\u{a68a}', - '\0', '\0']), ('\u{a68d}', ['\u{a68c}', '\0', '\0']), ('\u{a68f}', ['\u{a68e}', '\0', - '\0']), ('\u{a691}', ['\u{a690}', '\0', '\0']), ('\u{a693}', ['\u{a692}', '\0', '\0']), - ('\u{a695}', ['\u{a694}', '\0', '\0']), ('\u{a697}', ['\u{a696}', '\0', '\0']), ('\u{a699}', - ['\u{a698}', '\0', '\0']), ('\u{a69b}', ['\u{a69a}', '\0', '\0']), ('\u{a723}', ['\u{a722}', - '\0', '\0']), ('\u{a725}', ['\u{a724}', '\0', '\0']), ('\u{a727}', ['\u{a726}', '\0', - '\0']), ('\u{a729}', ['\u{a728}', '\0', '\0']), ('\u{a72b}', ['\u{a72a}', '\0', '\0']), - ('\u{a72d}', ['\u{a72c}', '\0', '\0']), ('\u{a72f}', ['\u{a72e}', '\0', '\0']), ('\u{a733}', - ['\u{a732}', '\0', '\0']), ('\u{a735}', ['\u{a734}', '\0', '\0']), ('\u{a737}', ['\u{a736}', - '\0', '\0']), ('\u{a739}', ['\u{a738}', '\0', '\0']), ('\u{a73b}', ['\u{a73a}', '\0', - '\0']), ('\u{a73d}', ['\u{a73c}', '\0', '\0']), ('\u{a73f}', ['\u{a73e}', '\0', '\0']), - ('\u{a741}', ['\u{a740}', '\0', '\0']), ('\u{a743}', ['\u{a742}', '\0', '\0']), ('\u{a745}', - ['\u{a744}', '\0', '\0']), ('\u{a747}', ['\u{a746}', '\0', '\0']), ('\u{a749}', ['\u{a748}', - '\0', '\0']), ('\u{a74b}', ['\u{a74a}', '\0', '\0']), ('\u{a74d}', ['\u{a74c}', '\0', - '\0']), ('\u{a74f}', ['\u{a74e}', '\0', '\0']), ('\u{a751}', ['\u{a750}', '\0', '\0']), - ('\u{a753}', ['\u{a752}', '\0', '\0']), ('\u{a755}', ['\u{a754}', '\0', '\0']), ('\u{a757}', - ['\u{a756}', '\0', '\0']), ('\u{a759}', ['\u{a758}', '\0', '\0']), ('\u{a75b}', ['\u{a75a}', - '\0', '\0']), ('\u{a75d}', ['\u{a75c}', '\0', '\0']), ('\u{a75f}', ['\u{a75e}', '\0', - '\0']), ('\u{a761}', ['\u{a760}', '\0', '\0']), ('\u{a763}', ['\u{a762}', '\0', '\0']), - ('\u{a765}', ['\u{a764}', '\0', '\0']), ('\u{a767}', ['\u{a766}', '\0', '\0']), ('\u{a769}', - ['\u{a768}', '\0', '\0']), ('\u{a76b}', ['\u{a76a}', '\0', '\0']), ('\u{a76d}', ['\u{a76c}', - '\0', '\0']), ('\u{a76f}', ['\u{a76e}', '\0', '\0']), ('\u{a77a}', ['\u{a779}', '\0', - '\0']), ('\u{a77c}', ['\u{a77b}', '\0', '\0']), ('\u{a77f}', ['\u{a77e}', '\0', '\0']), - ('\u{a781}', ['\u{a780}', '\0', '\0']), ('\u{a783}', ['\u{a782}', '\0', '\0']), ('\u{a785}', - ['\u{a784}', '\0', '\0']), ('\u{a787}', ['\u{a786}', '\0', '\0']), ('\u{a78c}', ['\u{a78b}', - '\0', '\0']), ('\u{a791}', ['\u{a790}', '\0', '\0']), ('\u{a793}', ['\u{a792}', '\0', - '\0']), ('\u{a794}', ['\u{a7c4}', '\0', '\0']), ('\u{a797}', ['\u{a796}', '\0', '\0']), - ('\u{a799}', ['\u{a798}', '\0', '\0']), ('\u{a79b}', ['\u{a79a}', '\0', '\0']), ('\u{a79d}', - ['\u{a79c}', '\0', '\0']), ('\u{a79f}', ['\u{a79e}', '\0', '\0']), ('\u{a7a1}', ['\u{a7a0}', - '\0', '\0']), ('\u{a7a3}', ['\u{a7a2}', '\0', '\0']), ('\u{a7a5}', ['\u{a7a4}', '\0', - '\0']), ('\u{a7a7}', ['\u{a7a6}', '\0', '\0']), ('\u{a7a9}', ['\u{a7a8}', '\0', '\0']), - ('\u{a7b5}', ['\u{a7b4}', '\0', '\0']), ('\u{a7b7}', ['\u{a7b6}', '\0', '\0']), ('\u{a7b9}', - ['\u{a7b8}', '\0', '\0']), ('\u{a7bb}', ['\u{a7ba}', '\0', '\0']), ('\u{a7bd}', ['\u{a7bc}', - '\0', '\0']), ('\u{a7bf}', ['\u{a7be}', '\0', '\0']), ('\u{a7c3}', ['\u{a7c2}', '\0', - '\0']), ('\u{ab53}', ['\u{a7b3}', '\0', '\0']), ('\u{ab70}', ['\u{13a0}', '\0', '\0']), - ('\u{ab71}', ['\u{13a1}', '\0', '\0']), ('\u{ab72}', ['\u{13a2}', '\0', '\0']), ('\u{ab73}', - ['\u{13a3}', '\0', '\0']), ('\u{ab74}', ['\u{13a4}', '\0', '\0']), ('\u{ab75}', ['\u{13a5}', - '\0', '\0']), ('\u{ab76}', ['\u{13a6}', '\0', '\0']), ('\u{ab77}', ['\u{13a7}', '\0', - '\0']), ('\u{ab78}', ['\u{13a8}', '\0', '\0']), ('\u{ab79}', ['\u{13a9}', '\0', '\0']), - ('\u{ab7a}', ['\u{13aa}', '\0', '\0']), ('\u{ab7b}', ['\u{13ab}', '\0', '\0']), ('\u{ab7c}', - ['\u{13ac}', '\0', '\0']), ('\u{ab7d}', ['\u{13ad}', '\0', '\0']), ('\u{ab7e}', ['\u{13ae}', - '\0', '\0']), ('\u{ab7f}', ['\u{13af}', '\0', '\0']), ('\u{ab80}', ['\u{13b0}', '\0', - '\0']), ('\u{ab81}', ['\u{13b1}', '\0', '\0']), ('\u{ab82}', ['\u{13b2}', '\0', '\0']), - ('\u{ab83}', ['\u{13b3}', '\0', '\0']), ('\u{ab84}', ['\u{13b4}', '\0', '\0']), ('\u{ab85}', - ['\u{13b5}', '\0', '\0']), ('\u{ab86}', ['\u{13b6}', '\0', '\0']), ('\u{ab87}', ['\u{13b7}', - '\0', '\0']), ('\u{ab88}', ['\u{13b8}', '\0', '\0']), ('\u{ab89}', ['\u{13b9}', '\0', - '\0']), ('\u{ab8a}', ['\u{13ba}', '\0', '\0']), ('\u{ab8b}', ['\u{13bb}', '\0', '\0']), - ('\u{ab8c}', ['\u{13bc}', '\0', '\0']), ('\u{ab8d}', ['\u{13bd}', '\0', '\0']), ('\u{ab8e}', - ['\u{13be}', '\0', '\0']), ('\u{ab8f}', ['\u{13bf}', '\0', '\0']), ('\u{ab90}', ['\u{13c0}', - '\0', '\0']), ('\u{ab91}', ['\u{13c1}', '\0', '\0']), ('\u{ab92}', ['\u{13c2}', '\0', - '\0']), ('\u{ab93}', ['\u{13c3}', '\0', '\0']), ('\u{ab94}', ['\u{13c4}', '\0', '\0']), - ('\u{ab95}', ['\u{13c5}', '\0', '\0']), ('\u{ab96}', ['\u{13c6}', '\0', '\0']), ('\u{ab97}', - ['\u{13c7}', '\0', '\0']), ('\u{ab98}', ['\u{13c8}', '\0', '\0']), ('\u{ab99}', ['\u{13c9}', - '\0', '\0']), ('\u{ab9a}', ['\u{13ca}', '\0', '\0']), ('\u{ab9b}', ['\u{13cb}', '\0', - '\0']), ('\u{ab9c}', ['\u{13cc}', '\0', '\0']), ('\u{ab9d}', ['\u{13cd}', '\0', '\0']), - ('\u{ab9e}', ['\u{13ce}', '\0', '\0']), ('\u{ab9f}', ['\u{13cf}', '\0', '\0']), ('\u{aba0}', - ['\u{13d0}', '\0', '\0']), ('\u{aba1}', ['\u{13d1}', '\0', '\0']), ('\u{aba2}', ['\u{13d2}', - '\0', '\0']), ('\u{aba3}', ['\u{13d3}', '\0', '\0']), ('\u{aba4}', ['\u{13d4}', '\0', - '\0']), ('\u{aba5}', ['\u{13d5}', '\0', '\0']), ('\u{aba6}', ['\u{13d6}', '\0', '\0']), - ('\u{aba7}', ['\u{13d7}', '\0', '\0']), ('\u{aba8}', ['\u{13d8}', '\0', '\0']), ('\u{aba9}', - ['\u{13d9}', '\0', '\0']), ('\u{abaa}', ['\u{13da}', '\0', '\0']), ('\u{abab}', ['\u{13db}', - '\0', '\0']), ('\u{abac}', ['\u{13dc}', '\0', '\0']), ('\u{abad}', ['\u{13dd}', '\0', - '\0']), ('\u{abae}', ['\u{13de}', '\0', '\0']), ('\u{abaf}', ['\u{13df}', '\0', '\0']), - ('\u{abb0}', ['\u{13e0}', '\0', '\0']), ('\u{abb1}', ['\u{13e1}', '\0', '\0']), ('\u{abb2}', - ['\u{13e2}', '\0', '\0']), ('\u{abb3}', ['\u{13e3}', '\0', '\0']), ('\u{abb4}', ['\u{13e4}', - '\0', '\0']), ('\u{abb5}', ['\u{13e5}', '\0', '\0']), ('\u{abb6}', ['\u{13e6}', '\0', - '\0']), ('\u{abb7}', ['\u{13e7}', '\0', '\0']), ('\u{abb8}', ['\u{13e8}', '\0', '\0']), - ('\u{abb9}', ['\u{13e9}', '\0', '\0']), ('\u{abba}', ['\u{13ea}', '\0', '\0']), ('\u{abbb}', - ['\u{13eb}', '\0', '\0']), ('\u{abbc}', ['\u{13ec}', '\0', '\0']), ('\u{abbd}', ['\u{13ed}', - '\0', '\0']), ('\u{abbe}', ['\u{13ee}', '\0', '\0']), ('\u{abbf}', ['\u{13ef}', '\0', - '\0']), ('\u{fb00}', ['\u{46}', '\u{46}', '\0']), ('\u{fb01}', ['\u{46}', '\u{49}', '\0']), - ('\u{fb02}', ['\u{46}', '\u{4c}', '\0']), ('\u{fb03}', ['\u{46}', '\u{46}', '\u{49}']), - ('\u{fb04}', ['\u{46}', '\u{46}', '\u{4c}']), ('\u{fb05}', ['\u{53}', '\u{54}', '\0']), - ('\u{fb06}', ['\u{53}', '\u{54}', '\0']), ('\u{fb13}', ['\u{544}', '\u{546}', '\0']), - ('\u{fb14}', ['\u{544}', '\u{535}', '\0']), ('\u{fb15}', ['\u{544}', '\u{53b}', '\0']), - ('\u{fb16}', ['\u{54e}', '\u{546}', '\0']), ('\u{fb17}', ['\u{544}', '\u{53d}', '\0']), - ('\u{ff41}', ['\u{ff21}', '\0', '\0']), ('\u{ff42}', ['\u{ff22}', '\0', '\0']), ('\u{ff43}', - ['\u{ff23}', '\0', '\0']), ('\u{ff44}', ['\u{ff24}', '\0', '\0']), ('\u{ff45}', ['\u{ff25}', - '\0', '\0']), ('\u{ff46}', ['\u{ff26}', '\0', '\0']), ('\u{ff47}', ['\u{ff27}', '\0', - '\0']), ('\u{ff48}', ['\u{ff28}', '\0', '\0']), ('\u{ff49}', ['\u{ff29}', '\0', '\0']), - ('\u{ff4a}', ['\u{ff2a}', '\0', '\0']), ('\u{ff4b}', ['\u{ff2b}', '\0', '\0']), ('\u{ff4c}', - ['\u{ff2c}', '\0', '\0']), ('\u{ff4d}', ['\u{ff2d}', '\0', '\0']), ('\u{ff4e}', ['\u{ff2e}', - '\0', '\0']), ('\u{ff4f}', ['\u{ff2f}', '\0', '\0']), ('\u{ff50}', ['\u{ff30}', '\0', - '\0']), ('\u{ff51}', ['\u{ff31}', '\0', '\0']), ('\u{ff52}', ['\u{ff32}', '\0', '\0']), - ('\u{ff53}', ['\u{ff33}', '\0', '\0']), ('\u{ff54}', ['\u{ff34}', '\0', '\0']), ('\u{ff55}', - ['\u{ff35}', '\0', '\0']), ('\u{ff56}', ['\u{ff36}', '\0', '\0']), ('\u{ff57}', ['\u{ff37}', - '\0', '\0']), ('\u{ff58}', ['\u{ff38}', '\0', '\0']), ('\u{ff59}', ['\u{ff39}', '\0', - '\0']), ('\u{ff5a}', ['\u{ff3a}', '\0', '\0']), ('\u{10428}', ['\u{10400}', '\0', '\0']), - ('\u{10429}', ['\u{10401}', '\0', '\0']), ('\u{1042a}', ['\u{10402}', '\0', '\0']), - ('\u{1042b}', ['\u{10403}', '\0', '\0']), ('\u{1042c}', ['\u{10404}', '\0', '\0']), - ('\u{1042d}', ['\u{10405}', '\0', '\0']), ('\u{1042e}', ['\u{10406}', '\0', '\0']), - ('\u{1042f}', ['\u{10407}', '\0', '\0']), ('\u{10430}', ['\u{10408}', '\0', '\0']), - ('\u{10431}', ['\u{10409}', '\0', '\0']), ('\u{10432}', ['\u{1040a}', '\0', '\0']), - ('\u{10433}', ['\u{1040b}', '\0', '\0']), ('\u{10434}', ['\u{1040c}', '\0', '\0']), - ('\u{10435}', ['\u{1040d}', '\0', '\0']), ('\u{10436}', ['\u{1040e}', '\0', '\0']), - ('\u{10437}', ['\u{1040f}', '\0', '\0']), ('\u{10438}', ['\u{10410}', '\0', '\0']), - ('\u{10439}', ['\u{10411}', '\0', '\0']), ('\u{1043a}', ['\u{10412}', '\0', '\0']), - ('\u{1043b}', ['\u{10413}', '\0', '\0']), ('\u{1043c}', ['\u{10414}', '\0', '\0']), - ('\u{1043d}', ['\u{10415}', '\0', '\0']), ('\u{1043e}', ['\u{10416}', '\0', '\0']), - ('\u{1043f}', ['\u{10417}', '\0', '\0']), ('\u{10440}', ['\u{10418}', '\0', '\0']), - ('\u{10441}', ['\u{10419}', '\0', '\0']), ('\u{10442}', ['\u{1041a}', '\0', '\0']), - ('\u{10443}', ['\u{1041b}', '\0', '\0']), ('\u{10444}', ['\u{1041c}', '\0', '\0']), - ('\u{10445}', ['\u{1041d}', '\0', '\0']), ('\u{10446}', ['\u{1041e}', '\0', '\0']), - ('\u{10447}', ['\u{1041f}', '\0', '\0']), ('\u{10448}', ['\u{10420}', '\0', '\0']), - ('\u{10449}', ['\u{10421}', '\0', '\0']), ('\u{1044a}', ['\u{10422}', '\0', '\0']), - ('\u{1044b}', ['\u{10423}', '\0', '\0']), ('\u{1044c}', ['\u{10424}', '\0', '\0']), - ('\u{1044d}', ['\u{10425}', '\0', '\0']), ('\u{1044e}', ['\u{10426}', '\0', '\0']), - ('\u{1044f}', ['\u{10427}', '\0', '\0']), ('\u{104d8}', ['\u{104b0}', '\0', '\0']), - ('\u{104d9}', ['\u{104b1}', '\0', '\0']), ('\u{104da}', ['\u{104b2}', '\0', '\0']), - ('\u{104db}', ['\u{104b3}', '\0', '\0']), ('\u{104dc}', ['\u{104b4}', '\0', '\0']), - ('\u{104dd}', ['\u{104b5}', '\0', '\0']), ('\u{104de}', ['\u{104b6}', '\0', '\0']), - ('\u{104df}', ['\u{104b7}', '\0', '\0']), ('\u{104e0}', ['\u{104b8}', '\0', '\0']), - ('\u{104e1}', ['\u{104b9}', '\0', '\0']), ('\u{104e2}', ['\u{104ba}', '\0', '\0']), - ('\u{104e3}', ['\u{104bb}', '\0', '\0']), ('\u{104e4}', ['\u{104bc}', '\0', '\0']), - ('\u{104e5}', ['\u{104bd}', '\0', '\0']), ('\u{104e6}', ['\u{104be}', '\0', '\0']), - ('\u{104e7}', ['\u{104bf}', '\0', '\0']), ('\u{104e8}', ['\u{104c0}', '\0', '\0']), - ('\u{104e9}', ['\u{104c1}', '\0', '\0']), ('\u{104ea}', ['\u{104c2}', '\0', '\0']), - ('\u{104eb}', ['\u{104c3}', '\0', '\0']), ('\u{104ec}', ['\u{104c4}', '\0', '\0']), - ('\u{104ed}', ['\u{104c5}', '\0', '\0']), ('\u{104ee}', ['\u{104c6}', '\0', '\0']), - ('\u{104ef}', ['\u{104c7}', '\0', '\0']), ('\u{104f0}', ['\u{104c8}', '\0', '\0']), - ('\u{104f1}', ['\u{104c9}', '\0', '\0']), ('\u{104f2}', ['\u{104ca}', '\0', '\0']), - ('\u{104f3}', ['\u{104cb}', '\0', '\0']), ('\u{104f4}', ['\u{104cc}', '\0', '\0']), - ('\u{104f5}', ['\u{104cd}', '\0', '\0']), ('\u{104f6}', ['\u{104ce}', '\0', '\0']), - ('\u{104f7}', ['\u{104cf}', '\0', '\0']), ('\u{104f8}', ['\u{104d0}', '\0', '\0']), - ('\u{104f9}', ['\u{104d1}', '\0', '\0']), ('\u{104fa}', ['\u{104d2}', '\0', '\0']), - ('\u{104fb}', ['\u{104d3}', '\0', '\0']), ('\u{10cc0}', ['\u{10c80}', '\0', '\0']), - ('\u{10cc1}', ['\u{10c81}', '\0', '\0']), ('\u{10cc2}', ['\u{10c82}', '\0', '\0']), - ('\u{10cc3}', ['\u{10c83}', '\0', '\0']), ('\u{10cc4}', ['\u{10c84}', '\0', '\0']), - ('\u{10cc5}', ['\u{10c85}', '\0', '\0']), ('\u{10cc6}', ['\u{10c86}', '\0', '\0']), - ('\u{10cc7}', ['\u{10c87}', '\0', '\0']), ('\u{10cc8}', ['\u{10c88}', '\0', '\0']), - ('\u{10cc9}', ['\u{10c89}', '\0', '\0']), ('\u{10cca}', ['\u{10c8a}', '\0', '\0']), - ('\u{10ccb}', ['\u{10c8b}', '\0', '\0']), ('\u{10ccc}', ['\u{10c8c}', '\0', '\0']), - ('\u{10ccd}', ['\u{10c8d}', '\0', '\0']), ('\u{10cce}', ['\u{10c8e}', '\0', '\0']), - ('\u{10ccf}', ['\u{10c8f}', '\0', '\0']), ('\u{10cd0}', ['\u{10c90}', '\0', '\0']), - ('\u{10cd1}', ['\u{10c91}', '\0', '\0']), ('\u{10cd2}', ['\u{10c92}', '\0', '\0']), - ('\u{10cd3}', ['\u{10c93}', '\0', '\0']), ('\u{10cd4}', ['\u{10c94}', '\0', '\0']), - ('\u{10cd5}', ['\u{10c95}', '\0', '\0']), ('\u{10cd6}', ['\u{10c96}', '\0', '\0']), - ('\u{10cd7}', ['\u{10c97}', '\0', '\0']), ('\u{10cd8}', ['\u{10c98}', '\0', '\0']), - ('\u{10cd9}', ['\u{10c99}', '\0', '\0']), ('\u{10cda}', ['\u{10c9a}', '\0', '\0']), - ('\u{10cdb}', ['\u{10c9b}', '\0', '\0']), ('\u{10cdc}', ['\u{10c9c}', '\0', '\0']), - ('\u{10cdd}', ['\u{10c9d}', '\0', '\0']), ('\u{10cde}', ['\u{10c9e}', '\0', '\0']), - ('\u{10cdf}', ['\u{10c9f}', '\0', '\0']), ('\u{10ce0}', ['\u{10ca0}', '\0', '\0']), - ('\u{10ce1}', ['\u{10ca1}', '\0', '\0']), ('\u{10ce2}', ['\u{10ca2}', '\0', '\0']), - ('\u{10ce3}', ['\u{10ca3}', '\0', '\0']), ('\u{10ce4}', ['\u{10ca4}', '\0', '\0']), - ('\u{10ce5}', ['\u{10ca5}', '\0', '\0']), ('\u{10ce6}', ['\u{10ca6}', '\0', '\0']), - ('\u{10ce7}', ['\u{10ca7}', '\0', '\0']), ('\u{10ce8}', ['\u{10ca8}', '\0', '\0']), - ('\u{10ce9}', ['\u{10ca9}', '\0', '\0']), ('\u{10cea}', ['\u{10caa}', '\0', '\0']), - ('\u{10ceb}', ['\u{10cab}', '\0', '\0']), ('\u{10cec}', ['\u{10cac}', '\0', '\0']), - ('\u{10ced}', ['\u{10cad}', '\0', '\0']), ('\u{10cee}', ['\u{10cae}', '\0', '\0']), - ('\u{10cef}', ['\u{10caf}', '\0', '\0']), ('\u{10cf0}', ['\u{10cb0}', '\0', '\0']), - ('\u{10cf1}', ['\u{10cb1}', '\0', '\0']), ('\u{10cf2}', ['\u{10cb2}', '\0', '\0']), - ('\u{118c0}', ['\u{118a0}', '\0', '\0']), ('\u{118c1}', ['\u{118a1}', '\0', '\0']), - ('\u{118c2}', ['\u{118a2}', '\0', '\0']), ('\u{118c3}', ['\u{118a3}', '\0', '\0']), - ('\u{118c4}', ['\u{118a4}', '\0', '\0']), ('\u{118c5}', ['\u{118a5}', '\0', '\0']), - ('\u{118c6}', ['\u{118a6}', '\0', '\0']), ('\u{118c7}', ['\u{118a7}', '\0', '\0']), - ('\u{118c8}', ['\u{118a8}', '\0', '\0']), ('\u{118c9}', ['\u{118a9}', '\0', '\0']), - ('\u{118ca}', ['\u{118aa}', '\0', '\0']), ('\u{118cb}', ['\u{118ab}', '\0', '\0']), - ('\u{118cc}', ['\u{118ac}', '\0', '\0']), ('\u{118cd}', ['\u{118ad}', '\0', '\0']), - ('\u{118ce}', ['\u{118ae}', '\0', '\0']), ('\u{118cf}', ['\u{118af}', '\0', '\0']), - ('\u{118d0}', ['\u{118b0}', '\0', '\0']), ('\u{118d1}', ['\u{118b1}', '\0', '\0']), - ('\u{118d2}', ['\u{118b2}', '\0', '\0']), ('\u{118d3}', ['\u{118b3}', '\0', '\0']), - ('\u{118d4}', ['\u{118b4}', '\0', '\0']), ('\u{118d5}', ['\u{118b5}', '\0', '\0']), - ('\u{118d6}', ['\u{118b6}', '\0', '\0']), ('\u{118d7}', ['\u{118b7}', '\0', '\0']), - ('\u{118d8}', ['\u{118b8}', '\0', '\0']), ('\u{118d9}', ['\u{118b9}', '\0', '\0']), - ('\u{118da}', ['\u{118ba}', '\0', '\0']), ('\u{118db}', ['\u{118bb}', '\0', '\0']), - ('\u{118dc}', ['\u{118bc}', '\0', '\0']), ('\u{118dd}', ['\u{118bd}', '\0', '\0']), - ('\u{118de}', ['\u{118be}', '\0', '\0']), ('\u{118df}', ['\u{118bf}', '\0', '\0']), - ('\u{16e60}', ['\u{16e40}', '\0', '\0']), ('\u{16e61}', ['\u{16e41}', '\0', '\0']), - ('\u{16e62}', ['\u{16e42}', '\0', '\0']), ('\u{16e63}', ['\u{16e43}', '\0', '\0']), - ('\u{16e64}', ['\u{16e44}', '\0', '\0']), ('\u{16e65}', ['\u{16e45}', '\0', '\0']), - ('\u{16e66}', ['\u{16e46}', '\0', '\0']), ('\u{16e67}', ['\u{16e47}', '\0', '\0']), - ('\u{16e68}', ['\u{16e48}', '\0', '\0']), ('\u{16e69}', ['\u{16e49}', '\0', '\0']), - ('\u{16e6a}', ['\u{16e4a}', '\0', '\0']), ('\u{16e6b}', ['\u{16e4b}', '\0', '\0']), - ('\u{16e6c}', ['\u{16e4c}', '\0', '\0']), ('\u{16e6d}', ['\u{16e4d}', '\0', '\0']), - ('\u{16e6e}', ['\u{16e4e}', '\0', '\0']), ('\u{16e6f}', ['\u{16e4f}', '\0', '\0']), - ('\u{16e70}', ['\u{16e50}', '\0', '\0']), ('\u{16e71}', ['\u{16e51}', '\0', '\0']), - ('\u{16e72}', ['\u{16e52}', '\0', '\0']), ('\u{16e73}', ['\u{16e53}', '\0', '\0']), - ('\u{16e74}', ['\u{16e54}', '\0', '\0']), ('\u{16e75}', ['\u{16e55}', '\0', '\0']), - ('\u{16e76}', ['\u{16e56}', '\0', '\0']), ('\u{16e77}', ['\u{16e57}', '\0', '\0']), - ('\u{16e78}', ['\u{16e58}', '\0', '\0']), ('\u{16e79}', ['\u{16e59}', '\0', '\0']), - ('\u{16e7a}', ['\u{16e5a}', '\0', '\0']), ('\u{16e7b}', ['\u{16e5b}', '\0', '\0']), - ('\u{16e7c}', ['\u{16e5c}', '\0', '\0']), ('\u{16e7d}', ['\u{16e5d}', '\0', '\0']), - ('\u{16e7e}', ['\u{16e5e}', '\0', '\0']), ('\u{16e7f}', ['\u{16e5f}', '\0', '\0']), - ('\u{1e922}', ['\u{1e900}', '\0', '\0']), ('\u{1e923}', ['\u{1e901}', '\0', '\0']), - ('\u{1e924}', ['\u{1e902}', '\0', '\0']), ('\u{1e925}', ['\u{1e903}', '\0', '\0']), - ('\u{1e926}', ['\u{1e904}', '\0', '\0']), ('\u{1e927}', ['\u{1e905}', '\0', '\0']), - ('\u{1e928}', ['\u{1e906}', '\0', '\0']), ('\u{1e929}', ['\u{1e907}', '\0', '\0']), - ('\u{1e92a}', ['\u{1e908}', '\0', '\0']), ('\u{1e92b}', ['\u{1e909}', '\0', '\0']), - ('\u{1e92c}', ['\u{1e90a}', '\0', '\0']), ('\u{1e92d}', ['\u{1e90b}', '\0', '\0']), - ('\u{1e92e}', ['\u{1e90c}', '\0', '\0']), ('\u{1e92f}', ['\u{1e90d}', '\0', '\0']), - ('\u{1e930}', ['\u{1e90e}', '\0', '\0']), ('\u{1e931}', ['\u{1e90f}', '\0', '\0']), - ('\u{1e932}', ['\u{1e910}', '\0', '\0']), ('\u{1e933}', ['\u{1e911}', '\0', '\0']), - ('\u{1e934}', ['\u{1e912}', '\0', '\0']), ('\u{1e935}', ['\u{1e913}', '\0', '\0']), - ('\u{1e936}', ['\u{1e914}', '\0', '\0']), ('\u{1e937}', ['\u{1e915}', '\0', '\0']), - ('\u{1e938}', ['\u{1e916}', '\0', '\0']), ('\u{1e939}', ['\u{1e917}', '\0', '\0']), - ('\u{1e93a}', ['\u{1e918}', '\0', '\0']), ('\u{1e93b}', ['\u{1e919}', '\0', '\0']), - ('\u{1e93c}', ['\u{1e91a}', '\0', '\0']), ('\u{1e93d}', ['\u{1e91b}', '\0', '\0']), - ('\u{1e93e}', ['\u{1e91c}', '\0', '\0']), ('\u{1e93f}', ['\u{1e91d}', '\0', '\0']), - ('\u{1e940}', ['\u{1e91e}', '\0', '\0']), ('\u{1e941}', ['\u{1e91f}', '\0', '\0']), - ('\u{1e942}', ['\u{1e920}', '\0', '\0']), ('\u{1e943}', ['\u{1e921}', '\0', '\0']) - ]; -} diff --git a/src/libcore/unicode/unicode.py b/src/libcore/unicode/unicode.py deleted file mode 100755 index 97df92a56da66..0000000000000 --- a/src/libcore/unicode/unicode.py +++ /dev/null @@ -1,878 +0,0 @@ -#!/usr/bin/env python - -""" -Regenerate Unicode tables (tables.rs). -""" - -# This script uses the Unicode tables as defined -# in the UnicodeFiles class. - -# Since this should not require frequent updates, we just store this -# out-of-line and check the tables.rs file into git. - -# Note that the "curl" program is required for operation. -# This script is compatible with Python 2.7 and 3.x. - -import argparse -import datetime -import fileinput -import itertools -import os -import re -import textwrap -import subprocess - -from collections import defaultdict, namedtuple - -try: - # Python 3 - from itertools import zip_longest - from io import StringIO -except ImportError: - # Python 2 compatibility - zip_longest = itertools.izip_longest - from StringIO import StringIO - -try: - # Completely optional type hinting - # (Python 2 compatible using comments, - # see: https://mypy.readthedocs.io/en/latest/python2.html) - # This is very helpful in typing-aware IDE like PyCharm. - from typing import Any, Callable, Dict, Iterable, Iterator, List, Optional, Set, Tuple -except ImportError: - pass - - -# We don't use enum.Enum because of Python 2.7 compatibility. -class UnicodeFiles(object): - # ReadMe does not contain any Unicode data, we - # only use it to extract versions. - README = "ReadMe.txt" - - DERIVED_CORE_PROPERTIES = "DerivedCoreProperties.txt" - DERIVED_NORMALIZATION_PROPS = "DerivedNormalizationProps.txt" - PROPS = "PropList.txt" - SCRIPTS = "Scripts.txt" - SPECIAL_CASING = "SpecialCasing.txt" - UNICODE_DATA = "UnicodeData.txt" - - -# The order doesn't really matter (Python < 3.6 won't preserve it), -# we only want to aggregate all the file names. -ALL_UNICODE_FILES = tuple( - value for name, value in UnicodeFiles.__dict__.items() - if not name.startswith("_") -) - -assert len(ALL_UNICODE_FILES) == 7, "Unexpected number of unicode files" - -# The directory this file is located in. -THIS_DIR = os.path.dirname(os.path.realpath(__file__)) - -# Where to download the Unicode data. The downloaded files -# will be placed in sub-directories named after Unicode version. -FETCH_DIR = os.path.join(THIS_DIR, "downloaded") - -FETCH_URL_LATEST = "ftp://ftp.unicode.org/Public/UNIDATA/{filename}" -FETCH_URL_VERSION = "ftp://ftp.unicode.org/Public/{version}/ucd/{filename}" - -PREAMBLE = """\ -// NOTE: The following code was generated by "./unicode.py", do not edit directly - -#![allow(missing_docs, non_upper_case_globals, non_snake_case, clippy::unreadable_literal)] - -use crate::unicode::bool_trie::{{BoolTrie, SmallBoolTrie}}; -use crate::unicode::version::UnicodeVersion; -""".format(year=datetime.datetime.now().year) - -# Mapping taken from Table 12 from: -# http://www.unicode.org/reports/tr44/#General_Category_Values -EXPANDED_CATEGORIES = { - "Lu": ["LC", "L"], "Ll": ["LC", "L"], "Lt": ["LC", "L"], - "Lm": ["L"], "Lo": ["L"], - "Mn": ["M"], "Mc": ["M"], "Me": ["M"], - "Nd": ["N"], "Nl": ["N"], "No": ["N"], - "Pc": ["P"], "Pd": ["P"], "Ps": ["P"], "Pe": ["P"], - "Pi": ["P"], "Pf": ["P"], "Po": ["P"], - "Sm": ["S"], "Sc": ["S"], "Sk": ["S"], "So": ["S"], - "Zs": ["Z"], "Zl": ["Z"], "Zp": ["Z"], - "Cc": ["C"], "Cf": ["C"], "Cs": ["C"], "Co": ["C"], "Cn": ["C"], -} - -# This is the (inclusive) range of surrogate codepoints. -# These are not valid Rust characters. -SURROGATE_CODEPOINTS_RANGE = (0xd800, 0xdfff) - -UnicodeData = namedtuple( - "UnicodeData", ( - # Conversions: - "to_upper", "to_lower", "to_title", - - # Decompositions: canonical decompositions, compatibility decomp - "canon_decomp", "compat_decomp", - - # Grouped: general categories and combining characters - "general_categories", "combines", - ) -) - -UnicodeVersion = namedtuple( - "UnicodeVersion", ("major", "minor", "micro", "as_str") -) - - -def fetch_files(version=None): - # type: (str) -> UnicodeVersion - """ - Fetch all the Unicode files from unicode.org. - - This will use cached files (stored in `FETCH_DIR`) if they exist, - creating them if they don't. In any case, the Unicode version - is always returned. - - :param version: The desired Unicode version, as string. - (If None, defaults to latest final release available, - querying the unicode.org service). - """ - have_version = check_stored_version(version) - if have_version: - return have_version - - if version: - # Check if the desired version exists on the server. - get_fetch_url = lambda name: FETCH_URL_VERSION.format(version=version, filename=name) - else: - # Extract the latest version. - get_fetch_url = lambda name: FETCH_URL_LATEST.format(filename=name) - - readme_url = get_fetch_url(UnicodeFiles.README) - - print("Fetching: {}".format(readme_url)) - readme_content = subprocess.check_output(("curl", readme_url)) - - unicode_version = parse_readme_unicode_version( - readme_content.decode("utf8") - ) - - download_dir = get_unicode_dir(unicode_version) - if not os.path.exists(download_dir): - # For 2.7 compat, we don't use `exist_ok=True`. - os.makedirs(download_dir) - - for filename in ALL_UNICODE_FILES: - file_path = get_unicode_file_path(unicode_version, filename) - - if os.path.exists(file_path): - # Assume file on the server didn't change if it's been saved before. - continue - - if filename == UnicodeFiles.README: - with open(file_path, "wb") as fd: - fd.write(readme_content) - else: - url = get_fetch_url(filename) - print("Fetching: {}".format(url)) - subprocess.check_call(("curl", "-o", file_path, url)) - - return unicode_version - - -def check_stored_version(version): - # type: (Optional[str]) -> Optional[UnicodeVersion] - """ - Given desired Unicode version, return the version - if stored files are all present, and `None` otherwise. - """ - if not version: - # If no desired version specified, we should check what's the latest - # version, skipping stored version checks. - return None - - fetch_dir = os.path.join(FETCH_DIR, version) - - for filename in ALL_UNICODE_FILES: - file_path = os.path.join(fetch_dir, filename) - - if not os.path.exists(file_path): - return None - - with open(os.path.join(fetch_dir, UnicodeFiles.README)) as fd: - return parse_readme_unicode_version(fd.read()) - - -def parse_readme_unicode_version(readme_content): - # type: (str) -> UnicodeVersion - """ - Parse the Unicode version contained in their `ReadMe.txt` file. - """ - # "Raw string" is necessary for \d not being treated as escape char - # (for the sake of compat with future Python versions). - # See: https://docs.python.org/3.6/whatsnew/3.6.html#deprecated-python-behavior - pattern = r"for Version (\d+)\.(\d+)\.(\d+) of the Unicode" - groups = re.search(pattern, readme_content).groups() - - return UnicodeVersion(*map(int, groups), as_str=".".join(groups)) - - -def get_unicode_dir(unicode_version): - # type: (UnicodeVersion) -> str - """ - Indicate in which parent dir the Unicode data files should be stored. - - This returns a full, absolute path. - """ - return os.path.join(FETCH_DIR, unicode_version.as_str) - - -def get_unicode_file_path(unicode_version, filename): - # type: (UnicodeVersion, str) -> str - """ - Indicate where the Unicode data file should be stored. - """ - return os.path.join(get_unicode_dir(unicode_version), filename) - - -def is_surrogate(n): - # type: (int) -> bool - """ - Tell if given codepoint is a surrogate (not a valid Rust character). - """ - return SURROGATE_CODEPOINTS_RANGE[0] <= n <= SURROGATE_CODEPOINTS_RANGE[1] - - -def load_unicode_data(file_path): - # type: (str) -> UnicodeData - """ - Load main Unicode data. - """ - # Conversions - to_lower = {} # type: Dict[int, Tuple[int, int, int]] - to_upper = {} # type: Dict[int, Tuple[int, int, int]] - to_title = {} # type: Dict[int, Tuple[int, int, int]] - - # Decompositions - compat_decomp = {} # type: Dict[int, List[int]] - canon_decomp = {} # type: Dict[int, List[int]] - - # Combining characters - # FIXME: combines are not used - combines = defaultdict(set) # type: Dict[str, Set[int]] - - # Categories - general_categories = defaultdict(set) # type: Dict[str, Set[int]] - category_assigned_codepoints = set() # type: Set[int] - - all_codepoints = {} - - range_start = -1 - - for line in fileinput.input(file_path): - data = line.split(";") - if len(data) != 15: - continue - codepoint = int(data[0], 16) - if is_surrogate(codepoint): - continue - if range_start >= 0: - for i in range(range_start, codepoint): - all_codepoints[i] = data - range_start = -1 - if data[1].endswith(", First>"): - range_start = codepoint - continue - all_codepoints[codepoint] = data - - for code, data in all_codepoints.items(): - (code_org, name, gencat, combine, bidi, - decomp, deci, digit, num, mirror, - old, iso, upcase, lowcase, titlecase) = data - - # Generate char to char direct common and simple conversions: - - # Uppercase to lowercase - if lowcase != "" and code_org != lowcase: - to_lower[code] = (int(lowcase, 16), 0, 0) - - # Lowercase to uppercase - if upcase != "" and code_org != upcase: - to_upper[code] = (int(upcase, 16), 0, 0) - - # Title case - if titlecase.strip() != "" and code_org != titlecase: - to_title[code] = (int(titlecase, 16), 0, 0) - - # Store decomposition, if given - if decomp: - decompositions = decomp.split()[1:] - decomp_code_points = [int(i, 16) for i in decompositions] - - if decomp.startswith("<"): - # Compatibility decomposition - compat_decomp[code] = decomp_code_points - else: - # Canonical decomposition - canon_decomp[code] = decomp_code_points - - # Place letter in categories as appropriate. - for cat in itertools.chain((gencat, ), EXPANDED_CATEGORIES.get(gencat, [])): - general_categories[cat].add(code) - category_assigned_codepoints.add(code) - - # Record combining class, if any. - if combine != "0": - combines[combine].add(code) - - # Generate Not_Assigned from Assigned. - general_categories["Cn"] = get_unassigned_codepoints(category_assigned_codepoints) - - # Other contains Not_Assigned - general_categories["C"].update(general_categories["Cn"]) - - grouped_categories = group_categories(general_categories) - - # FIXME: combines are not used - return UnicodeData( - to_lower=to_lower, to_upper=to_upper, to_title=to_title, - compat_decomp=compat_decomp, canon_decomp=canon_decomp, - general_categories=grouped_categories, combines=combines, - ) - - -def load_special_casing(file_path, unicode_data): - # type: (str, UnicodeData) -> None - """ - Load special casing data and enrich given Unicode data. - """ - for line in fileinput.input(file_path): - data = line.split("#")[0].split(";") - if len(data) == 5: - code, lower, title, upper, _comment = data - elif len(data) == 6: - code, lower, title, upper, condition, _comment = data - if condition.strip(): # Only keep unconditional mappins - continue - else: - continue - code = code.strip() - lower = lower.strip() - title = title.strip() - upper = upper.strip() - key = int(code, 16) - for (map_, values) in ((unicode_data.to_lower, lower), - (unicode_data.to_upper, upper), - (unicode_data.to_title, title)): - if values != code: - split = values.split() - - codepoints = list(itertools.chain( - (int(i, 16) for i in split), - (0 for _ in range(len(split), 3)) - )) - - assert len(codepoints) == 3 - map_[key] = codepoints - - -def group_categories(mapping): - # type: (Dict[Any, Iterable[int]]) -> Dict[str, List[Tuple[int, int]]] - """ - Group codepoints mapped in "categories". - """ - return {category: group_codepoints(codepoints) - for category, codepoints in mapping.items()} - - -def group_codepoints(codepoints): - # type: (Iterable[int]) -> List[Tuple[int, int]] - """ - Group integral values into continuous, disjoint value ranges. - - Performs value deduplication. - - :return: sorted list of pairs denoting start and end of codepoint - group values, both ends inclusive. - - >>> group_codepoints([1, 2, 10, 11, 12, 3, 4]) - [(1, 4), (10, 12)] - >>> group_codepoints([1]) - [(1, 1)] - >>> group_codepoints([1, 5, 6]) - [(1, 1), (5, 6)] - >>> group_codepoints([]) - [] - """ - sorted_codes = sorted(set(codepoints)) - result = [] # type: List[Tuple[int, int]] - - if not sorted_codes: - return result - - next_codes = sorted_codes[1:] - start_code = sorted_codes[0] - - for code, next_code in zip_longest(sorted_codes, next_codes, fillvalue=None): - if next_code is None or next_code - code != 1: - result.append((start_code, code)) - start_code = next_code - - return result - - -def ungroup_codepoints(codepoint_pairs): - # type: (Iterable[Tuple[int, int]]) -> List[int] - """ - The inverse of group_codepoints -- produce a flat list of values - from value range pairs. - - >>> ungroup_codepoints([(1, 4), (10, 12)]) - [1, 2, 3, 4, 10, 11, 12] - >>> ungroup_codepoints([(1, 1), (5, 6)]) - [1, 5, 6] - >>> ungroup_codepoints(group_codepoints([1, 2, 7, 8])) - [1, 2, 7, 8] - >>> ungroup_codepoints([]) - [] - """ - return list(itertools.chain.from_iterable( - range(lo, hi + 1) for lo, hi in codepoint_pairs - )) - - -def get_unassigned_codepoints(assigned_codepoints): - # type: (Set[int]) -> Set[int] - """ - Given a set of "assigned" codepoints, return a set - of these that are not in assigned and not surrogate. - """ - return {i for i in range(0, 0x110000) - if i not in assigned_codepoints and not is_surrogate(i)} - - -def generate_table_lines(items, indent, wrap=98): - # type: (Iterable[str], int, int) -> Iterator[str] - """ - Given table items, generate wrapped lines of text with comma-separated items. - - This is a generator function. - - :param wrap: soft wrap limit (characters per line), integer. - """ - line = " " * indent - first = True - for item in items: - if len(line) + len(item) < wrap: - if first: - line += item - else: - line += ", " + item - first = False - else: - yield line + ",\n" - line = " " * indent + item - - yield line - - -def load_properties(file_path, interesting_props): - # type: (str, Iterable[str]) -> Dict[str, List[Tuple[int, int]]] - """ - Load properties data and return in grouped form. - """ - props = defaultdict(list) # type: Dict[str, List[Tuple[int, int]]] - # "Raw string" is necessary for `\.` and `\w` not to be treated as escape chars - # (for the sake of compat with future Python versions). - # See: https://docs.python.org/3.6/whatsnew/3.6.html#deprecated-python-behavior - re1 = re.compile(r"^ *([0-9A-F]+) *; *(\w+)") - re2 = re.compile(r"^ *([0-9A-F]+)\.\.([0-9A-F]+) *; *(\w+)") - - for line in fileinput.input(file_path): - match = re1.match(line) or re2.match(line) - if match: - groups = match.groups() - - if len(groups) == 2: - # `re1` matched (2 groups). - d_lo, prop = groups - d_hi = d_lo - else: - d_lo, d_hi, prop = groups - else: - continue - - if interesting_props and prop not in interesting_props: - continue - - lo_value = int(d_lo, 16) - hi_value = int(d_hi, 16) - - props[prop].append((lo_value, hi_value)) - - # Optimize if possible. - for prop in props: - props[prop] = group_codepoints(ungroup_codepoints(props[prop])) - - return props - - -def escape_char(c): - # type: (int) -> str - r""" - Escape a codepoint for use as Rust char literal. - - Outputs are OK to use as Rust source code as char literals - and they also include necessary quotes. - - >>> escape_char(97) - "'\\u{61}'" - >>> escape_char(0) - "'\\0'" - """ - return r"'\u{%x}'" % c if c != 0 else r"'\0'" - - -def format_char_pair(pair): - # type: (Tuple[int, int]) -> str - """ - Format a pair of two Rust chars. - """ - return "(%s,%s)" % (escape_char(pair[0]), escape_char(pair[1])) - - -def generate_table( - name, # type: str - items, # type: List[Tuple[int, int]] - decl_type="&[(char, char)]", # type: str - is_pub=True, # type: bool - format_item=format_char_pair, # type: Callable[[Tuple[int, int]], str] -): - # type: (...) -> Iterator[str] - """ - Generate a nicely formatted Rust constant "table" array. - - This generates actual Rust code. - """ - pub_string = "" - if is_pub: - pub_string = "pub " - - yield "\n" - yield " #[rustfmt::skip]\n" - yield " %sconst %s: %s = &[\n" % (pub_string, name, decl_type) - - data = [] - first = True - for item in items: - if not first: - data.append(",") - first = False - data.extend(format_item(item)) - - for table_line in generate_table_lines("".join(data).split(","), 8): - yield table_line - - yield "\n ];\n" - - -def compute_trie(raw_data, chunk_size): - # type: (List[int], int) -> Tuple[List[int], List[int]] - """ - Compute postfix-compressed trie. - - See: bool_trie.rs for more details. - - >>> compute_trie([1, 2, 3, 1, 2, 3, 4, 5, 6], 3) - ([0, 0, 1], [1, 2, 3, 4, 5, 6]) - >>> compute_trie([1, 2, 3, 1, 2, 4, 4, 5, 6], 3) - ([0, 1, 2], [1, 2, 3, 1, 2, 4, 4, 5, 6]) - """ - root = [] - childmap = {} # type: Dict[Tuple[int, ...], int] - child_data = [] - - assert len(raw_data) % chunk_size == 0, "Chunks must be equally sized" - - for i in range(len(raw_data) // chunk_size): - data = raw_data[i * chunk_size : (i + 1) * chunk_size] - - # Postfix compression of child nodes (data chunks) - # (identical child nodes are shared). - - # Make a tuple out of the list so it's hashable. - child = tuple(data) - if child not in childmap: - childmap[child] = len(childmap) - child_data.extend(data) - - root.append(childmap[child]) - - return root, child_data - - -def generate_bool_trie(name, codepoint_ranges, is_pub=False): - # type: (str, List[Tuple[int, int]], bool) -> Iterator[str] - """ - Generate Rust code for BoolTrie struct. - - This yields string fragments that should be joined to produce - the final string. - - See: `bool_trie.rs`. - """ - chunk_size = 64 - rawdata = [False] * 0x110000 - for (lo, hi) in codepoint_ranges: - for cp in range(lo, hi + 1): - rawdata[cp] = True - - # Convert to bitmap chunks of `chunk_size` bits each. - chunks = [] - for i in range(0x110000 // chunk_size): - chunk = 0 - for j in range(chunk_size): - if rawdata[i * chunk_size + j]: - chunk |= 1 << j - chunks.append(chunk) - - pub_string = "" - if is_pub: - pub_string = "pub " - - yield "\n" - yield " #[rustfmt::skip]\n" - yield " %sconst %s: &super::BoolTrie = &super::BoolTrie {\n" % (pub_string, name) - yield " r1: [\n" - data = ("0x%016x" % chunk for chunk in chunks[:0x800 // chunk_size]) - for fragment in generate_table_lines(data, 12): - yield fragment - yield "\n ],\n" - - # 0x800..0x10000 trie - (r2, r3) = compute_trie(chunks[0x800 // chunk_size : 0x10000 // chunk_size], 64 // chunk_size) - yield " r2: [\n" - data = map(str, r2) - for fragment in generate_table_lines(data, 12): - yield fragment - yield "\n ],\n" - - yield " r3: &[\n" - data = ("0x%016x" % node for node in r3) - for fragment in generate_table_lines(data, 12): - yield fragment - yield "\n ],\n" - - # 0x10000..0x110000 trie - (mid, r6) = compute_trie(chunks[0x10000 // chunk_size : 0x110000 // chunk_size], - 64 // chunk_size) - (r4, r5) = compute_trie(mid, 64) - - yield " r4: [\n" - data = map(str, r4) - for fragment in generate_table_lines(data, 12): - yield fragment - yield "\n ],\n" - - yield " r5: &[\n" - data = map(str, r5) - for fragment in generate_table_lines(data, 12): - yield fragment - yield "\n ],\n" - - yield " r6: &[\n" - data = ("0x%016x" % node for node in r6) - for fragment in generate_table_lines(data, 12): - yield fragment - yield "\n ],\n" - - yield " };\n" - - -def generate_small_bool_trie(name, codepoint_ranges, is_pub=False): - # type: (str, List[Tuple[int, int]], bool) -> Iterator[str] - """ - Generate Rust code for `SmallBoolTrie` struct. - - See: `bool_trie.rs`. - """ - last_chunk = max(hi // 64 for (lo, hi) in codepoint_ranges) - n_chunks = last_chunk + 1 - chunks = [0] * n_chunks - for (lo, hi) in codepoint_ranges: - for cp in range(lo, hi + 1): - assert cp // 64 < len(chunks) - chunks[cp // 64] |= 1 << (cp & 63) - - pub_string = "" - if is_pub: - pub_string = "pub " - - yield "\n" - yield " #[rustfmt::skip]\n" - yield (" %sconst %s: &super::SmallBoolTrie = &super::SmallBoolTrie {\n" - % (pub_string, name)) - - (r1, r2) = compute_trie(chunks, 1) - - yield " r1: &[\n" - data = (str(node) for node in r1) - for fragment in generate_table_lines(data, 12): - yield fragment - yield "\n ],\n" - - yield " r2: &[\n" - data = ("0x%016x" % node for node in r2) - for fragment in generate_table_lines(data, 12): - yield fragment - yield "\n ],\n" - - yield " };\n" - - -def generate_property_module(mod, grouped_categories, category_subset): - # type: (str, Dict[str, List[Tuple[int, int]]], Iterable[str]) -> Iterator[str] - """ - Generate Rust code for module defining properties. - """ - - yield "pub(crate) mod %s {" % mod - for cat in sorted(category_subset): - if cat in ("Cc", "White_Space"): - generator = generate_small_bool_trie("%s_table" % cat, grouped_categories[cat]) - else: - generator = generate_bool_trie("%s_table" % cat, grouped_categories[cat]) - - for fragment in generator: - yield fragment - - yield "\n" - yield " pub fn %s(c: char) -> bool {\n" % cat - yield " %s_table.lookup(c)\n" % cat - yield " }\n" - - yield "}\n\n" - - -def generate_conversions_module(unicode_data): - # type: (UnicodeData) -> Iterator[str] - """ - Generate Rust code for module defining conversions. - """ - - yield "pub(crate) mod conversions {" - yield """ - pub fn to_lower(c: char) -> [char; 3] { - match bsearch_case_table(c, to_lowercase_table) { - None => [c, '\\0', '\\0'], - Some(index) => to_lowercase_table[index].1, - } - } - - pub fn to_upper(c: char) -> [char; 3] { - match bsearch_case_table(c, to_uppercase_table) { - None => [c, '\\0', '\\0'], - Some(index) => to_uppercase_table[index].1, - } - } - - fn bsearch_case_table(c: char, table: &[(char, [char; 3])]) -> Option { - table.binary_search_by(|&(key, _)| key.cmp(&c)).ok() - }\n""" - - decl_type = "&[(char, [char; 3])]" - format_conversion = lambda x: "({},[{},{},{}])".format(*( - escape_char(c) for c in (x[0], x[1][0], x[1][1], x[1][2]) - )) - - for fragment in generate_table( - name="to_lowercase_table", - items=sorted(unicode_data.to_lower.items(), key=lambda x: x[0]), - decl_type=decl_type, - is_pub=False, - format_item=format_conversion - ): - yield fragment - - for fragment in generate_table( - name="to_uppercase_table", - items=sorted(unicode_data.to_upper.items(), key=lambda x: x[0]), - decl_type=decl_type, - is_pub=False, - format_item=format_conversion - ): - yield fragment - - yield "}\n" - - -def parse_args(): - # type: () -> argparse.Namespace - """ - Parse command line arguments. - """ - parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument("-v", "--version", default=None, type=str, - help="Unicode version to use (if not specified," - " defaults to latest release).") - - return parser.parse_args() - - -def main(): - # type: () -> None - """ - Script entry point. - """ - args = parse_args() - - unicode_version = fetch_files(args.version) - print("Using Unicode version: {}".format(unicode_version.as_str)) - - # All the writing happens entirely in memory, we only write to file - # once we have generated the file content (it's not very large, <1 MB). - buf = StringIO() - buf.write(PREAMBLE) - - unicode_version_notice = textwrap.dedent(""" - /// The version of [Unicode](http://www.unicode.org/) that the Unicode parts of - /// `char` and `str` methods are based on. - #[unstable(feature = "unicode_version", issue = "49726")] - pub const UNICODE_VERSION: UnicodeVersion = - UnicodeVersion {{ major: {v.major}, minor: {v.minor}, micro: {v.micro}, _priv: () }}; - """).format(v=unicode_version) - buf.write(unicode_version_notice) - - get_path = lambda f: get_unicode_file_path(unicode_version, f) - - unicode_data = load_unicode_data(get_path(UnicodeFiles.UNICODE_DATA)) - load_special_casing(get_path(UnicodeFiles.SPECIAL_CASING), unicode_data) - - want_derived = {"Alphabetic", "Lowercase", "Uppercase", - "Cased", "Case_Ignorable", "Grapheme_Extend"} - derived = load_properties(get_path(UnicodeFiles.DERIVED_CORE_PROPERTIES), want_derived) - - props = load_properties(get_path(UnicodeFiles.PROPS), - {"White_Space", "Join_Control", "Noncharacter_Code_Point"}) - - # Category tables - for (name, categories, category_subset) in ( - ("general_category", unicode_data.general_categories, ["N", "Cc"]), - ("derived_property", derived, want_derived), - ("property", props, ["White_Space"]) - ): - for fragment in generate_property_module(name, categories, category_subset): - buf.write(fragment) - - for fragment in generate_conversions_module(unicode_data): - buf.write(fragment) - - tables_rs_path = os.path.join(THIS_DIR, "tables.rs") - - # Actually write out the file content. - # Will overwrite the file if it exists. - with open(tables_rs_path, "w") as fd: - fd.write(buf.getvalue()) - - print("Regenerated tables.rs.") - - -if __name__ == "__main__": - main() diff --git a/src/libcore/unicode/unicode_data.rs b/src/libcore/unicode/unicode_data.rs new file mode 100644 index 0000000000000..da4cd4e9b1da1 --- /dev/null +++ b/src/libcore/unicode/unicode_data.rs @@ -0,0 +1,2343 @@ +///! This file is generated by src/tools/unicode-table-generator; do not edit manually! +use super::range_search; + +pub const UNICODE_VERSION: (u32, u32, u32) = (12, 1, 0); + +#[rustfmt::skip] +pub mod alphabetic { + static BITSET_LAST_CHUNK_MAP: (u16, u8) = (190, 37); + static BITSET_CHUNKS_MAP: [u8; 187] = [ + 6, 32, 10, 18, 19, 23, 21, 12, 7, 5, 0, 20, 14, 49, 49, 49, 49, 49, 49, 36, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 47, 49, 30, 8, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 45, 0, 0, 0, 0, 0, 0, 0, 0, 4, 35, 17, 31, 16, 25, 24, 26, 13, 15, + 44, 27, 0, 0, 49, 11, 0, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 38, 1, 49, 49, 49, 49, 49, 48, + 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 28, 0, 0, 0, 0, 0, 29, 0, 0, 9, 0, 33, 2, 3, 0, 0, + 0, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, + 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 41, 49, 49, 49, + 43, 22, 49, 49, 49, 49, 40, 49, 49, 49, 49, 49, 49, 46, + ]; + static BITSET_INDEX_CHUNKS: [[u8; 16]; 50] = [ + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 248, 0, 0, 248, 241, 38, 40], + [0, 0, 0, 0, 0, 0, 0, 0, 108, 133, 110, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 190, 200, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 248, 248, 248, 248, 248, 205, 248, 23, 134, 245, 68, 237], + [0, 0, 179, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 103, 99, 176, 248, 248, 248, 248, 248, 248, 248, 61, 0, 151, 217, 178], + [0, 145, 28, 0, 168, 221, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [48, 77, 248, 165, 201, 120, 184, 137, 91, 175, 143, 83, 206, 196, 248, 56], + [53, 0, 0, 0, 126, 15, 0, 0, 0, 0, 0, 58, 0, 0, 0, 0], + [59, 54, 127, 199, 167, 186, 157, 114, 154, 84, 160, 115, 158, 66, 155, 21], + [62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [91, 129, 164, 101, 248, 248, 248, 79, 248, 248, 248, 248, 230, 128, 135, 117], + [97, 0, 220, 144, 0, 0, 212, 44, 142, 240, 30, 97, 0, 0, 0, 0], + [116, 247, 219, 171, 188, 248, 104, 190, 0, 0, 0, 0, 0, 0, 0, 0], + [141, 185, 88, 0, 149, 213, 22, 0, 0, 0, 0, 89, 0, 0, 0, 0], + [147, 90, 35, 82, 98, 0, 153, 0, 85, 119, 29, 45, 86, 71, 18, 0], + [150, 32, 248, 107, 0, 81, 0, 0, 0, 0, 227, 17, 211, 105, 231, 19], + [162, 41, 161, 69, 163, 173, 123, 73, 106, 14, 124, 37, 1, 187, 121, 0], + [172, 240, 228, 170, 248, 248, 248, 248, 248, 229, 138, 235, 234, 24, 222, 125], + [208, 233, 248, 74, 204, 64, 140, 232, 63, 0, 0, 0, 0, 0, 0, 0], + [220, 97, 202, 86, 94, 78, 203, 9, 226, 80, 46, 0, 183, 11, 174, 67], + [231, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248], + [247, 248, 248, 248, 248, 248, 248, 248, 248, 209, 225, 95, 76, 75, 180, 25], + [248, 5, 96, 50, 72, 87, 248, 26, 132, 0, 198, 51, 159, 42, 0, 0], + [248, 8, 72, 72, 49, 0, 0, 0, 0, 0, 0, 0, 194, 5, 0, 89], + [248, 36, 248, 7, 0, 0, 139, 31, 143, 3, 93, 0, 55, 0, 0, 0], + [248, 62, 248, 248, 248, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [248, 118, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [248, 236, 166, 246, 136, 239, 248, 248, 248, 248, 215, 169, 182, 207, 214, 12], + [248, 248, 13, 130, 248, 248, 248, 248, 57, 146, 248, 65, 218, 248, 243, 177], + [248, 248, 191, 111, 197, 43, 0, 0, 248, 248, 248, 248, 91, 47, 0, 0], + [248, 248, 244, 248, 189, 223, 152, 70, 224, 210, 248, 148, 240, 242, 68, 100], + [248, 248, 248, 4, 248, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [248, 248, 248, 248, 35, 195, 248, 248, 248, 248, 248, 113, 0, 0, 0, 0], + [248, 248, 248, 248, 131, 240, 238, 109, 0, 181, 248, 122, 102, 216, 143, 27], + [248, 248, 248, 248, 248, 248, 86, 0, 248, 248, 248, 248, 248, 248, 248, 248], + [248, 248, 248, 248, 248, 248, 248, 248, 33, 0, 0, 0, 0, 0, 0, 0], + [248, 248, 248, 248, 248, 248, 248, 248, 97, 35, 0, 60, 65, 156, 16, 0], + [248, 248, 248, 248, 248, 248, 248, 248, 248, 6, 0, 0, 0, 0, 0, 0], + [248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 192, 248, 248, 248, 248, 248], + [248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 20, 248, 248, 248, 248], + [248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 72, 0, 0, 0, 0], + [248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 81, 248, 248, 248], + [248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 23, 0], + [248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 193, 112], + [248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 39], + [248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 65], + [248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 92], + [248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248], + ]; + static BITSET: [u64; 249] = [ + 0, 1, 15, 17, 31, 63, 127, 179, 511, 1023, 2191, 4079, 4087, 8191, 8319, 16384, 65535, + 131071, 262143, 4128527, 8388607, 8461767, 24870911, 67108863, 134217727, 276824575, + 335544350, 486341884, 536805376, 536870911, 553648127, 1056964608, 1073692671, 1073741823, + 1140785663, 2147483647, 2147485627, 4026540127, 4294934783, 8589934591, 47244640256, + 64548249055, 68191066527, 68719476735, 115913785343, 137438953215, 549755813888, + 1095220854783, 1099511627711, 1099511627775, 2199023190016, 2199023255551, 4398046511103, + 8641373536127, 8791831609343, 8795690369023, 8796093022207, 13198434443263, 17592186044415, + 35184321757183, 70368744112128, 88094074470339, 140737488355327, 140737488355328, + 141836999983103, 281474976710655, 563017343310239, 1125625028935679, 1125899906842623, + 1688915364814303, 2119858418286774, 2251795522912255, 2251799813685247, 3377704004976767, + 3509778554814463, 3905461007941631, 4503595333443583, 4503599627370495, 8796093022142464, + 9006649498927104, 9007192812290047, 9007199254740991, 15762594400829440, 17169970223906821, + 17732925109967239, 18014398491652207, 18014398509481983, 20266198323101808, + 36027697507139583, 36028792723996672, 36028792728190975, 36028797018963967, + 72057594037927935, 90071992547409919, 143851303137705983, 144053615424700415, + 144115188075855868, 144115188075855871, 288230371860938751, 297241973452963840, + 301749971126844416, 319718190147960832, 576460743713488896, 576460743847706622, + 576460748008488959, 576460752303359999, 576460752303423486, 576460752303423487, + 790380184120328175, 1152640029630136575, 1152917029519358975, 1152921504591118335, + 1152921504606845055, 1152921504606846975, 1153765996922689951, 2161727885562420159, + 2251241253188403424, 2295745090394464220, 2305570330330005503, 2305843004918726656, + 2305843004919250943, 2305843009196916483, 2305843009213693951, 3457638613854978028, + 4323455298678290390, 4557642822898941951, 4575692405780512767, 4602678814877679616, + 4611686017001275199, 4611686018360336384, 4611686018427322368, 4611686018427387903, + 4656722014700830719, 6843210385291930244, 6881498031078244479, 6908521828386340863, + 8935141660164089791, 8935423131384840192, 9168765891372858879, 9169328841326329855, + 9187201948305063935, 9187343239835811327, 9216616637413720063, 9223372036854775807, + 9223372041149743103, 9223934986808197120, 10371930679322607615, 10502394331027995967, + 11241233151490523135, 13006395723845991295, 13258596753222922239, 13609596598936928288, + 13834776580305453567, 13907115649320091647, 14082190885810440174, 14123225865944680428, + 16212958624174047247, 16412803692974677999, 16424062692043104238, 16424062692043104239, + 16424062692043243502, 16424625641996804079, 16429129241624174575, 16717361816799141871, + 16717361816799216127, 16788293510930366511, 17005555242810474495, 17293822569102704639, + 17581979622616071300, 17870283321271910397, 17870283321406070975, 17870283321406128127, + 17978369712463020031, 18158513764145585631, 18158781978395017215, 18194542490281852927, + 18410715276682199039, 18410715276690587772, 18428729675200069631, 18428729675200069632, + 18433233274827440127, 18437455399478099968, 18437736874452713471, 18442240474082181119, + 18444492273895866367, 18445618173802708993, 18446181192473632767, 18446216308128218879, + 18446462598732840928, 18446462598732840959, 18446462598732840960, 18446462599806582783, + 18446462615912710143, 18446462667452317695, 18446463149025525759, 18446463629525450752, + 18446463698110251007, 18446463698244468735, 18446464796682337663, 18446466966713532416, + 18446466996779287551, 18446471394825862144, 18446471394825863167, 18446480190918885375, + 18446498607738650623, 18446532967477018623, 18446602782178705022, 18446603336221163519, + 18446603336221196287, 18446638520593285119, 18446673709243564031, 18446708893632430079, + 18446740770879700992, 18446741595513422027, 18446741874686295551, 18446743249075830783, + 18446743798965862398, 18446744056529672000, 18446744060816261120, 18446744068886102015, + 18446744069414584320, 18446744069414601696, 18446744069414649855, 18446744069456527359, + 18446744069548736512, 18446744069548802046, 18446744069683019775, 18446744069951455231, + 18446744070421282815, 18446744070446333439, 18446744070475743231, 18446744070488326143, + 18446744071553646463, 18446744071562067967, 18446744073696837631, 18446744073701162813, + 18446744073707454463, 18446744073709027328, 18446744073709355007, 18446744073709419615, + 18446744073709486080, 18446744073709520895, 18446744073709543424, 18446744073709550079, + 18446744073709550595, 18446744073709551579, 18446744073709551599, 18446744073709551614, + 18446744073709551615, + ]; + + pub fn lookup(c: char) -> bool { + super::range_search( + c as u32, + &BITSET_CHUNKS_MAP, + BITSET_LAST_CHUNK_MAP, + &BITSET_INDEX_CHUNKS, + &BITSET, + ) + } +} + +#[rustfmt::skip] +pub mod case_ignorable { + static BITSET_LAST_CHUNK_MAP: (u16, u8) = (896, 33); + static BITSET_CHUNKS_MAP: [u8; 125] = [ + 25, 14, 21, 30, 28, 4, 17, 23, 22, 0, 0, 16, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 13, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3, 6, 9, 0, 7, 11, 32, 31, 26, 29, 0, 0, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, + 10, 0, 8, 0, 20, 0, 12, 0, 1, + ]; + static BITSET_INDEX_CHUNKS: [[u8; 16]; 34] = [ + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 164], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 47, 52], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 171, 2], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 88, 134, 38], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 94, 102, 6, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 76, 26, 0, 146, 136, 79, 43, 117], + [0, 0, 0, 0, 0, 0, 0, 0, 152, 0, 0, 58, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 165, 97, 75, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 0, 48, 0, 114, 0, 0], + [0, 0, 0, 0, 0, 170, 68, 0, 0, 7, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 61, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0], + [0, 0, 0, 28, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 133, 0, 0, 0, 0, 15, 160, 45, 84, 51, 78, 12, 109], + [0, 0, 11, 0, 0, 30, 161, 90, 35, 80, 0, 69, 173, 13, 81, 129], + [0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 131, 0, 85, 0, 148, 0, 175, 73, 0, 0, 0, 0, 0, 0, 0], + [20, 4, 62, 0, 118, 0, 0, 0, 32, 154, 145, 0, 124, 89, 67, 86], + [25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [59, 0, 0, 150, 70, 24, 132, 60, 100, 122, 163, 99, 0, 46, 0, 66], + [63, 0, 0, 0, 135, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 0], + [71, 33, 0, 178, 123, 83, 120, 137, 121, 98, 121, 167, 153, 55, 3, 18], + [72, 149, 36, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [104, 133, 0, 110, 174, 105, 177, 166, 0, 0, 0, 0, 0, 0, 155, 139], + [107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [111, 50, 106, 0, 0, 0, 0, 0, 0, 0, 172, 179, 179, 112, 9, 0], + [113, 0, 0, 0, 0, 0, 0, 49, 142, 34, 31, 0, 0, 0, 0, 0], + [116, 0, 42, 141, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [140, 93, 37, 119, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0], + [159, 0, 101, 0, 158, 10, 29, 0, 0, 0, 0, 91, 0, 0, 0, 0], + [162, 56, 153, 54, 125, 53, 0, 27, 115, 21, 126, 19, 108, 144, 127, 8], + [168, 41, 151, 5, 0, 0, 157, 39, 156, 1, 103, 0, 65, 0, 0, 0], + [169, 147, 130, 17, 96, 87, 143, 16, 138, 0, 0, 64, 125, 95, 0, 0], + [176, 179, 0, 0, 179, 179, 179, 77, 0, 0, 0, 0, 0, 0, 0, 0], + ]; + static BITSET: [u64; 180] = [ + 0, 1, 3, 4, 8, 13, 15, 28, 64, 176, 191, 1016, 1792, 2047, 4080, 4096, 7680, 8192, 8193, + 16192, 30720, 32704, 32768, 131008, 262016, 2097152, 2359296, 6030336, 8323072, 10682368, + 33554432, 58719232, 159383552, 234881024, 243138688, 402587711, 536805376, 536879204, + 546307648, 805306369, 1073741824, 1073741916, 2113929216, 3221225472, 3758096384, + 4026531840, 4160749568, 4294934528, 4294967296, 4512022528, 5368709120, 17179869183, + 47244640256, 51539615774, 51539619904, 51543810078, 51545914817, 66035122176, 412316860416, + 412316862532, 412316893184, 1030792151040, 2199023255648, 8641373536127, 8763880767488, + 17303886364672, 36421322670080, 65128884076547, 65970697670631, 68168642985984, + 70093866270720, 70368739983360, 136957967529984, 140737488355328, 263882790666240, + 281470547525648, 281470682333183, 281474976710655, 281474976710656, 281474976710657, + 281479271675905, 562675075514368, 562949953355776, 563001509683710, 844424930131968, + 985162418487296, 1023920203366400, 2251799813685248, 3377699721314304, 4494803534348292, + 4503599627370678, 6755399441055744, 7881299349733376, 8444256867844096, 8725724278030336, + 8760633772212225, 8989057312882695, 9042383626829823, 9851624185018758, 24822575045541890, + 28848986089586688, 30958948903026688, 35747322042253312, 53805701016846336, + 58529202969772032, 72066390130950143, 112767012056334336, 143833713099145216, + 189151184399892480, 216172782113783808, 220713756545974272, 288301294651703296, + 302022650010533887, 504262420777140224, 558446353793941504, 572520102629474304, + 593978171557150752, 1008806350890729472, 1009933895770046464, 1152921504606846976, + 1152921504606846978, 1152921504606846982, 1153202979583561736, 1441151880758558727, + 1715871458028158991, 1729382256910270467, 2301902359539744768, 2305843009196908767, + 2305843009213693952, 2612078987781865472, 2771965570646540291, 3458764513820540928, + 3731232291276455943, 4539628424389459968, 4589168020290535424, 4611404543450677248, + 4611686018494513280, 4611686069967003678, 4671217976001691648, 6917775322003857411, + 7421334051581067264, 8070450532247928832, 8788774672813524990, 9205357638345293827, + 9222809086901354496, 9223091111633879040, 9223372036854775808, 9223372036854775935, + 9223512774343131136, 9224216320050987008, 9224497932466651184, 9653465801268658176, + 9727775195120332910, 10376293541461622786, 11526998316797657088, 11529215046068469760, + 12103423998558208000, 12699025049277956096, 13005832773892571136, 13798747783286489088, + 13832665517980123136, 13835058055282032640, 13835058055282163729, 13951307220663664640, + 17870283321406128128, 17906312118425092095, 18158513697557839871, 18158513749097456062, + 18374686479671623680, 18374686479671623682, 18444496122186563584, 18445618173802708992, + 18446462598732840960, 18446462598733004800, 18446726481523507200, 18446744069414584320, + 18446744069414584322, 18446744073575333888, 18446744073709027328, 18446744073709551615, + ]; + + pub fn lookup(c: char) -> bool { + super::range_search( + c as u32, + &BITSET_CHUNKS_MAP, + BITSET_LAST_CHUNK_MAP, + &BITSET_INDEX_CHUNKS, + &BITSET, + ) + } +} + +#[rustfmt::skip] +pub mod cased { + static BITSET_LAST_CHUNK_MAP: (u16, u8) = (124, 6); + static BITSET_CHUNKS_MAP: [u8; 123] = [ + 13, 18, 0, 0, 12, 0, 0, 9, 14, 10, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 2, 0, 16, 0, 8, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 0, + 0, 0, 0, 7, + ]; + static BITSET_INDEX_CHUNKS: [[u8; 16]; 19] = [ + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 8, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 43, 62, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 10, 0, 50, 62, 58, 20], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 42, 44, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 62, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 31, 0, 62, 62, 62, 0, 62, 62, 62, 62, 54, 26, 27, 24], + [0, 0, 39, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 51, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 51, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 51, 25], + [0, 22, 19, 37, 62, 62, 36, 61, 62, 62, 18, 12, 0, 30, 49, 38], + [0, 29, 9, 0, 34, 52, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [46, 55, 62, 17, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [62, 6, 42, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [62, 56, 33, 60, 28, 57, 62, 62, 62, 62, 48, 35, 40, 45, 47, 5], + [62, 62, 59, 62, 41, 53, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0], + ]; + static BITSET: [u64; 63] = [ + 0, 15, 24, 511, 1023, 4087, 65535, 16253055, 134217726, 536805376, 1073741823, 4294967295, + 133143986179, 4398046511103, 36009005809663, 70368744177663, 2251799813685247, + 3509778554814463, 144115188074807295, 297241973452963840, 504403158265495676, + 576460743713488896, 576460743847706622, 1152921504591118335, 2295745090394464220, + 4557642822898941951, 4611686017001275199, 6908521828386340863, 8935141660164089791, + 9223934986808197120, 13605092999309557792, 16717361816799216127, 16717361816799223999, + 17005555242810474495, 17446871633794956420, 17870283321271910397, 17870283321406128127, + 18410715276682199039, 18428729675200069631, 18428729675200069632, 18437736874452713471, + 18446462598732840959, 18446462598732840960, 18446463698110251007, 18446466996779287551, + 18446603336221163519, 18446603336221196287, 18446741874686295551, 18446743249075830783, + 18446744056529672000, 18446744056529682432, 18446744069414584320, 18446744069414601696, + 18446744069422972927, 18446744070475743231, 18446744071562067967, 18446744073707454463, + 18446744073709419615, 18446744073709517055, 18446744073709550595, 18446744073709551599, + 18446744073709551600, 18446744073709551615, + ]; + + pub fn lookup(c: char) -> bool { + super::range_search( + c as u32, + &BITSET_CHUNKS_MAP, + BITSET_LAST_CHUNK_MAP, + &BITSET_INDEX_CHUNKS, + &BITSET, + ) + } +} + +#[rustfmt::skip] +pub mod cc { + static BITSET_LAST_CHUNK_MAP: (u16, u8) = (0, 0); + static BITSET_CHUNKS_MAP: [u8; 0] = [ + ]; + static BITSET_INDEX_CHUNKS: [[u8; 16]; 1] = [ + [1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + ]; + static BITSET: [u64; 3] = [ + 0, 4294967295, 9223372036854775808, + ]; + + pub fn lookup(c: char) -> bool { + super::range_search( + c as u32, + &BITSET_CHUNKS_MAP, + BITSET_LAST_CHUNK_MAP, + &BITSET_INDEX_CHUNKS, + &BITSET, + ) + } +} + +#[rustfmt::skip] +pub mod grapheme_extend { + static BITSET_LAST_CHUNK_MAP: (u16, u8) = (896, 30); + static BITSET_CHUNKS_MAP: [u8; 123] = [ + 4, 15, 21, 27, 25, 3, 18, 23, 17, 0, 0, 14, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 7, 10, 0, 8, 12, 29, 28, 24, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, + 11, 0, 9, 0, 20, 0, 13, + ]; + static BITSET_INDEX_CHUNKS: [[u8; 16]; 31] = [ + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 18, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 70, 102, 29], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 62, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, 83, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 103, 35, 66, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 61, 0, 0, 0, 0, 0, 35, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 117, 0, 0, 45, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 130, 78, 60, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 99, 0, 0, 0, 37, 0, 90, 0, 0], + [0, 0, 0, 0, 0, 129, 54, 0, 0, 3, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0], + [0, 0, 0, 19, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 67, 0, 114, 0, 137, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 7, 0, 0, 0, 125, 5, 24, 63, 0, 55, 135, 9, 64, 100], + [0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [10, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [12, 0, 48, 0, 92, 0, 0, 0, 25, 119, 113, 0, 96, 71, 53, 68], + [46, 0, 0, 116, 57, 17, 101, 44, 81, 94, 127, 80, 0, 0, 0, 52], + [49, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 58, 0, 0, 0, 0], + [56, 26, 0, 136, 95, 43, 107, 105, 93, 79, 93, 132, 128, 42, 104, 20], + [59, 0, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [85, 0, 0, 87, 0, 0, 0, 131, 0, 0, 0, 0, 0, 0, 0, 0], + [89, 0, 0, 0, 0, 0, 0, 38, 110, 27, 22, 0, 0, 0, 0, 0], + [109, 74, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0], + [124, 0, 82, 0, 123, 6, 21, 0, 0, 0, 0, 72, 0, 0, 0, 0], + [126, 40, 118, 39, 108, 41, 0, 34, 91, 14, 97, 13, 86, 112, 98, 4], + [133, 32, 120, 2, 0, 0, 122, 30, 121, 1, 84, 0, 51, 0, 0, 0], + [134, 115, 88, 0, 77, 69, 111, 11, 106, 0, 0, 50, 108, 76, 0, 0], + [137, 138, 0, 0, 138, 138, 138, 62, 0, 0, 0, 0, 0, 0, 0, 0], + ]; + static BITSET: [u64; 139] = [ + 0, 1, 13, 28, 64, 182, 191, 1016, 2032, 2047, 4096, 7680, 14336, 16128, 32640, 32768, + 131008, 262016, 491520, 8323072, 8396801, 10682368, 58719232, 100663296, 134152192, + 159383552, 234881024, 243138688, 536879204, 537919040, 805306369, 1073741824, 1073741916, + 1610612736, 2153546752, 3221225472, 3758096384, 4294967296, 4512022528, 51545911364, + 51545914817, 51548004382, 51552198686, 51556262398, 137438953472, 412316860416, + 412316862532, 1030792151040, 2199023255648, 8641373536127, 8763880767488, 17303886364672, + 36421322670080, 65128884076547, 65970697670631, 67755789254656, 69200441769984, + 70093866270720, 263882790666240, 277076930199552, 281470547525648, 281470681808895, + 281474976710655, 281479271675904, 562675075514368, 562949953355776, 844424930131968, + 985162418487296, 1023920203366400, 2251799813685248, 3377699721314304, 4494803534348292, + 6755399441055744, 7881299349733376, 8444256867844096, 8725724278030336, 8760633780600833, + 8989057312882695, 9042383626829823, 9851624185018758, 18067175067615234, 28848986089586688, + 30958948903026688, 35747322042253312, 53805701016846336, 58529202969772032, + 189151184399892480, 220713756545974272, 466122561432846339, 504262420777140224, + 558446353793941504, 572520102629474304, 1009933895770046464, 1152921504606846982, + 1152921504606851080, 1441151880758558727, 1724878657282899983, 2301902359539744768, + 2305843009196908767, 2305843009213693952, 2310337812748042240, 3731232291276455943, + 4589168020290535424, 4609293481125347328, 4611686018427387908, 4611686069975392286, + 4671217976001691648, 5764607523034234882, 6341068275337658371, 7421334051581067264, + 8788774672813524990, 9205357638345293827, 9222809086901354496, 9223090561878065152, + 9223372036854775808, 9223372036854775935, 9224497932466651184, 9727775195120332910, + 10376293541461622786, 11526998316797657088, 11959590285459062784, 12103423998558208000, + 12699165786766311424, 13005832773892571136, 13798747783286489088, 13835058055282032640, + 13835058055282163729, 13951307220663664640, 14987979559889010690, 17872468738205286400, + 17906312118425092095, 18158513697557839871, 18158513749097456062, 18374686479671623680, + 18374686479671623682, 18446462598732972032, 18446744056529158144, 18446744069414584320, + 18446744073709551615, + ]; + + pub fn lookup(c: char) -> bool { + super::range_search( + c as u32, + &BITSET_CHUNKS_MAP, + BITSET_LAST_CHUNK_MAP, + &BITSET_INDEX_CHUNKS, + &BITSET, + ) + } +} + +#[rustfmt::skip] +pub mod lowercase { + static BITSET_LAST_CHUNK_MAP: (u16, u8) = (122, 6); + static BITSET_CHUNKS_MAP: [u8; 118] = [ + 12, 16, 0, 0, 10, 0, 0, 11, 13, 8, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2, 1, 0, 17, 0, 9, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, + ]; + static BITSET_INDEX_CHUNKS: [[u8; 16]; 18] = [ + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 62, 71, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 9, 0, 50, 42, 44, 28], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 68, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35], + [0, 0, 3, 0, 71, 71, 71, 0, 46, 46, 48, 46, 24, 37, 38, 23], + [0, 29, 27, 57, 39, 51, 52, 43, 41, 70, 26, 11, 0, 34, 64, 32], + [0, 40, 8, 0, 33, 60, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [22, 13, 54, 66, 25, 15, 56, 63, 30, 19, 12, 55, 58, 61, 65, 4], + [59, 36, 46, 21, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [59, 49, 45, 47, 18, 69, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [67, 5, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + ]; + static BITSET: [u64; 72] = [ + 0, 15, 16, 511, 3063, 65535, 16253055, 134217726, 536805376, 984263338, 4294967295, + 133143986179, 274877905920, 1099509514240, 4398046445568, 17592185782272, 36009005809663, + 46912496118442, 187649984473770, 281474972516352, 2251799813685247, 2339875276368554, + 4503599560261632, 61925590106570972, 71777214282006783, 72057592964186127, + 144115188074807295, 297241973452963840, 504403158265495560, 576460743713488896, + 1152921487426978047, 1152921504590069760, 1814856824841797631, 3607524039012697088, + 4362299189061746720, 4539628424389459968, 4601013482110844927, 4611405638684049471, + 4674456033467236607, 6172933889249159850, 9223934986808197120, 10663022717737544362, + 10808545280696953514, 12261519110656315968, 12294970652241842346, 12297829382473033730, + 12297829382473034410, 12297829382473045332, 12297829382829550250, 12297829383904690175, + 12298110845996498944, 15324248332066007893, 16596095761559859497, 16717361816799215616, + 16987577794709946364, 17293822586148356092, 18158513701852807104, 18410715274543104000, + 18428729675466407935, 18446462598732840960, 18446462598732858304, 18446462598737002495, + 18446463698110251007, 18446673704966422527, 18446726481523572736, 18446739675663105535, + 18446739675663106031, 18446742974197923840, 18446744056529682432, 18446744069414584320, + 18446744073709529733, 18446744073709551615, + ]; + + pub fn lookup(c: char) -> bool { + super::range_search( + c as u32, + &BITSET_CHUNKS_MAP, + BITSET_LAST_CHUNK_MAP, + &BITSET_INDEX_CHUNKS, + &BITSET, + ) + } +} + +#[rustfmt::skip] +pub mod n { + static BITSET_LAST_CHUNK_MAP: (u16, u8) = (124, 11); + static BITSET_CHUNKS_MAP: [u8; 124] = [ + 30, 7, 10, 24, 18, 3, 28, 20, 23, 27, 0, 15, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2, 12, 17, 25, 16, 22, 19, 14, 21, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 6, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 1, 0, 0, 9, 0, 13, 26, + ]; + static BITSET_INDEX_CHUNKS: [[u8; 16]; 33] = [ + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 48], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 42, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 21, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 46, 0, 0, 0, 2], + [0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 30, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 46, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 30, 0, 44, 0, 30, 0, 30, 0, 40, 0, 33], + [0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 36, 43, 4, 0, 0, 0, 0, 51, 22, 3, 0, 12], + [0, 0, 0, 6, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 61, 46, 0, 0, 0, 0, 59, 0, 0, 23, 9, 0, 0], + [0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 2, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0], + [0, 14, 0, 14, 0, 0, 0, 0, 0, 14, 0, 2, 50, 0, 0, 0], + [0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 25, 0, 0, 0, 14, 24, 0, 0, 0, 0, 0, 0, 0, 0, 10], + [0, 31, 0, 46, 64, 0, 0, 38, 0, 0, 0, 46, 0, 0, 0, 0], + [0, 45, 2, 0, 0, 70, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 58, 0, 30, 0, 41, 0, 30, 0, 14, 0, 14, 35, 0, 0, 0], + [0, 62, 29, 60, 17, 0, 54, 69, 0, 56, 19, 27, 0, 63, 28, 0], + [0, 65, 37, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 68, 18, 67, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 8, 0], + [14, 0, 0, 0, 0, 7, 0, 16, 0, 0, 15, 0, 0, 14, 46, 0], + [39, 0, 0, 14, 2, 0, 0, 47, 0, 14, 0, 0, 0, 0, 0, 46], + [46, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [49, 0, 0, 0, 0, 0, 11, 0, 24, 20, 66, 0, 0, 0, 0, 0], + [72, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + ]; + static BITSET: [u64; 73] = [ + 0, 999, 1023, 1026, 3072, 8191, 65408, 65472, 1048575, 1966080, 2097151, 3932160, 4063232, + 8388607, 67043328, 67044351, 134152192, 264241152, 268435455, 3758096384, 4294901504, + 17112694784, 64424509440, 549218942976, 4393751543808, 35184372023296, 140737488355327, + 272678883688448, 279275953455104, 280925220896768, 281200098803712, 281474976448512, + 492581209243648, 2251524935778304, 2251795518717952, 4503595332403200, 4503599627370368, + 8708132091985919, 9007190731849728, 17732923532771328, 71212894229889024, + 144114915328655360, 144115183780888576, 144115188075855871, 284007976623144960, + 284008251501051904, 287948901175001088, 287948901242044416, 287953294926544896, + 504407547722072192, 1152640029630136320, 1152921496016912384, 2305840810190438400, + 2305843009213693952, 3458764513820540928, 4611615649683210238, 6917529027641082367, + 8217943420044312576, 9151595642915651584, 9223372032559808512, 17870283321406128128, + 18158513697557839872, 18302628889911885824, 18374686483949813760, 18428729675200069632, + 18446181123756130304, 18446181123756131327, 18446739675663040512, 18446744069414584320, + 18446744073709355007, 18446744073709486080, 18446744073709535232, 18446744073709551615, + ]; + + pub fn lookup(c: char) -> bool { + super::range_search( + c as u32, + &BITSET_CHUNKS_MAP, + BITSET_LAST_CHUNK_MAP, + &BITSET_INDEX_CHUNKS, + &BITSET, + ) + } +} + +#[rustfmt::skip] +pub mod uppercase { + static BITSET_LAST_CHUNK_MAP: (u16, u8) = (124, 6); + static BITSET_CHUNKS_MAP: [u8; 123] = [ + 12, 15, 0, 0, 11, 0, 0, 8, 5, 9, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 13, 0, 7, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, + 0, 0, 4, + ]; + static BITSET_INDEX_CHUNKS: [[u8; 16]; 17] = [ + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 10, 0, 38, 46, 44, 2], + [0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 51, 24, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 60, 62, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 54, 0, 0, 0, 0, 0, 43, 43, 40, 43, 56, 23, 34, 35], + [0, 0, 57, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 66, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66, 30], + [0, 11, 0, 12, 50, 37, 36, 45, 47, 6, 0, 0, 0, 49, 18, 53], + [15, 0, 60, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [22, 52, 43, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [25, 39, 42, 41, 59, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [58, 65, 29, 17, 48, 63, 31, 20, 55, 61, 64, 32, 28, 21, 16, 4], + ]; + static BITSET: [u64; 67] = [ + 0, 8, 116, 1023, 1024, 8383, 21882, 65535, 1048575, 8388607, 89478485, 134217726, + 2139095039, 4294967295, 17179869183, 1099511627775, 2199023190016, 4398046445568, + 17575006099264, 23456248059221, 70368743129088, 140737484161024, 140737488355327, + 280378317225728, 281470681743392, 281474976710655, 1169903278445909, 2251799813685247, + 9007198986305536, 17977448100528131, 18014398509481983, 288230371856744511, + 576460735123554305, 576460743713488896, 1080863910568919040, 1080897995681042176, + 1274187559846268630, 3122495741643543722, 6148633210533183488, 6148914689804861440, + 6148914690880001365, 6148914691236506283, 6148914691236516865, 6148914691236517205, + 6151773421467674709, 6184099063146390672, 7638198793012598101, 7783721355972007253, + 8863084067199903664, 9242793810247811072, 12273810184460391765, 13839347594782259332, + 13845730589451223040, 16613872850358272000, 16717361816799215616, 17293822586282573568, + 18374966856193736448, 18428729675200069632, 18442240474149289983, 18446274948748367189, + 18446462598732840960, 18446462598737035263, 18446466996779287551, 18446726481523637343, + 18446742974197924863, 18446742974197940223, 18446744069414584320, + ]; + + pub fn lookup(c: char) -> bool { + super::range_search( + c as u32, + &BITSET_CHUNKS_MAP, + BITSET_LAST_CHUNK_MAP, + &BITSET_INDEX_CHUNKS, + &BITSET, + ) + } +} + +#[rustfmt::skip] +pub mod white_space { + static BITSET_LAST_CHUNK_MAP: (u16, u8) = (12, 2); + static BITSET_CHUNKS_MAP: [u8; 9] = [ + 3, 0, 0, 0, 0, 1, 0, 0, 4, + ]; + static BITSET_INDEX_CHUNKS: [[u8; 16]; 5] = [ + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], + [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [4, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + ]; + static BITSET: [u64; 6] = [ + 0, 1, 2147483648, 4294967328, 4294983168, 144036023240703, + ]; + + pub fn lookup(c: char) -> bool { + super::range_search( + c as u32, + &BITSET_CHUNKS_MAP, + BITSET_LAST_CHUNK_MAP, + &BITSET_INDEX_CHUNKS, + &BITSET, + ) + } +} + +#[rustfmt::skip] +pub mod conversions { + pub fn to_lower(c: char) -> [char; 3] { + match bsearch_case_table(c, LOWERCASE_TABLE) { + None => [c, '\0', '\0'], + Some(index) => LOWERCASE_TABLE[index].1, + } + } + + pub fn to_upper(c: char) -> [char; 3] { + match bsearch_case_table(c, UPPERCASE_TABLE) { + None => [c, '\0', '\0'], + Some(index) => UPPERCASE_TABLE[index].1, + } + } + + fn bsearch_case_table(c: char, table: &[(char, [char; 3])]) -> Option { + table.binary_search_by(|&(key, _)| key.cmp(&c)).ok() + } + static LOWERCASE_TABLE: &[(char, [char; 3])] = &[ + ('A', ['a', '\u{0}', '\u{0}']), ('B', ['b', '\u{0}', '\u{0}']), + ('C', ['c', '\u{0}', '\u{0}']), ('D', ['d', '\u{0}', '\u{0}']), + ('E', ['e', '\u{0}', '\u{0}']), ('F', ['f', '\u{0}', '\u{0}']), + ('G', ['g', '\u{0}', '\u{0}']), ('H', ['h', '\u{0}', '\u{0}']), + ('I', ['i', '\u{0}', '\u{0}']), ('J', ['j', '\u{0}', '\u{0}']), + ('K', ['k', '\u{0}', '\u{0}']), ('L', ['l', '\u{0}', '\u{0}']), + ('M', ['m', '\u{0}', '\u{0}']), ('N', ['n', '\u{0}', '\u{0}']), + ('O', ['o', '\u{0}', '\u{0}']), ('P', ['p', '\u{0}', '\u{0}']), + ('Q', ['q', '\u{0}', '\u{0}']), ('R', ['r', '\u{0}', '\u{0}']), + ('S', ['s', '\u{0}', '\u{0}']), ('T', ['t', '\u{0}', '\u{0}']), + ('U', ['u', '\u{0}', '\u{0}']), ('V', ['v', '\u{0}', '\u{0}']), + ('W', ['w', '\u{0}', '\u{0}']), ('X', ['x', '\u{0}', '\u{0}']), + ('Y', ['y', '\u{0}', '\u{0}']), ('Z', ['z', '\u{0}', '\u{0}']), + ('\u{c0}', ['\u{e0}', '\u{0}', '\u{0}']), ('\u{c1}', ['\u{e1}', '\u{0}', '\u{0}']), + ('\u{c2}', ['\u{e2}', '\u{0}', '\u{0}']), ('\u{c3}', ['\u{e3}', '\u{0}', '\u{0}']), + ('\u{c4}', ['\u{e4}', '\u{0}', '\u{0}']), ('\u{c5}', ['\u{e5}', '\u{0}', '\u{0}']), + ('\u{c6}', ['\u{e6}', '\u{0}', '\u{0}']), ('\u{c7}', ['\u{e7}', '\u{0}', '\u{0}']), + ('\u{c8}', ['\u{e8}', '\u{0}', '\u{0}']), ('\u{c9}', ['\u{e9}', '\u{0}', '\u{0}']), + ('\u{ca}', ['\u{ea}', '\u{0}', '\u{0}']), ('\u{cb}', ['\u{eb}', '\u{0}', '\u{0}']), + ('\u{cc}', ['\u{ec}', '\u{0}', '\u{0}']), ('\u{cd}', ['\u{ed}', '\u{0}', '\u{0}']), + ('\u{ce}', ['\u{ee}', '\u{0}', '\u{0}']), ('\u{cf}', ['\u{ef}', '\u{0}', '\u{0}']), + ('\u{d0}', ['\u{f0}', '\u{0}', '\u{0}']), ('\u{d1}', ['\u{f1}', '\u{0}', '\u{0}']), + ('\u{d2}', ['\u{f2}', '\u{0}', '\u{0}']), ('\u{d3}', ['\u{f3}', '\u{0}', '\u{0}']), + ('\u{d4}', ['\u{f4}', '\u{0}', '\u{0}']), ('\u{d5}', ['\u{f5}', '\u{0}', '\u{0}']), + ('\u{d6}', ['\u{f6}', '\u{0}', '\u{0}']), ('\u{d8}', ['\u{f8}', '\u{0}', '\u{0}']), + ('\u{d9}', ['\u{f9}', '\u{0}', '\u{0}']), ('\u{da}', ['\u{fa}', '\u{0}', '\u{0}']), + ('\u{db}', ['\u{fb}', '\u{0}', '\u{0}']), ('\u{dc}', ['\u{fc}', '\u{0}', '\u{0}']), + ('\u{dd}', ['\u{fd}', '\u{0}', '\u{0}']), ('\u{de}', ['\u{fe}', '\u{0}', '\u{0}']), + ('\u{100}', ['\u{101}', '\u{0}', '\u{0}']), ('\u{102}', ['\u{103}', '\u{0}', '\u{0}']), + ('\u{104}', ['\u{105}', '\u{0}', '\u{0}']), ('\u{106}', ['\u{107}', '\u{0}', '\u{0}']), + ('\u{108}', ['\u{109}', '\u{0}', '\u{0}']), ('\u{10a}', ['\u{10b}', '\u{0}', '\u{0}']), + ('\u{10c}', ['\u{10d}', '\u{0}', '\u{0}']), ('\u{10e}', ['\u{10f}', '\u{0}', '\u{0}']), + ('\u{110}', ['\u{111}', '\u{0}', '\u{0}']), ('\u{112}', ['\u{113}', '\u{0}', '\u{0}']), + ('\u{114}', ['\u{115}', '\u{0}', '\u{0}']), ('\u{116}', ['\u{117}', '\u{0}', '\u{0}']), + ('\u{118}', ['\u{119}', '\u{0}', '\u{0}']), ('\u{11a}', ['\u{11b}', '\u{0}', '\u{0}']), + ('\u{11c}', ['\u{11d}', '\u{0}', '\u{0}']), ('\u{11e}', ['\u{11f}', '\u{0}', '\u{0}']), + ('\u{120}', ['\u{121}', '\u{0}', '\u{0}']), ('\u{122}', ['\u{123}', '\u{0}', '\u{0}']), + ('\u{124}', ['\u{125}', '\u{0}', '\u{0}']), ('\u{126}', ['\u{127}', '\u{0}', '\u{0}']), + ('\u{128}', ['\u{129}', '\u{0}', '\u{0}']), ('\u{12a}', ['\u{12b}', '\u{0}', '\u{0}']), + ('\u{12c}', ['\u{12d}', '\u{0}', '\u{0}']), ('\u{12e}', ['\u{12f}', '\u{0}', '\u{0}']), + ('\u{130}', ['i', '\u{307}', '\u{0}']), ('\u{132}', ['\u{133}', '\u{0}', '\u{0}']), + ('\u{134}', ['\u{135}', '\u{0}', '\u{0}']), ('\u{136}', ['\u{137}', '\u{0}', '\u{0}']), + ('\u{139}', ['\u{13a}', '\u{0}', '\u{0}']), ('\u{13b}', ['\u{13c}', '\u{0}', '\u{0}']), + ('\u{13d}', ['\u{13e}', '\u{0}', '\u{0}']), ('\u{13f}', ['\u{140}', '\u{0}', '\u{0}']), + ('\u{141}', ['\u{142}', '\u{0}', '\u{0}']), ('\u{143}', ['\u{144}', '\u{0}', '\u{0}']), + ('\u{145}', ['\u{146}', '\u{0}', '\u{0}']), ('\u{147}', ['\u{148}', '\u{0}', '\u{0}']), + ('\u{14a}', ['\u{14b}', '\u{0}', '\u{0}']), ('\u{14c}', ['\u{14d}', '\u{0}', '\u{0}']), + ('\u{14e}', ['\u{14f}', '\u{0}', '\u{0}']), ('\u{150}', ['\u{151}', '\u{0}', '\u{0}']), + ('\u{152}', ['\u{153}', '\u{0}', '\u{0}']), ('\u{154}', ['\u{155}', '\u{0}', '\u{0}']), + ('\u{156}', ['\u{157}', '\u{0}', '\u{0}']), ('\u{158}', ['\u{159}', '\u{0}', '\u{0}']), + ('\u{15a}', ['\u{15b}', '\u{0}', '\u{0}']), ('\u{15c}', ['\u{15d}', '\u{0}', '\u{0}']), + ('\u{15e}', ['\u{15f}', '\u{0}', '\u{0}']), ('\u{160}', ['\u{161}', '\u{0}', '\u{0}']), + ('\u{162}', ['\u{163}', '\u{0}', '\u{0}']), ('\u{164}', ['\u{165}', '\u{0}', '\u{0}']), + ('\u{166}', ['\u{167}', '\u{0}', '\u{0}']), ('\u{168}', ['\u{169}', '\u{0}', '\u{0}']), + ('\u{16a}', ['\u{16b}', '\u{0}', '\u{0}']), ('\u{16c}', ['\u{16d}', '\u{0}', '\u{0}']), + ('\u{16e}', ['\u{16f}', '\u{0}', '\u{0}']), ('\u{170}', ['\u{171}', '\u{0}', '\u{0}']), + ('\u{172}', ['\u{173}', '\u{0}', '\u{0}']), ('\u{174}', ['\u{175}', '\u{0}', '\u{0}']), + ('\u{176}', ['\u{177}', '\u{0}', '\u{0}']), ('\u{178}', ['\u{ff}', '\u{0}', '\u{0}']), + ('\u{179}', ['\u{17a}', '\u{0}', '\u{0}']), ('\u{17b}', ['\u{17c}', '\u{0}', '\u{0}']), + ('\u{17d}', ['\u{17e}', '\u{0}', '\u{0}']), ('\u{181}', ['\u{253}', '\u{0}', '\u{0}']), + ('\u{182}', ['\u{183}', '\u{0}', '\u{0}']), ('\u{184}', ['\u{185}', '\u{0}', '\u{0}']), + ('\u{186}', ['\u{254}', '\u{0}', '\u{0}']), ('\u{187}', ['\u{188}', '\u{0}', '\u{0}']), + ('\u{189}', ['\u{256}', '\u{0}', '\u{0}']), ('\u{18a}', ['\u{257}', '\u{0}', '\u{0}']), + ('\u{18b}', ['\u{18c}', '\u{0}', '\u{0}']), ('\u{18e}', ['\u{1dd}', '\u{0}', '\u{0}']), + ('\u{18f}', ['\u{259}', '\u{0}', '\u{0}']), ('\u{190}', ['\u{25b}', '\u{0}', '\u{0}']), + ('\u{191}', ['\u{192}', '\u{0}', '\u{0}']), ('\u{193}', ['\u{260}', '\u{0}', '\u{0}']), + ('\u{194}', ['\u{263}', '\u{0}', '\u{0}']), ('\u{196}', ['\u{269}', '\u{0}', '\u{0}']), + ('\u{197}', ['\u{268}', '\u{0}', '\u{0}']), ('\u{198}', ['\u{199}', '\u{0}', '\u{0}']), + ('\u{19c}', ['\u{26f}', '\u{0}', '\u{0}']), ('\u{19d}', ['\u{272}', '\u{0}', '\u{0}']), + ('\u{19f}', ['\u{275}', '\u{0}', '\u{0}']), ('\u{1a0}', ['\u{1a1}', '\u{0}', '\u{0}']), + ('\u{1a2}', ['\u{1a3}', '\u{0}', '\u{0}']), ('\u{1a4}', ['\u{1a5}', '\u{0}', '\u{0}']), + ('\u{1a6}', ['\u{280}', '\u{0}', '\u{0}']), ('\u{1a7}', ['\u{1a8}', '\u{0}', '\u{0}']), + ('\u{1a9}', ['\u{283}', '\u{0}', '\u{0}']), ('\u{1ac}', ['\u{1ad}', '\u{0}', '\u{0}']), + ('\u{1ae}', ['\u{288}', '\u{0}', '\u{0}']), ('\u{1af}', ['\u{1b0}', '\u{0}', '\u{0}']), + ('\u{1b1}', ['\u{28a}', '\u{0}', '\u{0}']), ('\u{1b2}', ['\u{28b}', '\u{0}', '\u{0}']), + ('\u{1b3}', ['\u{1b4}', '\u{0}', '\u{0}']), ('\u{1b5}', ['\u{1b6}', '\u{0}', '\u{0}']), + ('\u{1b7}', ['\u{292}', '\u{0}', '\u{0}']), ('\u{1b8}', ['\u{1b9}', '\u{0}', '\u{0}']), + ('\u{1bc}', ['\u{1bd}', '\u{0}', '\u{0}']), ('\u{1c4}', ['\u{1c6}', '\u{0}', '\u{0}']), + ('\u{1c5}', ['\u{1c6}', '\u{0}', '\u{0}']), ('\u{1c7}', ['\u{1c9}', '\u{0}', '\u{0}']), + ('\u{1c8}', ['\u{1c9}', '\u{0}', '\u{0}']), ('\u{1ca}', ['\u{1cc}', '\u{0}', '\u{0}']), + ('\u{1cb}', ['\u{1cc}', '\u{0}', '\u{0}']), ('\u{1cd}', ['\u{1ce}', '\u{0}', '\u{0}']), + ('\u{1cf}', ['\u{1d0}', '\u{0}', '\u{0}']), ('\u{1d1}', ['\u{1d2}', '\u{0}', '\u{0}']), + ('\u{1d3}', ['\u{1d4}', '\u{0}', '\u{0}']), ('\u{1d5}', ['\u{1d6}', '\u{0}', '\u{0}']), + ('\u{1d7}', ['\u{1d8}', '\u{0}', '\u{0}']), ('\u{1d9}', ['\u{1da}', '\u{0}', '\u{0}']), + ('\u{1db}', ['\u{1dc}', '\u{0}', '\u{0}']), ('\u{1de}', ['\u{1df}', '\u{0}', '\u{0}']), + ('\u{1e0}', ['\u{1e1}', '\u{0}', '\u{0}']), ('\u{1e2}', ['\u{1e3}', '\u{0}', '\u{0}']), + ('\u{1e4}', ['\u{1e5}', '\u{0}', '\u{0}']), ('\u{1e6}', ['\u{1e7}', '\u{0}', '\u{0}']), + ('\u{1e8}', ['\u{1e9}', '\u{0}', '\u{0}']), ('\u{1ea}', ['\u{1eb}', '\u{0}', '\u{0}']), + ('\u{1ec}', ['\u{1ed}', '\u{0}', '\u{0}']), ('\u{1ee}', ['\u{1ef}', '\u{0}', '\u{0}']), + ('\u{1f1}', ['\u{1f3}', '\u{0}', '\u{0}']), ('\u{1f2}', ['\u{1f3}', '\u{0}', '\u{0}']), + ('\u{1f4}', ['\u{1f5}', '\u{0}', '\u{0}']), ('\u{1f6}', ['\u{195}', '\u{0}', '\u{0}']), + ('\u{1f7}', ['\u{1bf}', '\u{0}', '\u{0}']), ('\u{1f8}', ['\u{1f9}', '\u{0}', '\u{0}']), + ('\u{1fa}', ['\u{1fb}', '\u{0}', '\u{0}']), ('\u{1fc}', ['\u{1fd}', '\u{0}', '\u{0}']), + ('\u{1fe}', ['\u{1ff}', '\u{0}', '\u{0}']), ('\u{200}', ['\u{201}', '\u{0}', '\u{0}']), + ('\u{202}', ['\u{203}', '\u{0}', '\u{0}']), ('\u{204}', ['\u{205}', '\u{0}', '\u{0}']), + ('\u{206}', ['\u{207}', '\u{0}', '\u{0}']), ('\u{208}', ['\u{209}', '\u{0}', '\u{0}']), + ('\u{20a}', ['\u{20b}', '\u{0}', '\u{0}']), ('\u{20c}', ['\u{20d}', '\u{0}', '\u{0}']), + ('\u{20e}', ['\u{20f}', '\u{0}', '\u{0}']), ('\u{210}', ['\u{211}', '\u{0}', '\u{0}']), + ('\u{212}', ['\u{213}', '\u{0}', '\u{0}']), ('\u{214}', ['\u{215}', '\u{0}', '\u{0}']), + ('\u{216}', ['\u{217}', '\u{0}', '\u{0}']), ('\u{218}', ['\u{219}', '\u{0}', '\u{0}']), + ('\u{21a}', ['\u{21b}', '\u{0}', '\u{0}']), ('\u{21c}', ['\u{21d}', '\u{0}', '\u{0}']), + ('\u{21e}', ['\u{21f}', '\u{0}', '\u{0}']), ('\u{220}', ['\u{19e}', '\u{0}', '\u{0}']), + ('\u{222}', ['\u{223}', '\u{0}', '\u{0}']), ('\u{224}', ['\u{225}', '\u{0}', '\u{0}']), + ('\u{226}', ['\u{227}', '\u{0}', '\u{0}']), ('\u{228}', ['\u{229}', '\u{0}', '\u{0}']), + ('\u{22a}', ['\u{22b}', '\u{0}', '\u{0}']), ('\u{22c}', ['\u{22d}', '\u{0}', '\u{0}']), + ('\u{22e}', ['\u{22f}', '\u{0}', '\u{0}']), ('\u{230}', ['\u{231}', '\u{0}', '\u{0}']), + ('\u{232}', ['\u{233}', '\u{0}', '\u{0}']), ('\u{23a}', ['\u{2c65}', '\u{0}', '\u{0}']), + ('\u{23b}', ['\u{23c}', '\u{0}', '\u{0}']), ('\u{23d}', ['\u{19a}', '\u{0}', '\u{0}']), + ('\u{23e}', ['\u{2c66}', '\u{0}', '\u{0}']), ('\u{241}', ['\u{242}', '\u{0}', '\u{0}']), + ('\u{243}', ['\u{180}', '\u{0}', '\u{0}']), ('\u{244}', ['\u{289}', '\u{0}', '\u{0}']), + ('\u{245}', ['\u{28c}', '\u{0}', '\u{0}']), ('\u{246}', ['\u{247}', '\u{0}', '\u{0}']), + ('\u{248}', ['\u{249}', '\u{0}', '\u{0}']), ('\u{24a}', ['\u{24b}', '\u{0}', '\u{0}']), + ('\u{24c}', ['\u{24d}', '\u{0}', '\u{0}']), ('\u{24e}', ['\u{24f}', '\u{0}', '\u{0}']), + ('\u{370}', ['\u{371}', '\u{0}', '\u{0}']), ('\u{372}', ['\u{373}', '\u{0}', '\u{0}']), + ('\u{376}', ['\u{377}', '\u{0}', '\u{0}']), ('\u{37f}', ['\u{3f3}', '\u{0}', '\u{0}']), + ('\u{386}', ['\u{3ac}', '\u{0}', '\u{0}']), ('\u{388}', ['\u{3ad}', '\u{0}', '\u{0}']), + ('\u{389}', ['\u{3ae}', '\u{0}', '\u{0}']), ('\u{38a}', ['\u{3af}', '\u{0}', '\u{0}']), + ('\u{38c}', ['\u{3cc}', '\u{0}', '\u{0}']), ('\u{38e}', ['\u{3cd}', '\u{0}', '\u{0}']), + ('\u{38f}', ['\u{3ce}', '\u{0}', '\u{0}']), ('\u{391}', ['\u{3b1}', '\u{0}', '\u{0}']), + ('\u{392}', ['\u{3b2}', '\u{0}', '\u{0}']), ('\u{393}', ['\u{3b3}', '\u{0}', '\u{0}']), + ('\u{394}', ['\u{3b4}', '\u{0}', '\u{0}']), ('\u{395}', ['\u{3b5}', '\u{0}', '\u{0}']), + ('\u{396}', ['\u{3b6}', '\u{0}', '\u{0}']), ('\u{397}', ['\u{3b7}', '\u{0}', '\u{0}']), + ('\u{398}', ['\u{3b8}', '\u{0}', '\u{0}']), ('\u{399}', ['\u{3b9}', '\u{0}', '\u{0}']), + ('\u{39a}', ['\u{3ba}', '\u{0}', '\u{0}']), ('\u{39b}', ['\u{3bb}', '\u{0}', '\u{0}']), + ('\u{39c}', ['\u{3bc}', '\u{0}', '\u{0}']), ('\u{39d}', ['\u{3bd}', '\u{0}', '\u{0}']), + ('\u{39e}', ['\u{3be}', '\u{0}', '\u{0}']), ('\u{39f}', ['\u{3bf}', '\u{0}', '\u{0}']), + ('\u{3a0}', ['\u{3c0}', '\u{0}', '\u{0}']), ('\u{3a1}', ['\u{3c1}', '\u{0}', '\u{0}']), + ('\u{3a3}', ['\u{3c3}', '\u{0}', '\u{0}']), ('\u{3a4}', ['\u{3c4}', '\u{0}', '\u{0}']), + ('\u{3a5}', ['\u{3c5}', '\u{0}', '\u{0}']), ('\u{3a6}', ['\u{3c6}', '\u{0}', '\u{0}']), + ('\u{3a7}', ['\u{3c7}', '\u{0}', '\u{0}']), ('\u{3a8}', ['\u{3c8}', '\u{0}', '\u{0}']), + ('\u{3a9}', ['\u{3c9}', '\u{0}', '\u{0}']), ('\u{3aa}', ['\u{3ca}', '\u{0}', '\u{0}']), + ('\u{3ab}', ['\u{3cb}', '\u{0}', '\u{0}']), ('\u{3cf}', ['\u{3d7}', '\u{0}', '\u{0}']), + ('\u{3d8}', ['\u{3d9}', '\u{0}', '\u{0}']), ('\u{3da}', ['\u{3db}', '\u{0}', '\u{0}']), + ('\u{3dc}', ['\u{3dd}', '\u{0}', '\u{0}']), ('\u{3de}', ['\u{3df}', '\u{0}', '\u{0}']), + ('\u{3e0}', ['\u{3e1}', '\u{0}', '\u{0}']), ('\u{3e2}', ['\u{3e3}', '\u{0}', '\u{0}']), + ('\u{3e4}', ['\u{3e5}', '\u{0}', '\u{0}']), ('\u{3e6}', ['\u{3e7}', '\u{0}', '\u{0}']), + ('\u{3e8}', ['\u{3e9}', '\u{0}', '\u{0}']), ('\u{3ea}', ['\u{3eb}', '\u{0}', '\u{0}']), + ('\u{3ec}', ['\u{3ed}', '\u{0}', '\u{0}']), ('\u{3ee}', ['\u{3ef}', '\u{0}', '\u{0}']), + ('\u{3f4}', ['\u{3b8}', '\u{0}', '\u{0}']), ('\u{3f7}', ['\u{3f8}', '\u{0}', '\u{0}']), + ('\u{3f9}', ['\u{3f2}', '\u{0}', '\u{0}']), ('\u{3fa}', ['\u{3fb}', '\u{0}', '\u{0}']), + ('\u{3fd}', ['\u{37b}', '\u{0}', '\u{0}']), ('\u{3fe}', ['\u{37c}', '\u{0}', '\u{0}']), + ('\u{3ff}', ['\u{37d}', '\u{0}', '\u{0}']), ('\u{400}', ['\u{450}', '\u{0}', '\u{0}']), + ('\u{401}', ['\u{451}', '\u{0}', '\u{0}']), ('\u{402}', ['\u{452}', '\u{0}', '\u{0}']), + ('\u{403}', ['\u{453}', '\u{0}', '\u{0}']), ('\u{404}', ['\u{454}', '\u{0}', '\u{0}']), + ('\u{405}', ['\u{455}', '\u{0}', '\u{0}']), ('\u{406}', ['\u{456}', '\u{0}', '\u{0}']), + ('\u{407}', ['\u{457}', '\u{0}', '\u{0}']), ('\u{408}', ['\u{458}', '\u{0}', '\u{0}']), + ('\u{409}', ['\u{459}', '\u{0}', '\u{0}']), ('\u{40a}', ['\u{45a}', '\u{0}', '\u{0}']), + ('\u{40b}', ['\u{45b}', '\u{0}', '\u{0}']), ('\u{40c}', ['\u{45c}', '\u{0}', '\u{0}']), + ('\u{40d}', ['\u{45d}', '\u{0}', '\u{0}']), ('\u{40e}', ['\u{45e}', '\u{0}', '\u{0}']), + ('\u{40f}', ['\u{45f}', '\u{0}', '\u{0}']), ('\u{410}', ['\u{430}', '\u{0}', '\u{0}']), + ('\u{411}', ['\u{431}', '\u{0}', '\u{0}']), ('\u{412}', ['\u{432}', '\u{0}', '\u{0}']), + ('\u{413}', ['\u{433}', '\u{0}', '\u{0}']), ('\u{414}', ['\u{434}', '\u{0}', '\u{0}']), + ('\u{415}', ['\u{435}', '\u{0}', '\u{0}']), ('\u{416}', ['\u{436}', '\u{0}', '\u{0}']), + ('\u{417}', ['\u{437}', '\u{0}', '\u{0}']), ('\u{418}', ['\u{438}', '\u{0}', '\u{0}']), + ('\u{419}', ['\u{439}', '\u{0}', '\u{0}']), ('\u{41a}', ['\u{43a}', '\u{0}', '\u{0}']), + ('\u{41b}', ['\u{43b}', '\u{0}', '\u{0}']), ('\u{41c}', ['\u{43c}', '\u{0}', '\u{0}']), + ('\u{41d}', ['\u{43d}', '\u{0}', '\u{0}']), ('\u{41e}', ['\u{43e}', '\u{0}', '\u{0}']), + ('\u{41f}', ['\u{43f}', '\u{0}', '\u{0}']), ('\u{420}', ['\u{440}', '\u{0}', '\u{0}']), + ('\u{421}', ['\u{441}', '\u{0}', '\u{0}']), ('\u{422}', ['\u{442}', '\u{0}', '\u{0}']), + ('\u{423}', ['\u{443}', '\u{0}', '\u{0}']), ('\u{424}', ['\u{444}', '\u{0}', '\u{0}']), + ('\u{425}', ['\u{445}', '\u{0}', '\u{0}']), ('\u{426}', ['\u{446}', '\u{0}', '\u{0}']), + ('\u{427}', ['\u{447}', '\u{0}', '\u{0}']), ('\u{428}', ['\u{448}', '\u{0}', '\u{0}']), + ('\u{429}', ['\u{449}', '\u{0}', '\u{0}']), ('\u{42a}', ['\u{44a}', '\u{0}', '\u{0}']), + ('\u{42b}', ['\u{44b}', '\u{0}', '\u{0}']), ('\u{42c}', ['\u{44c}', '\u{0}', '\u{0}']), + ('\u{42d}', ['\u{44d}', '\u{0}', '\u{0}']), ('\u{42e}', ['\u{44e}', '\u{0}', '\u{0}']), + ('\u{42f}', ['\u{44f}', '\u{0}', '\u{0}']), ('\u{460}', ['\u{461}', '\u{0}', '\u{0}']), + ('\u{462}', ['\u{463}', '\u{0}', '\u{0}']), ('\u{464}', ['\u{465}', '\u{0}', '\u{0}']), + ('\u{466}', ['\u{467}', '\u{0}', '\u{0}']), ('\u{468}', ['\u{469}', '\u{0}', '\u{0}']), + ('\u{46a}', ['\u{46b}', '\u{0}', '\u{0}']), ('\u{46c}', ['\u{46d}', '\u{0}', '\u{0}']), + ('\u{46e}', ['\u{46f}', '\u{0}', '\u{0}']), ('\u{470}', ['\u{471}', '\u{0}', '\u{0}']), + ('\u{472}', ['\u{473}', '\u{0}', '\u{0}']), ('\u{474}', ['\u{475}', '\u{0}', '\u{0}']), + ('\u{476}', ['\u{477}', '\u{0}', '\u{0}']), ('\u{478}', ['\u{479}', '\u{0}', '\u{0}']), + ('\u{47a}', ['\u{47b}', '\u{0}', '\u{0}']), ('\u{47c}', ['\u{47d}', '\u{0}', '\u{0}']), + ('\u{47e}', ['\u{47f}', '\u{0}', '\u{0}']), ('\u{480}', ['\u{481}', '\u{0}', '\u{0}']), + ('\u{48a}', ['\u{48b}', '\u{0}', '\u{0}']), ('\u{48c}', ['\u{48d}', '\u{0}', '\u{0}']), + ('\u{48e}', ['\u{48f}', '\u{0}', '\u{0}']), ('\u{490}', ['\u{491}', '\u{0}', '\u{0}']), + ('\u{492}', ['\u{493}', '\u{0}', '\u{0}']), ('\u{494}', ['\u{495}', '\u{0}', '\u{0}']), + ('\u{496}', ['\u{497}', '\u{0}', '\u{0}']), ('\u{498}', ['\u{499}', '\u{0}', '\u{0}']), + ('\u{49a}', ['\u{49b}', '\u{0}', '\u{0}']), ('\u{49c}', ['\u{49d}', '\u{0}', '\u{0}']), + ('\u{49e}', ['\u{49f}', '\u{0}', '\u{0}']), ('\u{4a0}', ['\u{4a1}', '\u{0}', '\u{0}']), + ('\u{4a2}', ['\u{4a3}', '\u{0}', '\u{0}']), ('\u{4a4}', ['\u{4a5}', '\u{0}', '\u{0}']), + ('\u{4a6}', ['\u{4a7}', '\u{0}', '\u{0}']), ('\u{4a8}', ['\u{4a9}', '\u{0}', '\u{0}']), + ('\u{4aa}', ['\u{4ab}', '\u{0}', '\u{0}']), ('\u{4ac}', ['\u{4ad}', '\u{0}', '\u{0}']), + ('\u{4ae}', ['\u{4af}', '\u{0}', '\u{0}']), ('\u{4b0}', ['\u{4b1}', '\u{0}', '\u{0}']), + ('\u{4b2}', ['\u{4b3}', '\u{0}', '\u{0}']), ('\u{4b4}', ['\u{4b5}', '\u{0}', '\u{0}']), + ('\u{4b6}', ['\u{4b7}', '\u{0}', '\u{0}']), ('\u{4b8}', ['\u{4b9}', '\u{0}', '\u{0}']), + ('\u{4ba}', ['\u{4bb}', '\u{0}', '\u{0}']), ('\u{4bc}', ['\u{4bd}', '\u{0}', '\u{0}']), + ('\u{4be}', ['\u{4bf}', '\u{0}', '\u{0}']), ('\u{4c0}', ['\u{4cf}', '\u{0}', '\u{0}']), + ('\u{4c1}', ['\u{4c2}', '\u{0}', '\u{0}']), ('\u{4c3}', ['\u{4c4}', '\u{0}', '\u{0}']), + ('\u{4c5}', ['\u{4c6}', '\u{0}', '\u{0}']), ('\u{4c7}', ['\u{4c8}', '\u{0}', '\u{0}']), + ('\u{4c9}', ['\u{4ca}', '\u{0}', '\u{0}']), ('\u{4cb}', ['\u{4cc}', '\u{0}', '\u{0}']), + ('\u{4cd}', ['\u{4ce}', '\u{0}', '\u{0}']), ('\u{4d0}', ['\u{4d1}', '\u{0}', '\u{0}']), + ('\u{4d2}', ['\u{4d3}', '\u{0}', '\u{0}']), ('\u{4d4}', ['\u{4d5}', '\u{0}', '\u{0}']), + ('\u{4d6}', ['\u{4d7}', '\u{0}', '\u{0}']), ('\u{4d8}', ['\u{4d9}', '\u{0}', '\u{0}']), + ('\u{4da}', ['\u{4db}', '\u{0}', '\u{0}']), ('\u{4dc}', ['\u{4dd}', '\u{0}', '\u{0}']), + ('\u{4de}', ['\u{4df}', '\u{0}', '\u{0}']), ('\u{4e0}', ['\u{4e1}', '\u{0}', '\u{0}']), + ('\u{4e2}', ['\u{4e3}', '\u{0}', '\u{0}']), ('\u{4e4}', ['\u{4e5}', '\u{0}', '\u{0}']), + ('\u{4e6}', ['\u{4e7}', '\u{0}', '\u{0}']), ('\u{4e8}', ['\u{4e9}', '\u{0}', '\u{0}']), + ('\u{4ea}', ['\u{4eb}', '\u{0}', '\u{0}']), ('\u{4ec}', ['\u{4ed}', '\u{0}', '\u{0}']), + ('\u{4ee}', ['\u{4ef}', '\u{0}', '\u{0}']), ('\u{4f0}', ['\u{4f1}', '\u{0}', '\u{0}']), + ('\u{4f2}', ['\u{4f3}', '\u{0}', '\u{0}']), ('\u{4f4}', ['\u{4f5}', '\u{0}', '\u{0}']), + ('\u{4f6}', ['\u{4f7}', '\u{0}', '\u{0}']), ('\u{4f8}', ['\u{4f9}', '\u{0}', '\u{0}']), + ('\u{4fa}', ['\u{4fb}', '\u{0}', '\u{0}']), ('\u{4fc}', ['\u{4fd}', '\u{0}', '\u{0}']), + ('\u{4fe}', ['\u{4ff}', '\u{0}', '\u{0}']), ('\u{500}', ['\u{501}', '\u{0}', '\u{0}']), + ('\u{502}', ['\u{503}', '\u{0}', '\u{0}']), ('\u{504}', ['\u{505}', '\u{0}', '\u{0}']), + ('\u{506}', ['\u{507}', '\u{0}', '\u{0}']), ('\u{508}', ['\u{509}', '\u{0}', '\u{0}']), + ('\u{50a}', ['\u{50b}', '\u{0}', '\u{0}']), ('\u{50c}', ['\u{50d}', '\u{0}', '\u{0}']), + ('\u{50e}', ['\u{50f}', '\u{0}', '\u{0}']), ('\u{510}', ['\u{511}', '\u{0}', '\u{0}']), + ('\u{512}', ['\u{513}', '\u{0}', '\u{0}']), ('\u{514}', ['\u{515}', '\u{0}', '\u{0}']), + ('\u{516}', ['\u{517}', '\u{0}', '\u{0}']), ('\u{518}', ['\u{519}', '\u{0}', '\u{0}']), + ('\u{51a}', ['\u{51b}', '\u{0}', '\u{0}']), ('\u{51c}', ['\u{51d}', '\u{0}', '\u{0}']), + ('\u{51e}', ['\u{51f}', '\u{0}', '\u{0}']), ('\u{520}', ['\u{521}', '\u{0}', '\u{0}']), + ('\u{522}', ['\u{523}', '\u{0}', '\u{0}']), ('\u{524}', ['\u{525}', '\u{0}', '\u{0}']), + ('\u{526}', ['\u{527}', '\u{0}', '\u{0}']), ('\u{528}', ['\u{529}', '\u{0}', '\u{0}']), + ('\u{52a}', ['\u{52b}', '\u{0}', '\u{0}']), ('\u{52c}', ['\u{52d}', '\u{0}', '\u{0}']), + ('\u{52e}', ['\u{52f}', '\u{0}', '\u{0}']), ('\u{531}', ['\u{561}', '\u{0}', '\u{0}']), + ('\u{532}', ['\u{562}', '\u{0}', '\u{0}']), ('\u{533}', ['\u{563}', '\u{0}', '\u{0}']), + ('\u{534}', ['\u{564}', '\u{0}', '\u{0}']), ('\u{535}', ['\u{565}', '\u{0}', '\u{0}']), + ('\u{536}', ['\u{566}', '\u{0}', '\u{0}']), ('\u{537}', ['\u{567}', '\u{0}', '\u{0}']), + ('\u{538}', ['\u{568}', '\u{0}', '\u{0}']), ('\u{539}', ['\u{569}', '\u{0}', '\u{0}']), + ('\u{53a}', ['\u{56a}', '\u{0}', '\u{0}']), ('\u{53b}', ['\u{56b}', '\u{0}', '\u{0}']), + ('\u{53c}', ['\u{56c}', '\u{0}', '\u{0}']), ('\u{53d}', ['\u{56d}', '\u{0}', '\u{0}']), + ('\u{53e}', ['\u{56e}', '\u{0}', '\u{0}']), ('\u{53f}', ['\u{56f}', '\u{0}', '\u{0}']), + ('\u{540}', ['\u{570}', '\u{0}', '\u{0}']), ('\u{541}', ['\u{571}', '\u{0}', '\u{0}']), + ('\u{542}', ['\u{572}', '\u{0}', '\u{0}']), ('\u{543}', ['\u{573}', '\u{0}', '\u{0}']), + ('\u{544}', ['\u{574}', '\u{0}', '\u{0}']), ('\u{545}', ['\u{575}', '\u{0}', '\u{0}']), + ('\u{546}', ['\u{576}', '\u{0}', '\u{0}']), ('\u{547}', ['\u{577}', '\u{0}', '\u{0}']), + ('\u{548}', ['\u{578}', '\u{0}', '\u{0}']), ('\u{549}', ['\u{579}', '\u{0}', '\u{0}']), + ('\u{54a}', ['\u{57a}', '\u{0}', '\u{0}']), ('\u{54b}', ['\u{57b}', '\u{0}', '\u{0}']), + ('\u{54c}', ['\u{57c}', '\u{0}', '\u{0}']), ('\u{54d}', ['\u{57d}', '\u{0}', '\u{0}']), + ('\u{54e}', ['\u{57e}', '\u{0}', '\u{0}']), ('\u{54f}', ['\u{57f}', '\u{0}', '\u{0}']), + ('\u{550}', ['\u{580}', '\u{0}', '\u{0}']), ('\u{551}', ['\u{581}', '\u{0}', '\u{0}']), + ('\u{552}', ['\u{582}', '\u{0}', '\u{0}']), ('\u{553}', ['\u{583}', '\u{0}', '\u{0}']), + ('\u{554}', ['\u{584}', '\u{0}', '\u{0}']), ('\u{555}', ['\u{585}', '\u{0}', '\u{0}']), + ('\u{556}', ['\u{586}', '\u{0}', '\u{0}']), ('\u{10a0}', ['\u{2d00}', '\u{0}', '\u{0}']), + ('\u{10a1}', ['\u{2d01}', '\u{0}', '\u{0}']), ('\u{10a2}', ['\u{2d02}', '\u{0}', '\u{0}']), + ('\u{10a3}', ['\u{2d03}', '\u{0}', '\u{0}']), ('\u{10a4}', ['\u{2d04}', '\u{0}', '\u{0}']), + ('\u{10a5}', ['\u{2d05}', '\u{0}', '\u{0}']), ('\u{10a6}', ['\u{2d06}', '\u{0}', '\u{0}']), + ('\u{10a7}', ['\u{2d07}', '\u{0}', '\u{0}']), ('\u{10a8}', ['\u{2d08}', '\u{0}', '\u{0}']), + ('\u{10a9}', ['\u{2d09}', '\u{0}', '\u{0}']), ('\u{10aa}', ['\u{2d0a}', '\u{0}', '\u{0}']), + ('\u{10ab}', ['\u{2d0b}', '\u{0}', '\u{0}']), ('\u{10ac}', ['\u{2d0c}', '\u{0}', '\u{0}']), + ('\u{10ad}', ['\u{2d0d}', '\u{0}', '\u{0}']), ('\u{10ae}', ['\u{2d0e}', '\u{0}', '\u{0}']), + ('\u{10af}', ['\u{2d0f}', '\u{0}', '\u{0}']), ('\u{10b0}', ['\u{2d10}', '\u{0}', '\u{0}']), + ('\u{10b1}', ['\u{2d11}', '\u{0}', '\u{0}']), ('\u{10b2}', ['\u{2d12}', '\u{0}', '\u{0}']), + ('\u{10b3}', ['\u{2d13}', '\u{0}', '\u{0}']), ('\u{10b4}', ['\u{2d14}', '\u{0}', '\u{0}']), + ('\u{10b5}', ['\u{2d15}', '\u{0}', '\u{0}']), ('\u{10b6}', ['\u{2d16}', '\u{0}', '\u{0}']), + ('\u{10b7}', ['\u{2d17}', '\u{0}', '\u{0}']), ('\u{10b8}', ['\u{2d18}', '\u{0}', '\u{0}']), + ('\u{10b9}', ['\u{2d19}', '\u{0}', '\u{0}']), ('\u{10ba}', ['\u{2d1a}', '\u{0}', '\u{0}']), + ('\u{10bb}', ['\u{2d1b}', '\u{0}', '\u{0}']), ('\u{10bc}', ['\u{2d1c}', '\u{0}', '\u{0}']), + ('\u{10bd}', ['\u{2d1d}', '\u{0}', '\u{0}']), ('\u{10be}', ['\u{2d1e}', '\u{0}', '\u{0}']), + ('\u{10bf}', ['\u{2d1f}', '\u{0}', '\u{0}']), ('\u{10c0}', ['\u{2d20}', '\u{0}', '\u{0}']), + ('\u{10c1}', ['\u{2d21}', '\u{0}', '\u{0}']), ('\u{10c2}', ['\u{2d22}', '\u{0}', '\u{0}']), + ('\u{10c3}', ['\u{2d23}', '\u{0}', '\u{0}']), ('\u{10c4}', ['\u{2d24}', '\u{0}', '\u{0}']), + ('\u{10c5}', ['\u{2d25}', '\u{0}', '\u{0}']), ('\u{10c7}', ['\u{2d27}', '\u{0}', '\u{0}']), + ('\u{10cd}', ['\u{2d2d}', '\u{0}', '\u{0}']), ('\u{13a0}', ['\u{ab70}', '\u{0}', '\u{0}']), + ('\u{13a1}', ['\u{ab71}', '\u{0}', '\u{0}']), ('\u{13a2}', ['\u{ab72}', '\u{0}', '\u{0}']), + ('\u{13a3}', ['\u{ab73}', '\u{0}', '\u{0}']), ('\u{13a4}', ['\u{ab74}', '\u{0}', '\u{0}']), + ('\u{13a5}', ['\u{ab75}', '\u{0}', '\u{0}']), ('\u{13a6}', ['\u{ab76}', '\u{0}', '\u{0}']), + ('\u{13a7}', ['\u{ab77}', '\u{0}', '\u{0}']), ('\u{13a8}', ['\u{ab78}', '\u{0}', '\u{0}']), + ('\u{13a9}', ['\u{ab79}', '\u{0}', '\u{0}']), ('\u{13aa}', ['\u{ab7a}', '\u{0}', '\u{0}']), + ('\u{13ab}', ['\u{ab7b}', '\u{0}', '\u{0}']), ('\u{13ac}', ['\u{ab7c}', '\u{0}', '\u{0}']), + ('\u{13ad}', ['\u{ab7d}', '\u{0}', '\u{0}']), ('\u{13ae}', ['\u{ab7e}', '\u{0}', '\u{0}']), + ('\u{13af}', ['\u{ab7f}', '\u{0}', '\u{0}']), ('\u{13b0}', ['\u{ab80}', '\u{0}', '\u{0}']), + ('\u{13b1}', ['\u{ab81}', '\u{0}', '\u{0}']), ('\u{13b2}', ['\u{ab82}', '\u{0}', '\u{0}']), + ('\u{13b3}', ['\u{ab83}', '\u{0}', '\u{0}']), ('\u{13b4}', ['\u{ab84}', '\u{0}', '\u{0}']), + ('\u{13b5}', ['\u{ab85}', '\u{0}', '\u{0}']), ('\u{13b6}', ['\u{ab86}', '\u{0}', '\u{0}']), + ('\u{13b7}', ['\u{ab87}', '\u{0}', '\u{0}']), ('\u{13b8}', ['\u{ab88}', '\u{0}', '\u{0}']), + ('\u{13b9}', ['\u{ab89}', '\u{0}', '\u{0}']), ('\u{13ba}', ['\u{ab8a}', '\u{0}', '\u{0}']), + ('\u{13bb}', ['\u{ab8b}', '\u{0}', '\u{0}']), ('\u{13bc}', ['\u{ab8c}', '\u{0}', '\u{0}']), + ('\u{13bd}', ['\u{ab8d}', '\u{0}', '\u{0}']), ('\u{13be}', ['\u{ab8e}', '\u{0}', '\u{0}']), + ('\u{13bf}', ['\u{ab8f}', '\u{0}', '\u{0}']), ('\u{13c0}', ['\u{ab90}', '\u{0}', '\u{0}']), + ('\u{13c1}', ['\u{ab91}', '\u{0}', '\u{0}']), ('\u{13c2}', ['\u{ab92}', '\u{0}', '\u{0}']), + ('\u{13c3}', ['\u{ab93}', '\u{0}', '\u{0}']), ('\u{13c4}', ['\u{ab94}', '\u{0}', '\u{0}']), + ('\u{13c5}', ['\u{ab95}', '\u{0}', '\u{0}']), ('\u{13c6}', ['\u{ab96}', '\u{0}', '\u{0}']), + ('\u{13c7}', ['\u{ab97}', '\u{0}', '\u{0}']), ('\u{13c8}', ['\u{ab98}', '\u{0}', '\u{0}']), + ('\u{13c9}', ['\u{ab99}', '\u{0}', '\u{0}']), ('\u{13ca}', ['\u{ab9a}', '\u{0}', '\u{0}']), + ('\u{13cb}', ['\u{ab9b}', '\u{0}', '\u{0}']), ('\u{13cc}', ['\u{ab9c}', '\u{0}', '\u{0}']), + ('\u{13cd}', ['\u{ab9d}', '\u{0}', '\u{0}']), ('\u{13ce}', ['\u{ab9e}', '\u{0}', '\u{0}']), + ('\u{13cf}', ['\u{ab9f}', '\u{0}', '\u{0}']), ('\u{13d0}', ['\u{aba0}', '\u{0}', '\u{0}']), + ('\u{13d1}', ['\u{aba1}', '\u{0}', '\u{0}']), ('\u{13d2}', ['\u{aba2}', '\u{0}', '\u{0}']), + ('\u{13d3}', ['\u{aba3}', '\u{0}', '\u{0}']), ('\u{13d4}', ['\u{aba4}', '\u{0}', '\u{0}']), + ('\u{13d5}', ['\u{aba5}', '\u{0}', '\u{0}']), ('\u{13d6}', ['\u{aba6}', '\u{0}', '\u{0}']), + ('\u{13d7}', ['\u{aba7}', '\u{0}', '\u{0}']), ('\u{13d8}', ['\u{aba8}', '\u{0}', '\u{0}']), + ('\u{13d9}', ['\u{aba9}', '\u{0}', '\u{0}']), ('\u{13da}', ['\u{abaa}', '\u{0}', '\u{0}']), + ('\u{13db}', ['\u{abab}', '\u{0}', '\u{0}']), ('\u{13dc}', ['\u{abac}', '\u{0}', '\u{0}']), + ('\u{13dd}', ['\u{abad}', '\u{0}', '\u{0}']), ('\u{13de}', ['\u{abae}', '\u{0}', '\u{0}']), + ('\u{13df}', ['\u{abaf}', '\u{0}', '\u{0}']), ('\u{13e0}', ['\u{abb0}', '\u{0}', '\u{0}']), + ('\u{13e1}', ['\u{abb1}', '\u{0}', '\u{0}']), ('\u{13e2}', ['\u{abb2}', '\u{0}', '\u{0}']), + ('\u{13e3}', ['\u{abb3}', '\u{0}', '\u{0}']), ('\u{13e4}', ['\u{abb4}', '\u{0}', '\u{0}']), + ('\u{13e5}', ['\u{abb5}', '\u{0}', '\u{0}']), ('\u{13e6}', ['\u{abb6}', '\u{0}', '\u{0}']), + ('\u{13e7}', ['\u{abb7}', '\u{0}', '\u{0}']), ('\u{13e8}', ['\u{abb8}', '\u{0}', '\u{0}']), + ('\u{13e9}', ['\u{abb9}', '\u{0}', '\u{0}']), ('\u{13ea}', ['\u{abba}', '\u{0}', '\u{0}']), + ('\u{13eb}', ['\u{abbb}', '\u{0}', '\u{0}']), ('\u{13ec}', ['\u{abbc}', '\u{0}', '\u{0}']), + ('\u{13ed}', ['\u{abbd}', '\u{0}', '\u{0}']), ('\u{13ee}', ['\u{abbe}', '\u{0}', '\u{0}']), + ('\u{13ef}', ['\u{abbf}', '\u{0}', '\u{0}']), ('\u{13f0}', ['\u{13f8}', '\u{0}', '\u{0}']), + ('\u{13f1}', ['\u{13f9}', '\u{0}', '\u{0}']), ('\u{13f2}', ['\u{13fa}', '\u{0}', '\u{0}']), + ('\u{13f3}', ['\u{13fb}', '\u{0}', '\u{0}']), ('\u{13f4}', ['\u{13fc}', '\u{0}', '\u{0}']), + ('\u{13f5}', ['\u{13fd}', '\u{0}', '\u{0}']), ('\u{1c90}', ['\u{10d0}', '\u{0}', '\u{0}']), + ('\u{1c91}', ['\u{10d1}', '\u{0}', '\u{0}']), ('\u{1c92}', ['\u{10d2}', '\u{0}', '\u{0}']), + ('\u{1c93}', ['\u{10d3}', '\u{0}', '\u{0}']), ('\u{1c94}', ['\u{10d4}', '\u{0}', '\u{0}']), + ('\u{1c95}', ['\u{10d5}', '\u{0}', '\u{0}']), ('\u{1c96}', ['\u{10d6}', '\u{0}', '\u{0}']), + ('\u{1c97}', ['\u{10d7}', '\u{0}', '\u{0}']), ('\u{1c98}', ['\u{10d8}', '\u{0}', '\u{0}']), + ('\u{1c99}', ['\u{10d9}', '\u{0}', '\u{0}']), ('\u{1c9a}', ['\u{10da}', '\u{0}', '\u{0}']), + ('\u{1c9b}', ['\u{10db}', '\u{0}', '\u{0}']), ('\u{1c9c}', ['\u{10dc}', '\u{0}', '\u{0}']), + ('\u{1c9d}', ['\u{10dd}', '\u{0}', '\u{0}']), ('\u{1c9e}', ['\u{10de}', '\u{0}', '\u{0}']), + ('\u{1c9f}', ['\u{10df}', '\u{0}', '\u{0}']), ('\u{1ca0}', ['\u{10e0}', '\u{0}', '\u{0}']), + ('\u{1ca1}', ['\u{10e1}', '\u{0}', '\u{0}']), ('\u{1ca2}', ['\u{10e2}', '\u{0}', '\u{0}']), + ('\u{1ca3}', ['\u{10e3}', '\u{0}', '\u{0}']), ('\u{1ca4}', ['\u{10e4}', '\u{0}', '\u{0}']), + ('\u{1ca5}', ['\u{10e5}', '\u{0}', '\u{0}']), ('\u{1ca6}', ['\u{10e6}', '\u{0}', '\u{0}']), + ('\u{1ca7}', ['\u{10e7}', '\u{0}', '\u{0}']), ('\u{1ca8}', ['\u{10e8}', '\u{0}', '\u{0}']), + ('\u{1ca9}', ['\u{10e9}', '\u{0}', '\u{0}']), ('\u{1caa}', ['\u{10ea}', '\u{0}', '\u{0}']), + ('\u{1cab}', ['\u{10eb}', '\u{0}', '\u{0}']), ('\u{1cac}', ['\u{10ec}', '\u{0}', '\u{0}']), + ('\u{1cad}', ['\u{10ed}', '\u{0}', '\u{0}']), ('\u{1cae}', ['\u{10ee}', '\u{0}', '\u{0}']), + ('\u{1caf}', ['\u{10ef}', '\u{0}', '\u{0}']), ('\u{1cb0}', ['\u{10f0}', '\u{0}', '\u{0}']), + ('\u{1cb1}', ['\u{10f1}', '\u{0}', '\u{0}']), ('\u{1cb2}', ['\u{10f2}', '\u{0}', '\u{0}']), + ('\u{1cb3}', ['\u{10f3}', '\u{0}', '\u{0}']), ('\u{1cb4}', ['\u{10f4}', '\u{0}', '\u{0}']), + ('\u{1cb5}', ['\u{10f5}', '\u{0}', '\u{0}']), ('\u{1cb6}', ['\u{10f6}', '\u{0}', '\u{0}']), + ('\u{1cb7}', ['\u{10f7}', '\u{0}', '\u{0}']), ('\u{1cb8}', ['\u{10f8}', '\u{0}', '\u{0}']), + ('\u{1cb9}', ['\u{10f9}', '\u{0}', '\u{0}']), ('\u{1cba}', ['\u{10fa}', '\u{0}', '\u{0}']), + ('\u{1cbd}', ['\u{10fd}', '\u{0}', '\u{0}']), ('\u{1cbe}', ['\u{10fe}', '\u{0}', '\u{0}']), + ('\u{1cbf}', ['\u{10ff}', '\u{0}', '\u{0}']), ('\u{1e00}', ['\u{1e01}', '\u{0}', '\u{0}']), + ('\u{1e02}', ['\u{1e03}', '\u{0}', '\u{0}']), ('\u{1e04}', ['\u{1e05}', '\u{0}', '\u{0}']), + ('\u{1e06}', ['\u{1e07}', '\u{0}', '\u{0}']), ('\u{1e08}', ['\u{1e09}', '\u{0}', '\u{0}']), + ('\u{1e0a}', ['\u{1e0b}', '\u{0}', '\u{0}']), ('\u{1e0c}', ['\u{1e0d}', '\u{0}', '\u{0}']), + ('\u{1e0e}', ['\u{1e0f}', '\u{0}', '\u{0}']), ('\u{1e10}', ['\u{1e11}', '\u{0}', '\u{0}']), + ('\u{1e12}', ['\u{1e13}', '\u{0}', '\u{0}']), ('\u{1e14}', ['\u{1e15}', '\u{0}', '\u{0}']), + ('\u{1e16}', ['\u{1e17}', '\u{0}', '\u{0}']), ('\u{1e18}', ['\u{1e19}', '\u{0}', '\u{0}']), + ('\u{1e1a}', ['\u{1e1b}', '\u{0}', '\u{0}']), ('\u{1e1c}', ['\u{1e1d}', '\u{0}', '\u{0}']), + ('\u{1e1e}', ['\u{1e1f}', '\u{0}', '\u{0}']), ('\u{1e20}', ['\u{1e21}', '\u{0}', '\u{0}']), + ('\u{1e22}', ['\u{1e23}', '\u{0}', '\u{0}']), ('\u{1e24}', ['\u{1e25}', '\u{0}', '\u{0}']), + ('\u{1e26}', ['\u{1e27}', '\u{0}', '\u{0}']), ('\u{1e28}', ['\u{1e29}', '\u{0}', '\u{0}']), + ('\u{1e2a}', ['\u{1e2b}', '\u{0}', '\u{0}']), ('\u{1e2c}', ['\u{1e2d}', '\u{0}', '\u{0}']), + ('\u{1e2e}', ['\u{1e2f}', '\u{0}', '\u{0}']), ('\u{1e30}', ['\u{1e31}', '\u{0}', '\u{0}']), + ('\u{1e32}', ['\u{1e33}', '\u{0}', '\u{0}']), ('\u{1e34}', ['\u{1e35}', '\u{0}', '\u{0}']), + ('\u{1e36}', ['\u{1e37}', '\u{0}', '\u{0}']), ('\u{1e38}', ['\u{1e39}', '\u{0}', '\u{0}']), + ('\u{1e3a}', ['\u{1e3b}', '\u{0}', '\u{0}']), ('\u{1e3c}', ['\u{1e3d}', '\u{0}', '\u{0}']), + ('\u{1e3e}', ['\u{1e3f}', '\u{0}', '\u{0}']), ('\u{1e40}', ['\u{1e41}', '\u{0}', '\u{0}']), + ('\u{1e42}', ['\u{1e43}', '\u{0}', '\u{0}']), ('\u{1e44}', ['\u{1e45}', '\u{0}', '\u{0}']), + ('\u{1e46}', ['\u{1e47}', '\u{0}', '\u{0}']), ('\u{1e48}', ['\u{1e49}', '\u{0}', '\u{0}']), + ('\u{1e4a}', ['\u{1e4b}', '\u{0}', '\u{0}']), ('\u{1e4c}', ['\u{1e4d}', '\u{0}', '\u{0}']), + ('\u{1e4e}', ['\u{1e4f}', '\u{0}', '\u{0}']), ('\u{1e50}', ['\u{1e51}', '\u{0}', '\u{0}']), + ('\u{1e52}', ['\u{1e53}', '\u{0}', '\u{0}']), ('\u{1e54}', ['\u{1e55}', '\u{0}', '\u{0}']), + ('\u{1e56}', ['\u{1e57}', '\u{0}', '\u{0}']), ('\u{1e58}', ['\u{1e59}', '\u{0}', '\u{0}']), + ('\u{1e5a}', ['\u{1e5b}', '\u{0}', '\u{0}']), ('\u{1e5c}', ['\u{1e5d}', '\u{0}', '\u{0}']), + ('\u{1e5e}', ['\u{1e5f}', '\u{0}', '\u{0}']), ('\u{1e60}', ['\u{1e61}', '\u{0}', '\u{0}']), + ('\u{1e62}', ['\u{1e63}', '\u{0}', '\u{0}']), ('\u{1e64}', ['\u{1e65}', '\u{0}', '\u{0}']), + ('\u{1e66}', ['\u{1e67}', '\u{0}', '\u{0}']), ('\u{1e68}', ['\u{1e69}', '\u{0}', '\u{0}']), + ('\u{1e6a}', ['\u{1e6b}', '\u{0}', '\u{0}']), ('\u{1e6c}', ['\u{1e6d}', '\u{0}', '\u{0}']), + ('\u{1e6e}', ['\u{1e6f}', '\u{0}', '\u{0}']), ('\u{1e70}', ['\u{1e71}', '\u{0}', '\u{0}']), + ('\u{1e72}', ['\u{1e73}', '\u{0}', '\u{0}']), ('\u{1e74}', ['\u{1e75}', '\u{0}', '\u{0}']), + ('\u{1e76}', ['\u{1e77}', '\u{0}', '\u{0}']), ('\u{1e78}', ['\u{1e79}', '\u{0}', '\u{0}']), + ('\u{1e7a}', ['\u{1e7b}', '\u{0}', '\u{0}']), ('\u{1e7c}', ['\u{1e7d}', '\u{0}', '\u{0}']), + ('\u{1e7e}', ['\u{1e7f}', '\u{0}', '\u{0}']), ('\u{1e80}', ['\u{1e81}', '\u{0}', '\u{0}']), + ('\u{1e82}', ['\u{1e83}', '\u{0}', '\u{0}']), ('\u{1e84}', ['\u{1e85}', '\u{0}', '\u{0}']), + ('\u{1e86}', ['\u{1e87}', '\u{0}', '\u{0}']), ('\u{1e88}', ['\u{1e89}', '\u{0}', '\u{0}']), + ('\u{1e8a}', ['\u{1e8b}', '\u{0}', '\u{0}']), ('\u{1e8c}', ['\u{1e8d}', '\u{0}', '\u{0}']), + ('\u{1e8e}', ['\u{1e8f}', '\u{0}', '\u{0}']), ('\u{1e90}', ['\u{1e91}', '\u{0}', '\u{0}']), + ('\u{1e92}', ['\u{1e93}', '\u{0}', '\u{0}']), ('\u{1e94}', ['\u{1e95}', '\u{0}', '\u{0}']), + ('\u{1e9e}', ['\u{df}', '\u{0}', '\u{0}']), ('\u{1ea0}', ['\u{1ea1}', '\u{0}', '\u{0}']), + ('\u{1ea2}', ['\u{1ea3}', '\u{0}', '\u{0}']), ('\u{1ea4}', ['\u{1ea5}', '\u{0}', '\u{0}']), + ('\u{1ea6}', ['\u{1ea7}', '\u{0}', '\u{0}']), ('\u{1ea8}', ['\u{1ea9}', '\u{0}', '\u{0}']), + ('\u{1eaa}', ['\u{1eab}', '\u{0}', '\u{0}']), ('\u{1eac}', ['\u{1ead}', '\u{0}', '\u{0}']), + ('\u{1eae}', ['\u{1eaf}', '\u{0}', '\u{0}']), ('\u{1eb0}', ['\u{1eb1}', '\u{0}', '\u{0}']), + ('\u{1eb2}', ['\u{1eb3}', '\u{0}', '\u{0}']), ('\u{1eb4}', ['\u{1eb5}', '\u{0}', '\u{0}']), + ('\u{1eb6}', ['\u{1eb7}', '\u{0}', '\u{0}']), ('\u{1eb8}', ['\u{1eb9}', '\u{0}', '\u{0}']), + ('\u{1eba}', ['\u{1ebb}', '\u{0}', '\u{0}']), ('\u{1ebc}', ['\u{1ebd}', '\u{0}', '\u{0}']), + ('\u{1ebe}', ['\u{1ebf}', '\u{0}', '\u{0}']), ('\u{1ec0}', ['\u{1ec1}', '\u{0}', '\u{0}']), + ('\u{1ec2}', ['\u{1ec3}', '\u{0}', '\u{0}']), ('\u{1ec4}', ['\u{1ec5}', '\u{0}', '\u{0}']), + ('\u{1ec6}', ['\u{1ec7}', '\u{0}', '\u{0}']), ('\u{1ec8}', ['\u{1ec9}', '\u{0}', '\u{0}']), + ('\u{1eca}', ['\u{1ecb}', '\u{0}', '\u{0}']), ('\u{1ecc}', ['\u{1ecd}', '\u{0}', '\u{0}']), + ('\u{1ece}', ['\u{1ecf}', '\u{0}', '\u{0}']), ('\u{1ed0}', ['\u{1ed1}', '\u{0}', '\u{0}']), + ('\u{1ed2}', ['\u{1ed3}', '\u{0}', '\u{0}']), ('\u{1ed4}', ['\u{1ed5}', '\u{0}', '\u{0}']), + ('\u{1ed6}', ['\u{1ed7}', '\u{0}', '\u{0}']), ('\u{1ed8}', ['\u{1ed9}', '\u{0}', '\u{0}']), + ('\u{1eda}', ['\u{1edb}', '\u{0}', '\u{0}']), ('\u{1edc}', ['\u{1edd}', '\u{0}', '\u{0}']), + ('\u{1ede}', ['\u{1edf}', '\u{0}', '\u{0}']), ('\u{1ee0}', ['\u{1ee1}', '\u{0}', '\u{0}']), + ('\u{1ee2}', ['\u{1ee3}', '\u{0}', '\u{0}']), ('\u{1ee4}', ['\u{1ee5}', '\u{0}', '\u{0}']), + ('\u{1ee6}', ['\u{1ee7}', '\u{0}', '\u{0}']), ('\u{1ee8}', ['\u{1ee9}', '\u{0}', '\u{0}']), + ('\u{1eea}', ['\u{1eeb}', '\u{0}', '\u{0}']), ('\u{1eec}', ['\u{1eed}', '\u{0}', '\u{0}']), + ('\u{1eee}', ['\u{1eef}', '\u{0}', '\u{0}']), ('\u{1ef0}', ['\u{1ef1}', '\u{0}', '\u{0}']), + ('\u{1ef2}', ['\u{1ef3}', '\u{0}', '\u{0}']), ('\u{1ef4}', ['\u{1ef5}', '\u{0}', '\u{0}']), + ('\u{1ef6}', ['\u{1ef7}', '\u{0}', '\u{0}']), ('\u{1ef8}', ['\u{1ef9}', '\u{0}', '\u{0}']), + ('\u{1efa}', ['\u{1efb}', '\u{0}', '\u{0}']), ('\u{1efc}', ['\u{1efd}', '\u{0}', '\u{0}']), + ('\u{1efe}', ['\u{1eff}', '\u{0}', '\u{0}']), ('\u{1f08}', ['\u{1f00}', '\u{0}', '\u{0}']), + ('\u{1f09}', ['\u{1f01}', '\u{0}', '\u{0}']), ('\u{1f0a}', ['\u{1f02}', '\u{0}', '\u{0}']), + ('\u{1f0b}', ['\u{1f03}', '\u{0}', '\u{0}']), ('\u{1f0c}', ['\u{1f04}', '\u{0}', '\u{0}']), + ('\u{1f0d}', ['\u{1f05}', '\u{0}', '\u{0}']), ('\u{1f0e}', ['\u{1f06}', '\u{0}', '\u{0}']), + ('\u{1f0f}', ['\u{1f07}', '\u{0}', '\u{0}']), ('\u{1f18}', ['\u{1f10}', '\u{0}', '\u{0}']), + ('\u{1f19}', ['\u{1f11}', '\u{0}', '\u{0}']), ('\u{1f1a}', ['\u{1f12}', '\u{0}', '\u{0}']), + ('\u{1f1b}', ['\u{1f13}', '\u{0}', '\u{0}']), ('\u{1f1c}', ['\u{1f14}', '\u{0}', '\u{0}']), + ('\u{1f1d}', ['\u{1f15}', '\u{0}', '\u{0}']), ('\u{1f28}', ['\u{1f20}', '\u{0}', '\u{0}']), + ('\u{1f29}', ['\u{1f21}', '\u{0}', '\u{0}']), ('\u{1f2a}', ['\u{1f22}', '\u{0}', '\u{0}']), + ('\u{1f2b}', ['\u{1f23}', '\u{0}', '\u{0}']), ('\u{1f2c}', ['\u{1f24}', '\u{0}', '\u{0}']), + ('\u{1f2d}', ['\u{1f25}', '\u{0}', '\u{0}']), ('\u{1f2e}', ['\u{1f26}', '\u{0}', '\u{0}']), + ('\u{1f2f}', ['\u{1f27}', '\u{0}', '\u{0}']), ('\u{1f38}', ['\u{1f30}', '\u{0}', '\u{0}']), + ('\u{1f39}', ['\u{1f31}', '\u{0}', '\u{0}']), ('\u{1f3a}', ['\u{1f32}', '\u{0}', '\u{0}']), + ('\u{1f3b}', ['\u{1f33}', '\u{0}', '\u{0}']), ('\u{1f3c}', ['\u{1f34}', '\u{0}', '\u{0}']), + ('\u{1f3d}', ['\u{1f35}', '\u{0}', '\u{0}']), ('\u{1f3e}', ['\u{1f36}', '\u{0}', '\u{0}']), + ('\u{1f3f}', ['\u{1f37}', '\u{0}', '\u{0}']), ('\u{1f48}', ['\u{1f40}', '\u{0}', '\u{0}']), + ('\u{1f49}', ['\u{1f41}', '\u{0}', '\u{0}']), ('\u{1f4a}', ['\u{1f42}', '\u{0}', '\u{0}']), + ('\u{1f4b}', ['\u{1f43}', '\u{0}', '\u{0}']), ('\u{1f4c}', ['\u{1f44}', '\u{0}', '\u{0}']), + ('\u{1f4d}', ['\u{1f45}', '\u{0}', '\u{0}']), ('\u{1f59}', ['\u{1f51}', '\u{0}', '\u{0}']), + ('\u{1f5b}', ['\u{1f53}', '\u{0}', '\u{0}']), ('\u{1f5d}', ['\u{1f55}', '\u{0}', '\u{0}']), + ('\u{1f5f}', ['\u{1f57}', '\u{0}', '\u{0}']), ('\u{1f68}', ['\u{1f60}', '\u{0}', '\u{0}']), + ('\u{1f69}', ['\u{1f61}', '\u{0}', '\u{0}']), ('\u{1f6a}', ['\u{1f62}', '\u{0}', '\u{0}']), + ('\u{1f6b}', ['\u{1f63}', '\u{0}', '\u{0}']), ('\u{1f6c}', ['\u{1f64}', '\u{0}', '\u{0}']), + ('\u{1f6d}', ['\u{1f65}', '\u{0}', '\u{0}']), ('\u{1f6e}', ['\u{1f66}', '\u{0}', '\u{0}']), + ('\u{1f6f}', ['\u{1f67}', '\u{0}', '\u{0}']), ('\u{1f88}', ['\u{1f80}', '\u{0}', '\u{0}']), + ('\u{1f89}', ['\u{1f81}', '\u{0}', '\u{0}']), ('\u{1f8a}', ['\u{1f82}', '\u{0}', '\u{0}']), + ('\u{1f8b}', ['\u{1f83}', '\u{0}', '\u{0}']), ('\u{1f8c}', ['\u{1f84}', '\u{0}', '\u{0}']), + ('\u{1f8d}', ['\u{1f85}', '\u{0}', '\u{0}']), ('\u{1f8e}', ['\u{1f86}', '\u{0}', '\u{0}']), + ('\u{1f8f}', ['\u{1f87}', '\u{0}', '\u{0}']), ('\u{1f98}', ['\u{1f90}', '\u{0}', '\u{0}']), + ('\u{1f99}', ['\u{1f91}', '\u{0}', '\u{0}']), ('\u{1f9a}', ['\u{1f92}', '\u{0}', '\u{0}']), + ('\u{1f9b}', ['\u{1f93}', '\u{0}', '\u{0}']), ('\u{1f9c}', ['\u{1f94}', '\u{0}', '\u{0}']), + ('\u{1f9d}', ['\u{1f95}', '\u{0}', '\u{0}']), ('\u{1f9e}', ['\u{1f96}', '\u{0}', '\u{0}']), + ('\u{1f9f}', ['\u{1f97}', '\u{0}', '\u{0}']), ('\u{1fa8}', ['\u{1fa0}', '\u{0}', '\u{0}']), + ('\u{1fa9}', ['\u{1fa1}', '\u{0}', '\u{0}']), ('\u{1faa}', ['\u{1fa2}', '\u{0}', '\u{0}']), + ('\u{1fab}', ['\u{1fa3}', '\u{0}', '\u{0}']), ('\u{1fac}', ['\u{1fa4}', '\u{0}', '\u{0}']), + ('\u{1fad}', ['\u{1fa5}', '\u{0}', '\u{0}']), ('\u{1fae}', ['\u{1fa6}', '\u{0}', '\u{0}']), + ('\u{1faf}', ['\u{1fa7}', '\u{0}', '\u{0}']), ('\u{1fb8}', ['\u{1fb0}', '\u{0}', '\u{0}']), + ('\u{1fb9}', ['\u{1fb1}', '\u{0}', '\u{0}']), ('\u{1fba}', ['\u{1f70}', '\u{0}', '\u{0}']), + ('\u{1fbb}', ['\u{1f71}', '\u{0}', '\u{0}']), ('\u{1fbc}', ['\u{1fb3}', '\u{0}', '\u{0}']), + ('\u{1fc8}', ['\u{1f72}', '\u{0}', '\u{0}']), ('\u{1fc9}', ['\u{1f73}', '\u{0}', '\u{0}']), + ('\u{1fca}', ['\u{1f74}', '\u{0}', '\u{0}']), ('\u{1fcb}', ['\u{1f75}', '\u{0}', '\u{0}']), + ('\u{1fcc}', ['\u{1fc3}', '\u{0}', '\u{0}']), ('\u{1fd8}', ['\u{1fd0}', '\u{0}', '\u{0}']), + ('\u{1fd9}', ['\u{1fd1}', '\u{0}', '\u{0}']), ('\u{1fda}', ['\u{1f76}', '\u{0}', '\u{0}']), + ('\u{1fdb}', ['\u{1f77}', '\u{0}', '\u{0}']), ('\u{1fe8}', ['\u{1fe0}', '\u{0}', '\u{0}']), + ('\u{1fe9}', ['\u{1fe1}', '\u{0}', '\u{0}']), ('\u{1fea}', ['\u{1f7a}', '\u{0}', '\u{0}']), + ('\u{1feb}', ['\u{1f7b}', '\u{0}', '\u{0}']), ('\u{1fec}', ['\u{1fe5}', '\u{0}', '\u{0}']), + ('\u{1ff8}', ['\u{1f78}', '\u{0}', '\u{0}']), ('\u{1ff9}', ['\u{1f79}', '\u{0}', '\u{0}']), + ('\u{1ffa}', ['\u{1f7c}', '\u{0}', '\u{0}']), ('\u{1ffb}', ['\u{1f7d}', '\u{0}', '\u{0}']), + ('\u{1ffc}', ['\u{1ff3}', '\u{0}', '\u{0}']), ('\u{2126}', ['\u{3c9}', '\u{0}', '\u{0}']), + ('\u{212a}', ['k', '\u{0}', '\u{0}']), ('\u{212b}', ['\u{e5}', '\u{0}', '\u{0}']), + ('\u{2132}', ['\u{214e}', '\u{0}', '\u{0}']), ('\u{2160}', ['\u{2170}', '\u{0}', '\u{0}']), + ('\u{2161}', ['\u{2171}', '\u{0}', '\u{0}']), ('\u{2162}', ['\u{2172}', '\u{0}', '\u{0}']), + ('\u{2163}', ['\u{2173}', '\u{0}', '\u{0}']), ('\u{2164}', ['\u{2174}', '\u{0}', '\u{0}']), + ('\u{2165}', ['\u{2175}', '\u{0}', '\u{0}']), ('\u{2166}', ['\u{2176}', '\u{0}', '\u{0}']), + ('\u{2167}', ['\u{2177}', '\u{0}', '\u{0}']), ('\u{2168}', ['\u{2178}', '\u{0}', '\u{0}']), + ('\u{2169}', ['\u{2179}', '\u{0}', '\u{0}']), ('\u{216a}', ['\u{217a}', '\u{0}', '\u{0}']), + ('\u{216b}', ['\u{217b}', '\u{0}', '\u{0}']), ('\u{216c}', ['\u{217c}', '\u{0}', '\u{0}']), + ('\u{216d}', ['\u{217d}', '\u{0}', '\u{0}']), ('\u{216e}', ['\u{217e}', '\u{0}', '\u{0}']), + ('\u{216f}', ['\u{217f}', '\u{0}', '\u{0}']), ('\u{2183}', ['\u{2184}', '\u{0}', '\u{0}']), + ('\u{24b6}', ['\u{24d0}', '\u{0}', '\u{0}']), ('\u{24b7}', ['\u{24d1}', '\u{0}', '\u{0}']), + ('\u{24b8}', ['\u{24d2}', '\u{0}', '\u{0}']), ('\u{24b9}', ['\u{24d3}', '\u{0}', '\u{0}']), + ('\u{24ba}', ['\u{24d4}', '\u{0}', '\u{0}']), ('\u{24bb}', ['\u{24d5}', '\u{0}', '\u{0}']), + ('\u{24bc}', ['\u{24d6}', '\u{0}', '\u{0}']), ('\u{24bd}', ['\u{24d7}', '\u{0}', '\u{0}']), + ('\u{24be}', ['\u{24d8}', '\u{0}', '\u{0}']), ('\u{24bf}', ['\u{24d9}', '\u{0}', '\u{0}']), + ('\u{24c0}', ['\u{24da}', '\u{0}', '\u{0}']), ('\u{24c1}', ['\u{24db}', '\u{0}', '\u{0}']), + ('\u{24c2}', ['\u{24dc}', '\u{0}', '\u{0}']), ('\u{24c3}', ['\u{24dd}', '\u{0}', '\u{0}']), + ('\u{24c4}', ['\u{24de}', '\u{0}', '\u{0}']), ('\u{24c5}', ['\u{24df}', '\u{0}', '\u{0}']), + ('\u{24c6}', ['\u{24e0}', '\u{0}', '\u{0}']), ('\u{24c7}', ['\u{24e1}', '\u{0}', '\u{0}']), + ('\u{24c8}', ['\u{24e2}', '\u{0}', '\u{0}']), ('\u{24c9}', ['\u{24e3}', '\u{0}', '\u{0}']), + ('\u{24ca}', ['\u{24e4}', '\u{0}', '\u{0}']), ('\u{24cb}', ['\u{24e5}', '\u{0}', '\u{0}']), + ('\u{24cc}', ['\u{24e6}', '\u{0}', '\u{0}']), ('\u{24cd}', ['\u{24e7}', '\u{0}', '\u{0}']), + ('\u{24ce}', ['\u{24e8}', '\u{0}', '\u{0}']), ('\u{24cf}', ['\u{24e9}', '\u{0}', '\u{0}']), + ('\u{2c00}', ['\u{2c30}', '\u{0}', '\u{0}']), ('\u{2c01}', ['\u{2c31}', '\u{0}', '\u{0}']), + ('\u{2c02}', ['\u{2c32}', '\u{0}', '\u{0}']), ('\u{2c03}', ['\u{2c33}', '\u{0}', '\u{0}']), + ('\u{2c04}', ['\u{2c34}', '\u{0}', '\u{0}']), ('\u{2c05}', ['\u{2c35}', '\u{0}', '\u{0}']), + ('\u{2c06}', ['\u{2c36}', '\u{0}', '\u{0}']), ('\u{2c07}', ['\u{2c37}', '\u{0}', '\u{0}']), + ('\u{2c08}', ['\u{2c38}', '\u{0}', '\u{0}']), ('\u{2c09}', ['\u{2c39}', '\u{0}', '\u{0}']), + ('\u{2c0a}', ['\u{2c3a}', '\u{0}', '\u{0}']), ('\u{2c0b}', ['\u{2c3b}', '\u{0}', '\u{0}']), + ('\u{2c0c}', ['\u{2c3c}', '\u{0}', '\u{0}']), ('\u{2c0d}', ['\u{2c3d}', '\u{0}', '\u{0}']), + ('\u{2c0e}', ['\u{2c3e}', '\u{0}', '\u{0}']), ('\u{2c0f}', ['\u{2c3f}', '\u{0}', '\u{0}']), + ('\u{2c10}', ['\u{2c40}', '\u{0}', '\u{0}']), ('\u{2c11}', ['\u{2c41}', '\u{0}', '\u{0}']), + ('\u{2c12}', ['\u{2c42}', '\u{0}', '\u{0}']), ('\u{2c13}', ['\u{2c43}', '\u{0}', '\u{0}']), + ('\u{2c14}', ['\u{2c44}', '\u{0}', '\u{0}']), ('\u{2c15}', ['\u{2c45}', '\u{0}', '\u{0}']), + ('\u{2c16}', ['\u{2c46}', '\u{0}', '\u{0}']), ('\u{2c17}', ['\u{2c47}', '\u{0}', '\u{0}']), + ('\u{2c18}', ['\u{2c48}', '\u{0}', '\u{0}']), ('\u{2c19}', ['\u{2c49}', '\u{0}', '\u{0}']), + ('\u{2c1a}', ['\u{2c4a}', '\u{0}', '\u{0}']), ('\u{2c1b}', ['\u{2c4b}', '\u{0}', '\u{0}']), + ('\u{2c1c}', ['\u{2c4c}', '\u{0}', '\u{0}']), ('\u{2c1d}', ['\u{2c4d}', '\u{0}', '\u{0}']), + ('\u{2c1e}', ['\u{2c4e}', '\u{0}', '\u{0}']), ('\u{2c1f}', ['\u{2c4f}', '\u{0}', '\u{0}']), + ('\u{2c20}', ['\u{2c50}', '\u{0}', '\u{0}']), ('\u{2c21}', ['\u{2c51}', '\u{0}', '\u{0}']), + ('\u{2c22}', ['\u{2c52}', '\u{0}', '\u{0}']), ('\u{2c23}', ['\u{2c53}', '\u{0}', '\u{0}']), + ('\u{2c24}', ['\u{2c54}', '\u{0}', '\u{0}']), ('\u{2c25}', ['\u{2c55}', '\u{0}', '\u{0}']), + ('\u{2c26}', ['\u{2c56}', '\u{0}', '\u{0}']), ('\u{2c27}', ['\u{2c57}', '\u{0}', '\u{0}']), + ('\u{2c28}', ['\u{2c58}', '\u{0}', '\u{0}']), ('\u{2c29}', ['\u{2c59}', '\u{0}', '\u{0}']), + ('\u{2c2a}', ['\u{2c5a}', '\u{0}', '\u{0}']), ('\u{2c2b}', ['\u{2c5b}', '\u{0}', '\u{0}']), + ('\u{2c2c}', ['\u{2c5c}', '\u{0}', '\u{0}']), ('\u{2c2d}', ['\u{2c5d}', '\u{0}', '\u{0}']), + ('\u{2c2e}', ['\u{2c5e}', '\u{0}', '\u{0}']), ('\u{2c60}', ['\u{2c61}', '\u{0}', '\u{0}']), + ('\u{2c62}', ['\u{26b}', '\u{0}', '\u{0}']), ('\u{2c63}', ['\u{1d7d}', '\u{0}', '\u{0}']), + ('\u{2c64}', ['\u{27d}', '\u{0}', '\u{0}']), ('\u{2c67}', ['\u{2c68}', '\u{0}', '\u{0}']), + ('\u{2c69}', ['\u{2c6a}', '\u{0}', '\u{0}']), ('\u{2c6b}', ['\u{2c6c}', '\u{0}', '\u{0}']), + ('\u{2c6d}', ['\u{251}', '\u{0}', '\u{0}']), ('\u{2c6e}', ['\u{271}', '\u{0}', '\u{0}']), + ('\u{2c6f}', ['\u{250}', '\u{0}', '\u{0}']), ('\u{2c70}', ['\u{252}', '\u{0}', '\u{0}']), + ('\u{2c72}', ['\u{2c73}', '\u{0}', '\u{0}']), ('\u{2c75}', ['\u{2c76}', '\u{0}', '\u{0}']), + ('\u{2c7e}', ['\u{23f}', '\u{0}', '\u{0}']), ('\u{2c7f}', ['\u{240}', '\u{0}', '\u{0}']), + ('\u{2c80}', ['\u{2c81}', '\u{0}', '\u{0}']), ('\u{2c82}', ['\u{2c83}', '\u{0}', '\u{0}']), + ('\u{2c84}', ['\u{2c85}', '\u{0}', '\u{0}']), ('\u{2c86}', ['\u{2c87}', '\u{0}', '\u{0}']), + ('\u{2c88}', ['\u{2c89}', '\u{0}', '\u{0}']), ('\u{2c8a}', ['\u{2c8b}', '\u{0}', '\u{0}']), + ('\u{2c8c}', ['\u{2c8d}', '\u{0}', '\u{0}']), ('\u{2c8e}', ['\u{2c8f}', '\u{0}', '\u{0}']), + ('\u{2c90}', ['\u{2c91}', '\u{0}', '\u{0}']), ('\u{2c92}', ['\u{2c93}', '\u{0}', '\u{0}']), + ('\u{2c94}', ['\u{2c95}', '\u{0}', '\u{0}']), ('\u{2c96}', ['\u{2c97}', '\u{0}', '\u{0}']), + ('\u{2c98}', ['\u{2c99}', '\u{0}', '\u{0}']), ('\u{2c9a}', ['\u{2c9b}', '\u{0}', '\u{0}']), + ('\u{2c9c}', ['\u{2c9d}', '\u{0}', '\u{0}']), ('\u{2c9e}', ['\u{2c9f}', '\u{0}', '\u{0}']), + ('\u{2ca0}', ['\u{2ca1}', '\u{0}', '\u{0}']), ('\u{2ca2}', ['\u{2ca3}', '\u{0}', '\u{0}']), + ('\u{2ca4}', ['\u{2ca5}', '\u{0}', '\u{0}']), ('\u{2ca6}', ['\u{2ca7}', '\u{0}', '\u{0}']), + ('\u{2ca8}', ['\u{2ca9}', '\u{0}', '\u{0}']), ('\u{2caa}', ['\u{2cab}', '\u{0}', '\u{0}']), + ('\u{2cac}', ['\u{2cad}', '\u{0}', '\u{0}']), ('\u{2cae}', ['\u{2caf}', '\u{0}', '\u{0}']), + ('\u{2cb0}', ['\u{2cb1}', '\u{0}', '\u{0}']), ('\u{2cb2}', ['\u{2cb3}', '\u{0}', '\u{0}']), + ('\u{2cb4}', ['\u{2cb5}', '\u{0}', '\u{0}']), ('\u{2cb6}', ['\u{2cb7}', '\u{0}', '\u{0}']), + ('\u{2cb8}', ['\u{2cb9}', '\u{0}', '\u{0}']), ('\u{2cba}', ['\u{2cbb}', '\u{0}', '\u{0}']), + ('\u{2cbc}', ['\u{2cbd}', '\u{0}', '\u{0}']), ('\u{2cbe}', ['\u{2cbf}', '\u{0}', '\u{0}']), + ('\u{2cc0}', ['\u{2cc1}', '\u{0}', '\u{0}']), ('\u{2cc2}', ['\u{2cc3}', '\u{0}', '\u{0}']), + ('\u{2cc4}', ['\u{2cc5}', '\u{0}', '\u{0}']), ('\u{2cc6}', ['\u{2cc7}', '\u{0}', '\u{0}']), + ('\u{2cc8}', ['\u{2cc9}', '\u{0}', '\u{0}']), ('\u{2cca}', ['\u{2ccb}', '\u{0}', '\u{0}']), + ('\u{2ccc}', ['\u{2ccd}', '\u{0}', '\u{0}']), ('\u{2cce}', ['\u{2ccf}', '\u{0}', '\u{0}']), + ('\u{2cd0}', ['\u{2cd1}', '\u{0}', '\u{0}']), ('\u{2cd2}', ['\u{2cd3}', '\u{0}', '\u{0}']), + ('\u{2cd4}', ['\u{2cd5}', '\u{0}', '\u{0}']), ('\u{2cd6}', ['\u{2cd7}', '\u{0}', '\u{0}']), + ('\u{2cd8}', ['\u{2cd9}', '\u{0}', '\u{0}']), ('\u{2cda}', ['\u{2cdb}', '\u{0}', '\u{0}']), + ('\u{2cdc}', ['\u{2cdd}', '\u{0}', '\u{0}']), ('\u{2cde}', ['\u{2cdf}', '\u{0}', '\u{0}']), + ('\u{2ce0}', ['\u{2ce1}', '\u{0}', '\u{0}']), ('\u{2ce2}', ['\u{2ce3}', '\u{0}', '\u{0}']), + ('\u{2ceb}', ['\u{2cec}', '\u{0}', '\u{0}']), ('\u{2ced}', ['\u{2cee}', '\u{0}', '\u{0}']), + ('\u{2cf2}', ['\u{2cf3}', '\u{0}', '\u{0}']), ('\u{a640}', ['\u{a641}', '\u{0}', '\u{0}']), + ('\u{a642}', ['\u{a643}', '\u{0}', '\u{0}']), ('\u{a644}', ['\u{a645}', '\u{0}', '\u{0}']), + ('\u{a646}', ['\u{a647}', '\u{0}', '\u{0}']), ('\u{a648}', ['\u{a649}', '\u{0}', '\u{0}']), + ('\u{a64a}', ['\u{a64b}', '\u{0}', '\u{0}']), ('\u{a64c}', ['\u{a64d}', '\u{0}', '\u{0}']), + ('\u{a64e}', ['\u{a64f}', '\u{0}', '\u{0}']), ('\u{a650}', ['\u{a651}', '\u{0}', '\u{0}']), + ('\u{a652}', ['\u{a653}', '\u{0}', '\u{0}']), ('\u{a654}', ['\u{a655}', '\u{0}', '\u{0}']), + ('\u{a656}', ['\u{a657}', '\u{0}', '\u{0}']), ('\u{a658}', ['\u{a659}', '\u{0}', '\u{0}']), + ('\u{a65a}', ['\u{a65b}', '\u{0}', '\u{0}']), ('\u{a65c}', ['\u{a65d}', '\u{0}', '\u{0}']), + ('\u{a65e}', ['\u{a65f}', '\u{0}', '\u{0}']), ('\u{a660}', ['\u{a661}', '\u{0}', '\u{0}']), + ('\u{a662}', ['\u{a663}', '\u{0}', '\u{0}']), ('\u{a664}', ['\u{a665}', '\u{0}', '\u{0}']), + ('\u{a666}', ['\u{a667}', '\u{0}', '\u{0}']), ('\u{a668}', ['\u{a669}', '\u{0}', '\u{0}']), + ('\u{a66a}', ['\u{a66b}', '\u{0}', '\u{0}']), ('\u{a66c}', ['\u{a66d}', '\u{0}', '\u{0}']), + ('\u{a680}', ['\u{a681}', '\u{0}', '\u{0}']), ('\u{a682}', ['\u{a683}', '\u{0}', '\u{0}']), + ('\u{a684}', ['\u{a685}', '\u{0}', '\u{0}']), ('\u{a686}', ['\u{a687}', '\u{0}', '\u{0}']), + ('\u{a688}', ['\u{a689}', '\u{0}', '\u{0}']), ('\u{a68a}', ['\u{a68b}', '\u{0}', '\u{0}']), + ('\u{a68c}', ['\u{a68d}', '\u{0}', '\u{0}']), ('\u{a68e}', ['\u{a68f}', '\u{0}', '\u{0}']), + ('\u{a690}', ['\u{a691}', '\u{0}', '\u{0}']), ('\u{a692}', ['\u{a693}', '\u{0}', '\u{0}']), + ('\u{a694}', ['\u{a695}', '\u{0}', '\u{0}']), ('\u{a696}', ['\u{a697}', '\u{0}', '\u{0}']), + ('\u{a698}', ['\u{a699}', '\u{0}', '\u{0}']), ('\u{a69a}', ['\u{a69b}', '\u{0}', '\u{0}']), + ('\u{a722}', ['\u{a723}', '\u{0}', '\u{0}']), ('\u{a724}', ['\u{a725}', '\u{0}', '\u{0}']), + ('\u{a726}', ['\u{a727}', '\u{0}', '\u{0}']), ('\u{a728}', ['\u{a729}', '\u{0}', '\u{0}']), + ('\u{a72a}', ['\u{a72b}', '\u{0}', '\u{0}']), ('\u{a72c}', ['\u{a72d}', '\u{0}', '\u{0}']), + ('\u{a72e}', ['\u{a72f}', '\u{0}', '\u{0}']), ('\u{a732}', ['\u{a733}', '\u{0}', '\u{0}']), + ('\u{a734}', ['\u{a735}', '\u{0}', '\u{0}']), ('\u{a736}', ['\u{a737}', '\u{0}', '\u{0}']), + ('\u{a738}', ['\u{a739}', '\u{0}', '\u{0}']), ('\u{a73a}', ['\u{a73b}', '\u{0}', '\u{0}']), + ('\u{a73c}', ['\u{a73d}', '\u{0}', '\u{0}']), ('\u{a73e}', ['\u{a73f}', '\u{0}', '\u{0}']), + ('\u{a740}', ['\u{a741}', '\u{0}', '\u{0}']), ('\u{a742}', ['\u{a743}', '\u{0}', '\u{0}']), + ('\u{a744}', ['\u{a745}', '\u{0}', '\u{0}']), ('\u{a746}', ['\u{a747}', '\u{0}', '\u{0}']), + ('\u{a748}', ['\u{a749}', '\u{0}', '\u{0}']), ('\u{a74a}', ['\u{a74b}', '\u{0}', '\u{0}']), + ('\u{a74c}', ['\u{a74d}', '\u{0}', '\u{0}']), ('\u{a74e}', ['\u{a74f}', '\u{0}', '\u{0}']), + ('\u{a750}', ['\u{a751}', '\u{0}', '\u{0}']), ('\u{a752}', ['\u{a753}', '\u{0}', '\u{0}']), + ('\u{a754}', ['\u{a755}', '\u{0}', '\u{0}']), ('\u{a756}', ['\u{a757}', '\u{0}', '\u{0}']), + ('\u{a758}', ['\u{a759}', '\u{0}', '\u{0}']), ('\u{a75a}', ['\u{a75b}', '\u{0}', '\u{0}']), + ('\u{a75c}', ['\u{a75d}', '\u{0}', '\u{0}']), ('\u{a75e}', ['\u{a75f}', '\u{0}', '\u{0}']), + ('\u{a760}', ['\u{a761}', '\u{0}', '\u{0}']), ('\u{a762}', ['\u{a763}', '\u{0}', '\u{0}']), + ('\u{a764}', ['\u{a765}', '\u{0}', '\u{0}']), ('\u{a766}', ['\u{a767}', '\u{0}', '\u{0}']), + ('\u{a768}', ['\u{a769}', '\u{0}', '\u{0}']), ('\u{a76a}', ['\u{a76b}', '\u{0}', '\u{0}']), + ('\u{a76c}', ['\u{a76d}', '\u{0}', '\u{0}']), ('\u{a76e}', ['\u{a76f}', '\u{0}', '\u{0}']), + ('\u{a779}', ['\u{a77a}', '\u{0}', '\u{0}']), ('\u{a77b}', ['\u{a77c}', '\u{0}', '\u{0}']), + ('\u{a77d}', ['\u{1d79}', '\u{0}', '\u{0}']), ('\u{a77e}', ['\u{a77f}', '\u{0}', '\u{0}']), + ('\u{a780}', ['\u{a781}', '\u{0}', '\u{0}']), ('\u{a782}', ['\u{a783}', '\u{0}', '\u{0}']), + ('\u{a784}', ['\u{a785}', '\u{0}', '\u{0}']), ('\u{a786}', ['\u{a787}', '\u{0}', '\u{0}']), + ('\u{a78b}', ['\u{a78c}', '\u{0}', '\u{0}']), ('\u{a78d}', ['\u{265}', '\u{0}', '\u{0}']), + ('\u{a790}', ['\u{a791}', '\u{0}', '\u{0}']), ('\u{a792}', ['\u{a793}', '\u{0}', '\u{0}']), + ('\u{a796}', ['\u{a797}', '\u{0}', '\u{0}']), ('\u{a798}', ['\u{a799}', '\u{0}', '\u{0}']), + ('\u{a79a}', ['\u{a79b}', '\u{0}', '\u{0}']), ('\u{a79c}', ['\u{a79d}', '\u{0}', '\u{0}']), + ('\u{a79e}', ['\u{a79f}', '\u{0}', '\u{0}']), ('\u{a7a0}', ['\u{a7a1}', '\u{0}', '\u{0}']), + ('\u{a7a2}', ['\u{a7a3}', '\u{0}', '\u{0}']), ('\u{a7a4}', ['\u{a7a5}', '\u{0}', '\u{0}']), + ('\u{a7a6}', ['\u{a7a7}', '\u{0}', '\u{0}']), ('\u{a7a8}', ['\u{a7a9}', '\u{0}', '\u{0}']), + ('\u{a7aa}', ['\u{266}', '\u{0}', '\u{0}']), ('\u{a7ab}', ['\u{25c}', '\u{0}', '\u{0}']), + ('\u{a7ac}', ['\u{261}', '\u{0}', '\u{0}']), ('\u{a7ad}', ['\u{26c}', '\u{0}', '\u{0}']), + ('\u{a7ae}', ['\u{26a}', '\u{0}', '\u{0}']), ('\u{a7b0}', ['\u{29e}', '\u{0}', '\u{0}']), + ('\u{a7b1}', ['\u{287}', '\u{0}', '\u{0}']), ('\u{a7b2}', ['\u{29d}', '\u{0}', '\u{0}']), + ('\u{a7b3}', ['\u{ab53}', '\u{0}', '\u{0}']), ('\u{a7b4}', ['\u{a7b5}', '\u{0}', '\u{0}']), + ('\u{a7b6}', ['\u{a7b7}', '\u{0}', '\u{0}']), ('\u{a7b8}', ['\u{a7b9}', '\u{0}', '\u{0}']), + ('\u{a7ba}', ['\u{a7bb}', '\u{0}', '\u{0}']), ('\u{a7bc}', ['\u{a7bd}', '\u{0}', '\u{0}']), + ('\u{a7be}', ['\u{a7bf}', '\u{0}', '\u{0}']), ('\u{a7c2}', ['\u{a7c3}', '\u{0}', '\u{0}']), + ('\u{a7c4}', ['\u{a794}', '\u{0}', '\u{0}']), ('\u{a7c5}', ['\u{282}', '\u{0}', '\u{0}']), + ('\u{a7c6}', ['\u{1d8e}', '\u{0}', '\u{0}']), ('\u{ff21}', ['\u{ff41}', '\u{0}', '\u{0}']), + ('\u{ff22}', ['\u{ff42}', '\u{0}', '\u{0}']), ('\u{ff23}', ['\u{ff43}', '\u{0}', '\u{0}']), + ('\u{ff24}', ['\u{ff44}', '\u{0}', '\u{0}']), ('\u{ff25}', ['\u{ff45}', '\u{0}', '\u{0}']), + ('\u{ff26}', ['\u{ff46}', '\u{0}', '\u{0}']), ('\u{ff27}', ['\u{ff47}', '\u{0}', '\u{0}']), + ('\u{ff28}', ['\u{ff48}', '\u{0}', '\u{0}']), ('\u{ff29}', ['\u{ff49}', '\u{0}', '\u{0}']), + ('\u{ff2a}', ['\u{ff4a}', '\u{0}', '\u{0}']), ('\u{ff2b}', ['\u{ff4b}', '\u{0}', '\u{0}']), + ('\u{ff2c}', ['\u{ff4c}', '\u{0}', '\u{0}']), ('\u{ff2d}', ['\u{ff4d}', '\u{0}', '\u{0}']), + ('\u{ff2e}', ['\u{ff4e}', '\u{0}', '\u{0}']), ('\u{ff2f}', ['\u{ff4f}', '\u{0}', '\u{0}']), + ('\u{ff30}', ['\u{ff50}', '\u{0}', '\u{0}']), ('\u{ff31}', ['\u{ff51}', '\u{0}', '\u{0}']), + ('\u{ff32}', ['\u{ff52}', '\u{0}', '\u{0}']), ('\u{ff33}', ['\u{ff53}', '\u{0}', '\u{0}']), + ('\u{ff34}', ['\u{ff54}', '\u{0}', '\u{0}']), ('\u{ff35}', ['\u{ff55}', '\u{0}', '\u{0}']), + ('\u{ff36}', ['\u{ff56}', '\u{0}', '\u{0}']), ('\u{ff37}', ['\u{ff57}', '\u{0}', '\u{0}']), + ('\u{ff38}', ['\u{ff58}', '\u{0}', '\u{0}']), ('\u{ff39}', ['\u{ff59}', '\u{0}', '\u{0}']), + ('\u{ff3a}', ['\u{ff5a}', '\u{0}', '\u{0}']), + ('\u{10400}', ['\u{10428}', '\u{0}', '\u{0}']), + ('\u{10401}', ['\u{10429}', '\u{0}', '\u{0}']), + ('\u{10402}', ['\u{1042a}', '\u{0}', '\u{0}']), + ('\u{10403}', ['\u{1042b}', '\u{0}', '\u{0}']), + ('\u{10404}', ['\u{1042c}', '\u{0}', '\u{0}']), + ('\u{10405}', ['\u{1042d}', '\u{0}', '\u{0}']), + ('\u{10406}', ['\u{1042e}', '\u{0}', '\u{0}']), + ('\u{10407}', ['\u{1042f}', '\u{0}', '\u{0}']), + ('\u{10408}', ['\u{10430}', '\u{0}', '\u{0}']), + ('\u{10409}', ['\u{10431}', '\u{0}', '\u{0}']), + ('\u{1040a}', ['\u{10432}', '\u{0}', '\u{0}']), + ('\u{1040b}', ['\u{10433}', '\u{0}', '\u{0}']), + ('\u{1040c}', ['\u{10434}', '\u{0}', '\u{0}']), + ('\u{1040d}', ['\u{10435}', '\u{0}', '\u{0}']), + ('\u{1040e}', ['\u{10436}', '\u{0}', '\u{0}']), + ('\u{1040f}', ['\u{10437}', '\u{0}', '\u{0}']), + ('\u{10410}', ['\u{10438}', '\u{0}', '\u{0}']), + ('\u{10411}', ['\u{10439}', '\u{0}', '\u{0}']), + ('\u{10412}', ['\u{1043a}', '\u{0}', '\u{0}']), + ('\u{10413}', ['\u{1043b}', '\u{0}', '\u{0}']), + ('\u{10414}', ['\u{1043c}', '\u{0}', '\u{0}']), + ('\u{10415}', ['\u{1043d}', '\u{0}', '\u{0}']), + ('\u{10416}', ['\u{1043e}', '\u{0}', '\u{0}']), + ('\u{10417}', ['\u{1043f}', '\u{0}', '\u{0}']), + ('\u{10418}', ['\u{10440}', '\u{0}', '\u{0}']), + ('\u{10419}', ['\u{10441}', '\u{0}', '\u{0}']), + ('\u{1041a}', ['\u{10442}', '\u{0}', '\u{0}']), + ('\u{1041b}', ['\u{10443}', '\u{0}', '\u{0}']), + ('\u{1041c}', ['\u{10444}', '\u{0}', '\u{0}']), + ('\u{1041d}', ['\u{10445}', '\u{0}', '\u{0}']), + ('\u{1041e}', ['\u{10446}', '\u{0}', '\u{0}']), + ('\u{1041f}', ['\u{10447}', '\u{0}', '\u{0}']), + ('\u{10420}', ['\u{10448}', '\u{0}', '\u{0}']), + ('\u{10421}', ['\u{10449}', '\u{0}', '\u{0}']), + ('\u{10422}', ['\u{1044a}', '\u{0}', '\u{0}']), + ('\u{10423}', ['\u{1044b}', '\u{0}', '\u{0}']), + ('\u{10424}', ['\u{1044c}', '\u{0}', '\u{0}']), + ('\u{10425}', ['\u{1044d}', '\u{0}', '\u{0}']), + ('\u{10426}', ['\u{1044e}', '\u{0}', '\u{0}']), + ('\u{10427}', ['\u{1044f}', '\u{0}', '\u{0}']), + ('\u{104b0}', ['\u{104d8}', '\u{0}', '\u{0}']), + ('\u{104b1}', ['\u{104d9}', '\u{0}', '\u{0}']), + ('\u{104b2}', ['\u{104da}', '\u{0}', '\u{0}']), + ('\u{104b3}', ['\u{104db}', '\u{0}', '\u{0}']), + ('\u{104b4}', ['\u{104dc}', '\u{0}', '\u{0}']), + ('\u{104b5}', ['\u{104dd}', '\u{0}', '\u{0}']), + ('\u{104b6}', ['\u{104de}', '\u{0}', '\u{0}']), + ('\u{104b7}', ['\u{104df}', '\u{0}', '\u{0}']), + ('\u{104b8}', ['\u{104e0}', '\u{0}', '\u{0}']), + ('\u{104b9}', ['\u{104e1}', '\u{0}', '\u{0}']), + ('\u{104ba}', ['\u{104e2}', '\u{0}', '\u{0}']), + ('\u{104bb}', ['\u{104e3}', '\u{0}', '\u{0}']), + ('\u{104bc}', ['\u{104e4}', '\u{0}', '\u{0}']), + ('\u{104bd}', ['\u{104e5}', '\u{0}', '\u{0}']), + ('\u{104be}', ['\u{104e6}', '\u{0}', '\u{0}']), + ('\u{104bf}', ['\u{104e7}', '\u{0}', '\u{0}']), + ('\u{104c0}', ['\u{104e8}', '\u{0}', '\u{0}']), + ('\u{104c1}', ['\u{104e9}', '\u{0}', '\u{0}']), + ('\u{104c2}', ['\u{104ea}', '\u{0}', '\u{0}']), + ('\u{104c3}', ['\u{104eb}', '\u{0}', '\u{0}']), + ('\u{104c4}', ['\u{104ec}', '\u{0}', '\u{0}']), + ('\u{104c5}', ['\u{104ed}', '\u{0}', '\u{0}']), + ('\u{104c6}', ['\u{104ee}', '\u{0}', '\u{0}']), + ('\u{104c7}', ['\u{104ef}', '\u{0}', '\u{0}']), + ('\u{104c8}', ['\u{104f0}', '\u{0}', '\u{0}']), + ('\u{104c9}', ['\u{104f1}', '\u{0}', '\u{0}']), + ('\u{104ca}', ['\u{104f2}', '\u{0}', '\u{0}']), + ('\u{104cb}', ['\u{104f3}', '\u{0}', '\u{0}']), + ('\u{104cc}', ['\u{104f4}', '\u{0}', '\u{0}']), + ('\u{104cd}', ['\u{104f5}', '\u{0}', '\u{0}']), + ('\u{104ce}', ['\u{104f6}', '\u{0}', '\u{0}']), + ('\u{104cf}', ['\u{104f7}', '\u{0}', '\u{0}']), + ('\u{104d0}', ['\u{104f8}', '\u{0}', '\u{0}']), + ('\u{104d1}', ['\u{104f9}', '\u{0}', '\u{0}']), + ('\u{104d2}', ['\u{104fa}', '\u{0}', '\u{0}']), + ('\u{104d3}', ['\u{104fb}', '\u{0}', '\u{0}']), + ('\u{10c80}', ['\u{10cc0}', '\u{0}', '\u{0}']), + ('\u{10c81}', ['\u{10cc1}', '\u{0}', '\u{0}']), + ('\u{10c82}', ['\u{10cc2}', '\u{0}', '\u{0}']), + ('\u{10c83}', ['\u{10cc3}', '\u{0}', '\u{0}']), + ('\u{10c84}', ['\u{10cc4}', '\u{0}', '\u{0}']), + ('\u{10c85}', ['\u{10cc5}', '\u{0}', '\u{0}']), + ('\u{10c86}', ['\u{10cc6}', '\u{0}', '\u{0}']), + ('\u{10c87}', ['\u{10cc7}', '\u{0}', '\u{0}']), + ('\u{10c88}', ['\u{10cc8}', '\u{0}', '\u{0}']), + ('\u{10c89}', ['\u{10cc9}', '\u{0}', '\u{0}']), + ('\u{10c8a}', ['\u{10cca}', '\u{0}', '\u{0}']), + ('\u{10c8b}', ['\u{10ccb}', '\u{0}', '\u{0}']), + ('\u{10c8c}', ['\u{10ccc}', '\u{0}', '\u{0}']), + ('\u{10c8d}', ['\u{10ccd}', '\u{0}', '\u{0}']), + ('\u{10c8e}', ['\u{10cce}', '\u{0}', '\u{0}']), + ('\u{10c8f}', ['\u{10ccf}', '\u{0}', '\u{0}']), + ('\u{10c90}', ['\u{10cd0}', '\u{0}', '\u{0}']), + ('\u{10c91}', ['\u{10cd1}', '\u{0}', '\u{0}']), + ('\u{10c92}', ['\u{10cd2}', '\u{0}', '\u{0}']), + ('\u{10c93}', ['\u{10cd3}', '\u{0}', '\u{0}']), + ('\u{10c94}', ['\u{10cd4}', '\u{0}', '\u{0}']), + ('\u{10c95}', ['\u{10cd5}', '\u{0}', '\u{0}']), + ('\u{10c96}', ['\u{10cd6}', '\u{0}', '\u{0}']), + ('\u{10c97}', ['\u{10cd7}', '\u{0}', '\u{0}']), + ('\u{10c98}', ['\u{10cd8}', '\u{0}', '\u{0}']), + ('\u{10c99}', ['\u{10cd9}', '\u{0}', '\u{0}']), + ('\u{10c9a}', ['\u{10cda}', '\u{0}', '\u{0}']), + ('\u{10c9b}', ['\u{10cdb}', '\u{0}', '\u{0}']), + ('\u{10c9c}', ['\u{10cdc}', '\u{0}', '\u{0}']), + ('\u{10c9d}', ['\u{10cdd}', '\u{0}', '\u{0}']), + ('\u{10c9e}', ['\u{10cde}', '\u{0}', '\u{0}']), + ('\u{10c9f}', ['\u{10cdf}', '\u{0}', '\u{0}']), + ('\u{10ca0}', ['\u{10ce0}', '\u{0}', '\u{0}']), + ('\u{10ca1}', ['\u{10ce1}', '\u{0}', '\u{0}']), + ('\u{10ca2}', ['\u{10ce2}', '\u{0}', '\u{0}']), + ('\u{10ca3}', ['\u{10ce3}', '\u{0}', '\u{0}']), + ('\u{10ca4}', ['\u{10ce4}', '\u{0}', '\u{0}']), + ('\u{10ca5}', ['\u{10ce5}', '\u{0}', '\u{0}']), + ('\u{10ca6}', ['\u{10ce6}', '\u{0}', '\u{0}']), + ('\u{10ca7}', ['\u{10ce7}', '\u{0}', '\u{0}']), + ('\u{10ca8}', ['\u{10ce8}', '\u{0}', '\u{0}']), + ('\u{10ca9}', ['\u{10ce9}', '\u{0}', '\u{0}']), + ('\u{10caa}', ['\u{10cea}', '\u{0}', '\u{0}']), + ('\u{10cab}', ['\u{10ceb}', '\u{0}', '\u{0}']), + ('\u{10cac}', ['\u{10cec}', '\u{0}', '\u{0}']), + ('\u{10cad}', ['\u{10ced}', '\u{0}', '\u{0}']), + ('\u{10cae}', ['\u{10cee}', '\u{0}', '\u{0}']), + ('\u{10caf}', ['\u{10cef}', '\u{0}', '\u{0}']), + ('\u{10cb0}', ['\u{10cf0}', '\u{0}', '\u{0}']), + ('\u{10cb1}', ['\u{10cf1}', '\u{0}', '\u{0}']), + ('\u{10cb2}', ['\u{10cf2}', '\u{0}', '\u{0}']), + ('\u{118a0}', ['\u{118c0}', '\u{0}', '\u{0}']), + ('\u{118a1}', ['\u{118c1}', '\u{0}', '\u{0}']), + ('\u{118a2}', ['\u{118c2}', '\u{0}', '\u{0}']), + ('\u{118a3}', ['\u{118c3}', '\u{0}', '\u{0}']), + ('\u{118a4}', ['\u{118c4}', '\u{0}', '\u{0}']), + ('\u{118a5}', ['\u{118c5}', '\u{0}', '\u{0}']), + ('\u{118a6}', ['\u{118c6}', '\u{0}', '\u{0}']), + ('\u{118a7}', ['\u{118c7}', '\u{0}', '\u{0}']), + ('\u{118a8}', ['\u{118c8}', '\u{0}', '\u{0}']), + ('\u{118a9}', ['\u{118c9}', '\u{0}', '\u{0}']), + ('\u{118aa}', ['\u{118ca}', '\u{0}', '\u{0}']), + ('\u{118ab}', ['\u{118cb}', '\u{0}', '\u{0}']), + ('\u{118ac}', ['\u{118cc}', '\u{0}', '\u{0}']), + ('\u{118ad}', ['\u{118cd}', '\u{0}', '\u{0}']), + ('\u{118ae}', ['\u{118ce}', '\u{0}', '\u{0}']), + ('\u{118af}', ['\u{118cf}', '\u{0}', '\u{0}']), + ('\u{118b0}', ['\u{118d0}', '\u{0}', '\u{0}']), + ('\u{118b1}', ['\u{118d1}', '\u{0}', '\u{0}']), + ('\u{118b2}', ['\u{118d2}', '\u{0}', '\u{0}']), + ('\u{118b3}', ['\u{118d3}', '\u{0}', '\u{0}']), + ('\u{118b4}', ['\u{118d4}', '\u{0}', '\u{0}']), + ('\u{118b5}', ['\u{118d5}', '\u{0}', '\u{0}']), + ('\u{118b6}', ['\u{118d6}', '\u{0}', '\u{0}']), + ('\u{118b7}', ['\u{118d7}', '\u{0}', '\u{0}']), + ('\u{118b8}', ['\u{118d8}', '\u{0}', '\u{0}']), + ('\u{118b9}', ['\u{118d9}', '\u{0}', '\u{0}']), + ('\u{118ba}', ['\u{118da}', '\u{0}', '\u{0}']), + ('\u{118bb}', ['\u{118db}', '\u{0}', '\u{0}']), + ('\u{118bc}', ['\u{118dc}', '\u{0}', '\u{0}']), + ('\u{118bd}', ['\u{118dd}', '\u{0}', '\u{0}']), + ('\u{118be}', ['\u{118de}', '\u{0}', '\u{0}']), + ('\u{118bf}', ['\u{118df}', '\u{0}', '\u{0}']), + ('\u{16e40}', ['\u{16e60}', '\u{0}', '\u{0}']), + ('\u{16e41}', ['\u{16e61}', '\u{0}', '\u{0}']), + ('\u{16e42}', ['\u{16e62}', '\u{0}', '\u{0}']), + ('\u{16e43}', ['\u{16e63}', '\u{0}', '\u{0}']), + ('\u{16e44}', ['\u{16e64}', '\u{0}', '\u{0}']), + ('\u{16e45}', ['\u{16e65}', '\u{0}', '\u{0}']), + ('\u{16e46}', ['\u{16e66}', '\u{0}', '\u{0}']), + ('\u{16e47}', ['\u{16e67}', '\u{0}', '\u{0}']), + ('\u{16e48}', ['\u{16e68}', '\u{0}', '\u{0}']), + ('\u{16e49}', ['\u{16e69}', '\u{0}', '\u{0}']), + ('\u{16e4a}', ['\u{16e6a}', '\u{0}', '\u{0}']), + ('\u{16e4b}', ['\u{16e6b}', '\u{0}', '\u{0}']), + ('\u{16e4c}', ['\u{16e6c}', '\u{0}', '\u{0}']), + ('\u{16e4d}', ['\u{16e6d}', '\u{0}', '\u{0}']), + ('\u{16e4e}', ['\u{16e6e}', '\u{0}', '\u{0}']), + ('\u{16e4f}', ['\u{16e6f}', '\u{0}', '\u{0}']), + ('\u{16e50}', ['\u{16e70}', '\u{0}', '\u{0}']), + ('\u{16e51}', ['\u{16e71}', '\u{0}', '\u{0}']), + ('\u{16e52}', ['\u{16e72}', '\u{0}', '\u{0}']), + ('\u{16e53}', ['\u{16e73}', '\u{0}', '\u{0}']), + ('\u{16e54}', ['\u{16e74}', '\u{0}', '\u{0}']), + ('\u{16e55}', ['\u{16e75}', '\u{0}', '\u{0}']), + ('\u{16e56}', ['\u{16e76}', '\u{0}', '\u{0}']), + ('\u{16e57}', ['\u{16e77}', '\u{0}', '\u{0}']), + ('\u{16e58}', ['\u{16e78}', '\u{0}', '\u{0}']), + ('\u{16e59}', ['\u{16e79}', '\u{0}', '\u{0}']), + ('\u{16e5a}', ['\u{16e7a}', '\u{0}', '\u{0}']), + ('\u{16e5b}', ['\u{16e7b}', '\u{0}', '\u{0}']), + ('\u{16e5c}', ['\u{16e7c}', '\u{0}', '\u{0}']), + ('\u{16e5d}', ['\u{16e7d}', '\u{0}', '\u{0}']), + ('\u{16e5e}', ['\u{16e7e}', '\u{0}', '\u{0}']), + ('\u{16e5f}', ['\u{16e7f}', '\u{0}', '\u{0}']), + ('\u{1e900}', ['\u{1e922}', '\u{0}', '\u{0}']), + ('\u{1e901}', ['\u{1e923}', '\u{0}', '\u{0}']), + ('\u{1e902}', ['\u{1e924}', '\u{0}', '\u{0}']), + ('\u{1e903}', ['\u{1e925}', '\u{0}', '\u{0}']), + ('\u{1e904}', ['\u{1e926}', '\u{0}', '\u{0}']), + ('\u{1e905}', ['\u{1e927}', '\u{0}', '\u{0}']), + ('\u{1e906}', ['\u{1e928}', '\u{0}', '\u{0}']), + ('\u{1e907}', ['\u{1e929}', '\u{0}', '\u{0}']), + ('\u{1e908}', ['\u{1e92a}', '\u{0}', '\u{0}']), + ('\u{1e909}', ['\u{1e92b}', '\u{0}', '\u{0}']), + ('\u{1e90a}', ['\u{1e92c}', '\u{0}', '\u{0}']), + ('\u{1e90b}', ['\u{1e92d}', '\u{0}', '\u{0}']), + ('\u{1e90c}', ['\u{1e92e}', '\u{0}', '\u{0}']), + ('\u{1e90d}', ['\u{1e92f}', '\u{0}', '\u{0}']), + ('\u{1e90e}', ['\u{1e930}', '\u{0}', '\u{0}']), + ('\u{1e90f}', ['\u{1e931}', '\u{0}', '\u{0}']), + ('\u{1e910}', ['\u{1e932}', '\u{0}', '\u{0}']), + ('\u{1e911}', ['\u{1e933}', '\u{0}', '\u{0}']), + ('\u{1e912}', ['\u{1e934}', '\u{0}', '\u{0}']), + ('\u{1e913}', ['\u{1e935}', '\u{0}', '\u{0}']), + ('\u{1e914}', ['\u{1e936}', '\u{0}', '\u{0}']), + ('\u{1e915}', ['\u{1e937}', '\u{0}', '\u{0}']), + ('\u{1e916}', ['\u{1e938}', '\u{0}', '\u{0}']), + ('\u{1e917}', ['\u{1e939}', '\u{0}', '\u{0}']), + ('\u{1e918}', ['\u{1e93a}', '\u{0}', '\u{0}']), + ('\u{1e919}', ['\u{1e93b}', '\u{0}', '\u{0}']), + ('\u{1e91a}', ['\u{1e93c}', '\u{0}', '\u{0}']), + ('\u{1e91b}', ['\u{1e93d}', '\u{0}', '\u{0}']), + ('\u{1e91c}', ['\u{1e93e}', '\u{0}', '\u{0}']), + ('\u{1e91d}', ['\u{1e93f}', '\u{0}', '\u{0}']), + ('\u{1e91e}', ['\u{1e940}', '\u{0}', '\u{0}']), + ('\u{1e91f}', ['\u{1e941}', '\u{0}', '\u{0}']), + ('\u{1e920}', ['\u{1e942}', '\u{0}', '\u{0}']), + ('\u{1e921}', ['\u{1e943}', '\u{0}', '\u{0}']), + ]; + + static UPPERCASE_TABLE: &[(char, [char; 3])] = &[ + ('a', ['A', '\u{0}', '\u{0}']), ('b', ['B', '\u{0}', '\u{0}']), + ('c', ['C', '\u{0}', '\u{0}']), ('d', ['D', '\u{0}', '\u{0}']), + ('e', ['E', '\u{0}', '\u{0}']), ('f', ['F', '\u{0}', '\u{0}']), + ('g', ['G', '\u{0}', '\u{0}']), ('h', ['H', '\u{0}', '\u{0}']), + ('i', ['I', '\u{0}', '\u{0}']), ('j', ['J', '\u{0}', '\u{0}']), + ('k', ['K', '\u{0}', '\u{0}']), ('l', ['L', '\u{0}', '\u{0}']), + ('m', ['M', '\u{0}', '\u{0}']), ('n', ['N', '\u{0}', '\u{0}']), + ('o', ['O', '\u{0}', '\u{0}']), ('p', ['P', '\u{0}', '\u{0}']), + ('q', ['Q', '\u{0}', '\u{0}']), ('r', ['R', '\u{0}', '\u{0}']), + ('s', ['S', '\u{0}', '\u{0}']), ('t', ['T', '\u{0}', '\u{0}']), + ('u', ['U', '\u{0}', '\u{0}']), ('v', ['V', '\u{0}', '\u{0}']), + ('w', ['W', '\u{0}', '\u{0}']), ('x', ['X', '\u{0}', '\u{0}']), + ('y', ['Y', '\u{0}', '\u{0}']), ('z', ['Z', '\u{0}', '\u{0}']), + ('\u{b5}', ['\u{39c}', '\u{0}', '\u{0}']), ('\u{df}', ['S', 'S', '\u{0}']), + ('\u{e0}', ['\u{c0}', '\u{0}', '\u{0}']), ('\u{e1}', ['\u{c1}', '\u{0}', '\u{0}']), + ('\u{e2}', ['\u{c2}', '\u{0}', '\u{0}']), ('\u{e3}', ['\u{c3}', '\u{0}', '\u{0}']), + ('\u{e4}', ['\u{c4}', '\u{0}', '\u{0}']), ('\u{e5}', ['\u{c5}', '\u{0}', '\u{0}']), + ('\u{e6}', ['\u{c6}', '\u{0}', '\u{0}']), ('\u{e7}', ['\u{c7}', '\u{0}', '\u{0}']), + ('\u{e8}', ['\u{c8}', '\u{0}', '\u{0}']), ('\u{e9}', ['\u{c9}', '\u{0}', '\u{0}']), + ('\u{ea}', ['\u{ca}', '\u{0}', '\u{0}']), ('\u{eb}', ['\u{cb}', '\u{0}', '\u{0}']), + ('\u{ec}', ['\u{cc}', '\u{0}', '\u{0}']), ('\u{ed}', ['\u{cd}', '\u{0}', '\u{0}']), + ('\u{ee}', ['\u{ce}', '\u{0}', '\u{0}']), ('\u{ef}', ['\u{cf}', '\u{0}', '\u{0}']), + ('\u{f0}', ['\u{d0}', '\u{0}', '\u{0}']), ('\u{f1}', ['\u{d1}', '\u{0}', '\u{0}']), + ('\u{f2}', ['\u{d2}', '\u{0}', '\u{0}']), ('\u{f3}', ['\u{d3}', '\u{0}', '\u{0}']), + ('\u{f4}', ['\u{d4}', '\u{0}', '\u{0}']), ('\u{f5}', ['\u{d5}', '\u{0}', '\u{0}']), + ('\u{f6}', ['\u{d6}', '\u{0}', '\u{0}']), ('\u{f8}', ['\u{d8}', '\u{0}', '\u{0}']), + ('\u{f9}', ['\u{d9}', '\u{0}', '\u{0}']), ('\u{fa}', ['\u{da}', '\u{0}', '\u{0}']), + ('\u{fb}', ['\u{db}', '\u{0}', '\u{0}']), ('\u{fc}', ['\u{dc}', '\u{0}', '\u{0}']), + ('\u{fd}', ['\u{dd}', '\u{0}', '\u{0}']), ('\u{fe}', ['\u{de}', '\u{0}', '\u{0}']), + ('\u{ff}', ['\u{178}', '\u{0}', '\u{0}']), ('\u{101}', ['\u{100}', '\u{0}', '\u{0}']), + ('\u{103}', ['\u{102}', '\u{0}', '\u{0}']), ('\u{105}', ['\u{104}', '\u{0}', '\u{0}']), + ('\u{107}', ['\u{106}', '\u{0}', '\u{0}']), ('\u{109}', ['\u{108}', '\u{0}', '\u{0}']), + ('\u{10b}', ['\u{10a}', '\u{0}', '\u{0}']), ('\u{10d}', ['\u{10c}', '\u{0}', '\u{0}']), + ('\u{10f}', ['\u{10e}', '\u{0}', '\u{0}']), ('\u{111}', ['\u{110}', '\u{0}', '\u{0}']), + ('\u{113}', ['\u{112}', '\u{0}', '\u{0}']), ('\u{115}', ['\u{114}', '\u{0}', '\u{0}']), + ('\u{117}', ['\u{116}', '\u{0}', '\u{0}']), ('\u{119}', ['\u{118}', '\u{0}', '\u{0}']), + ('\u{11b}', ['\u{11a}', '\u{0}', '\u{0}']), ('\u{11d}', ['\u{11c}', '\u{0}', '\u{0}']), + ('\u{11f}', ['\u{11e}', '\u{0}', '\u{0}']), ('\u{121}', ['\u{120}', '\u{0}', '\u{0}']), + ('\u{123}', ['\u{122}', '\u{0}', '\u{0}']), ('\u{125}', ['\u{124}', '\u{0}', '\u{0}']), + ('\u{127}', ['\u{126}', '\u{0}', '\u{0}']), ('\u{129}', ['\u{128}', '\u{0}', '\u{0}']), + ('\u{12b}', ['\u{12a}', '\u{0}', '\u{0}']), ('\u{12d}', ['\u{12c}', '\u{0}', '\u{0}']), + ('\u{12f}', ['\u{12e}', '\u{0}', '\u{0}']), ('\u{131}', ['I', '\u{0}', '\u{0}']), + ('\u{133}', ['\u{132}', '\u{0}', '\u{0}']), ('\u{135}', ['\u{134}', '\u{0}', '\u{0}']), + ('\u{137}', ['\u{136}', '\u{0}', '\u{0}']), ('\u{13a}', ['\u{139}', '\u{0}', '\u{0}']), + ('\u{13c}', ['\u{13b}', '\u{0}', '\u{0}']), ('\u{13e}', ['\u{13d}', '\u{0}', '\u{0}']), + ('\u{140}', ['\u{13f}', '\u{0}', '\u{0}']), ('\u{142}', ['\u{141}', '\u{0}', '\u{0}']), + ('\u{144}', ['\u{143}', '\u{0}', '\u{0}']), ('\u{146}', ['\u{145}', '\u{0}', '\u{0}']), + ('\u{148}', ['\u{147}', '\u{0}', '\u{0}']), ('\u{149}', ['\u{2bc}', 'N', '\u{0}']), + ('\u{14b}', ['\u{14a}', '\u{0}', '\u{0}']), ('\u{14d}', ['\u{14c}', '\u{0}', '\u{0}']), + ('\u{14f}', ['\u{14e}', '\u{0}', '\u{0}']), ('\u{151}', ['\u{150}', '\u{0}', '\u{0}']), + ('\u{153}', ['\u{152}', '\u{0}', '\u{0}']), ('\u{155}', ['\u{154}', '\u{0}', '\u{0}']), + ('\u{157}', ['\u{156}', '\u{0}', '\u{0}']), ('\u{159}', ['\u{158}', '\u{0}', '\u{0}']), + ('\u{15b}', ['\u{15a}', '\u{0}', '\u{0}']), ('\u{15d}', ['\u{15c}', '\u{0}', '\u{0}']), + ('\u{15f}', ['\u{15e}', '\u{0}', '\u{0}']), ('\u{161}', ['\u{160}', '\u{0}', '\u{0}']), + ('\u{163}', ['\u{162}', '\u{0}', '\u{0}']), ('\u{165}', ['\u{164}', '\u{0}', '\u{0}']), + ('\u{167}', ['\u{166}', '\u{0}', '\u{0}']), ('\u{169}', ['\u{168}', '\u{0}', '\u{0}']), + ('\u{16b}', ['\u{16a}', '\u{0}', '\u{0}']), ('\u{16d}', ['\u{16c}', '\u{0}', '\u{0}']), + ('\u{16f}', ['\u{16e}', '\u{0}', '\u{0}']), ('\u{171}', ['\u{170}', '\u{0}', '\u{0}']), + ('\u{173}', ['\u{172}', '\u{0}', '\u{0}']), ('\u{175}', ['\u{174}', '\u{0}', '\u{0}']), + ('\u{177}', ['\u{176}', '\u{0}', '\u{0}']), ('\u{17a}', ['\u{179}', '\u{0}', '\u{0}']), + ('\u{17c}', ['\u{17b}', '\u{0}', '\u{0}']), ('\u{17e}', ['\u{17d}', '\u{0}', '\u{0}']), + ('\u{17f}', ['S', '\u{0}', '\u{0}']), ('\u{180}', ['\u{243}', '\u{0}', '\u{0}']), + ('\u{183}', ['\u{182}', '\u{0}', '\u{0}']), ('\u{185}', ['\u{184}', '\u{0}', '\u{0}']), + ('\u{188}', ['\u{187}', '\u{0}', '\u{0}']), ('\u{18c}', ['\u{18b}', '\u{0}', '\u{0}']), + ('\u{192}', ['\u{191}', '\u{0}', '\u{0}']), ('\u{195}', ['\u{1f6}', '\u{0}', '\u{0}']), + ('\u{199}', ['\u{198}', '\u{0}', '\u{0}']), ('\u{19a}', ['\u{23d}', '\u{0}', '\u{0}']), + ('\u{19e}', ['\u{220}', '\u{0}', '\u{0}']), ('\u{1a1}', ['\u{1a0}', '\u{0}', '\u{0}']), + ('\u{1a3}', ['\u{1a2}', '\u{0}', '\u{0}']), ('\u{1a5}', ['\u{1a4}', '\u{0}', '\u{0}']), + ('\u{1a8}', ['\u{1a7}', '\u{0}', '\u{0}']), ('\u{1ad}', ['\u{1ac}', '\u{0}', '\u{0}']), + ('\u{1b0}', ['\u{1af}', '\u{0}', '\u{0}']), ('\u{1b4}', ['\u{1b3}', '\u{0}', '\u{0}']), + ('\u{1b6}', ['\u{1b5}', '\u{0}', '\u{0}']), ('\u{1b9}', ['\u{1b8}', '\u{0}', '\u{0}']), + ('\u{1bd}', ['\u{1bc}', '\u{0}', '\u{0}']), ('\u{1bf}', ['\u{1f7}', '\u{0}', '\u{0}']), + ('\u{1c5}', ['\u{1c4}', '\u{0}', '\u{0}']), ('\u{1c6}', ['\u{1c4}', '\u{0}', '\u{0}']), + ('\u{1c8}', ['\u{1c7}', '\u{0}', '\u{0}']), ('\u{1c9}', ['\u{1c7}', '\u{0}', '\u{0}']), + ('\u{1cb}', ['\u{1ca}', '\u{0}', '\u{0}']), ('\u{1cc}', ['\u{1ca}', '\u{0}', '\u{0}']), + ('\u{1ce}', ['\u{1cd}', '\u{0}', '\u{0}']), ('\u{1d0}', ['\u{1cf}', '\u{0}', '\u{0}']), + ('\u{1d2}', ['\u{1d1}', '\u{0}', '\u{0}']), ('\u{1d4}', ['\u{1d3}', '\u{0}', '\u{0}']), + ('\u{1d6}', ['\u{1d5}', '\u{0}', '\u{0}']), ('\u{1d8}', ['\u{1d7}', '\u{0}', '\u{0}']), + ('\u{1da}', ['\u{1d9}', '\u{0}', '\u{0}']), ('\u{1dc}', ['\u{1db}', '\u{0}', '\u{0}']), + ('\u{1dd}', ['\u{18e}', '\u{0}', '\u{0}']), ('\u{1df}', ['\u{1de}', '\u{0}', '\u{0}']), + ('\u{1e1}', ['\u{1e0}', '\u{0}', '\u{0}']), ('\u{1e3}', ['\u{1e2}', '\u{0}', '\u{0}']), + ('\u{1e5}', ['\u{1e4}', '\u{0}', '\u{0}']), ('\u{1e7}', ['\u{1e6}', '\u{0}', '\u{0}']), + ('\u{1e9}', ['\u{1e8}', '\u{0}', '\u{0}']), ('\u{1eb}', ['\u{1ea}', '\u{0}', '\u{0}']), + ('\u{1ed}', ['\u{1ec}', '\u{0}', '\u{0}']), ('\u{1ef}', ['\u{1ee}', '\u{0}', '\u{0}']), + ('\u{1f0}', ['J', '\u{30c}', '\u{0}']), ('\u{1f2}', ['\u{1f1}', '\u{0}', '\u{0}']), + ('\u{1f3}', ['\u{1f1}', '\u{0}', '\u{0}']), ('\u{1f5}', ['\u{1f4}', '\u{0}', '\u{0}']), + ('\u{1f9}', ['\u{1f8}', '\u{0}', '\u{0}']), ('\u{1fb}', ['\u{1fa}', '\u{0}', '\u{0}']), + ('\u{1fd}', ['\u{1fc}', '\u{0}', '\u{0}']), ('\u{1ff}', ['\u{1fe}', '\u{0}', '\u{0}']), + ('\u{201}', ['\u{200}', '\u{0}', '\u{0}']), ('\u{203}', ['\u{202}', '\u{0}', '\u{0}']), + ('\u{205}', ['\u{204}', '\u{0}', '\u{0}']), ('\u{207}', ['\u{206}', '\u{0}', '\u{0}']), + ('\u{209}', ['\u{208}', '\u{0}', '\u{0}']), ('\u{20b}', ['\u{20a}', '\u{0}', '\u{0}']), + ('\u{20d}', ['\u{20c}', '\u{0}', '\u{0}']), ('\u{20f}', ['\u{20e}', '\u{0}', '\u{0}']), + ('\u{211}', ['\u{210}', '\u{0}', '\u{0}']), ('\u{213}', ['\u{212}', '\u{0}', '\u{0}']), + ('\u{215}', ['\u{214}', '\u{0}', '\u{0}']), ('\u{217}', ['\u{216}', '\u{0}', '\u{0}']), + ('\u{219}', ['\u{218}', '\u{0}', '\u{0}']), ('\u{21b}', ['\u{21a}', '\u{0}', '\u{0}']), + ('\u{21d}', ['\u{21c}', '\u{0}', '\u{0}']), ('\u{21f}', ['\u{21e}', '\u{0}', '\u{0}']), + ('\u{223}', ['\u{222}', '\u{0}', '\u{0}']), ('\u{225}', ['\u{224}', '\u{0}', '\u{0}']), + ('\u{227}', ['\u{226}', '\u{0}', '\u{0}']), ('\u{229}', ['\u{228}', '\u{0}', '\u{0}']), + ('\u{22b}', ['\u{22a}', '\u{0}', '\u{0}']), ('\u{22d}', ['\u{22c}', '\u{0}', '\u{0}']), + ('\u{22f}', ['\u{22e}', '\u{0}', '\u{0}']), ('\u{231}', ['\u{230}', '\u{0}', '\u{0}']), + ('\u{233}', ['\u{232}', '\u{0}', '\u{0}']), ('\u{23c}', ['\u{23b}', '\u{0}', '\u{0}']), + ('\u{23f}', ['\u{2c7e}', '\u{0}', '\u{0}']), ('\u{240}', ['\u{2c7f}', '\u{0}', '\u{0}']), + ('\u{242}', ['\u{241}', '\u{0}', '\u{0}']), ('\u{247}', ['\u{246}', '\u{0}', '\u{0}']), + ('\u{249}', ['\u{248}', '\u{0}', '\u{0}']), ('\u{24b}', ['\u{24a}', '\u{0}', '\u{0}']), + ('\u{24d}', ['\u{24c}', '\u{0}', '\u{0}']), ('\u{24f}', ['\u{24e}', '\u{0}', '\u{0}']), + ('\u{250}', ['\u{2c6f}', '\u{0}', '\u{0}']), ('\u{251}', ['\u{2c6d}', '\u{0}', '\u{0}']), + ('\u{252}', ['\u{2c70}', '\u{0}', '\u{0}']), ('\u{253}', ['\u{181}', '\u{0}', '\u{0}']), + ('\u{254}', ['\u{186}', '\u{0}', '\u{0}']), ('\u{256}', ['\u{189}', '\u{0}', '\u{0}']), + ('\u{257}', ['\u{18a}', '\u{0}', '\u{0}']), ('\u{259}', ['\u{18f}', '\u{0}', '\u{0}']), + ('\u{25b}', ['\u{190}', '\u{0}', '\u{0}']), ('\u{25c}', ['\u{a7ab}', '\u{0}', '\u{0}']), + ('\u{260}', ['\u{193}', '\u{0}', '\u{0}']), ('\u{261}', ['\u{a7ac}', '\u{0}', '\u{0}']), + ('\u{263}', ['\u{194}', '\u{0}', '\u{0}']), ('\u{265}', ['\u{a78d}', '\u{0}', '\u{0}']), + ('\u{266}', ['\u{a7aa}', '\u{0}', '\u{0}']), ('\u{268}', ['\u{197}', '\u{0}', '\u{0}']), + ('\u{269}', ['\u{196}', '\u{0}', '\u{0}']), ('\u{26a}', ['\u{a7ae}', '\u{0}', '\u{0}']), + ('\u{26b}', ['\u{2c62}', '\u{0}', '\u{0}']), ('\u{26c}', ['\u{a7ad}', '\u{0}', '\u{0}']), + ('\u{26f}', ['\u{19c}', '\u{0}', '\u{0}']), ('\u{271}', ['\u{2c6e}', '\u{0}', '\u{0}']), + ('\u{272}', ['\u{19d}', '\u{0}', '\u{0}']), ('\u{275}', ['\u{19f}', '\u{0}', '\u{0}']), + ('\u{27d}', ['\u{2c64}', '\u{0}', '\u{0}']), ('\u{280}', ['\u{1a6}', '\u{0}', '\u{0}']), + ('\u{282}', ['\u{a7c5}', '\u{0}', '\u{0}']), ('\u{283}', ['\u{1a9}', '\u{0}', '\u{0}']), + ('\u{287}', ['\u{a7b1}', '\u{0}', '\u{0}']), ('\u{288}', ['\u{1ae}', '\u{0}', '\u{0}']), + ('\u{289}', ['\u{244}', '\u{0}', '\u{0}']), ('\u{28a}', ['\u{1b1}', '\u{0}', '\u{0}']), + ('\u{28b}', ['\u{1b2}', '\u{0}', '\u{0}']), ('\u{28c}', ['\u{245}', '\u{0}', '\u{0}']), + ('\u{292}', ['\u{1b7}', '\u{0}', '\u{0}']), ('\u{29d}', ['\u{a7b2}', '\u{0}', '\u{0}']), + ('\u{29e}', ['\u{a7b0}', '\u{0}', '\u{0}']), ('\u{345}', ['\u{399}', '\u{0}', '\u{0}']), + ('\u{371}', ['\u{370}', '\u{0}', '\u{0}']), ('\u{373}', ['\u{372}', '\u{0}', '\u{0}']), + ('\u{377}', ['\u{376}', '\u{0}', '\u{0}']), ('\u{37b}', ['\u{3fd}', '\u{0}', '\u{0}']), + ('\u{37c}', ['\u{3fe}', '\u{0}', '\u{0}']), ('\u{37d}', ['\u{3ff}', '\u{0}', '\u{0}']), + ('\u{390}', ['\u{399}', '\u{308}', '\u{301}']), ('\u{3ac}', ['\u{386}', '\u{0}', '\u{0}']), + ('\u{3ad}', ['\u{388}', '\u{0}', '\u{0}']), ('\u{3ae}', ['\u{389}', '\u{0}', '\u{0}']), + ('\u{3af}', ['\u{38a}', '\u{0}', '\u{0}']), ('\u{3b0}', ['\u{3a5}', '\u{308}', '\u{301}']), + ('\u{3b1}', ['\u{391}', '\u{0}', '\u{0}']), ('\u{3b2}', ['\u{392}', '\u{0}', '\u{0}']), + ('\u{3b3}', ['\u{393}', '\u{0}', '\u{0}']), ('\u{3b4}', ['\u{394}', '\u{0}', '\u{0}']), + ('\u{3b5}', ['\u{395}', '\u{0}', '\u{0}']), ('\u{3b6}', ['\u{396}', '\u{0}', '\u{0}']), + ('\u{3b7}', ['\u{397}', '\u{0}', '\u{0}']), ('\u{3b8}', ['\u{398}', '\u{0}', '\u{0}']), + ('\u{3b9}', ['\u{399}', '\u{0}', '\u{0}']), ('\u{3ba}', ['\u{39a}', '\u{0}', '\u{0}']), + ('\u{3bb}', ['\u{39b}', '\u{0}', '\u{0}']), ('\u{3bc}', ['\u{39c}', '\u{0}', '\u{0}']), + ('\u{3bd}', ['\u{39d}', '\u{0}', '\u{0}']), ('\u{3be}', ['\u{39e}', '\u{0}', '\u{0}']), + ('\u{3bf}', ['\u{39f}', '\u{0}', '\u{0}']), ('\u{3c0}', ['\u{3a0}', '\u{0}', '\u{0}']), + ('\u{3c1}', ['\u{3a1}', '\u{0}', '\u{0}']), ('\u{3c2}', ['\u{3a3}', '\u{0}', '\u{0}']), + ('\u{3c3}', ['\u{3a3}', '\u{0}', '\u{0}']), ('\u{3c4}', ['\u{3a4}', '\u{0}', '\u{0}']), + ('\u{3c5}', ['\u{3a5}', '\u{0}', '\u{0}']), ('\u{3c6}', ['\u{3a6}', '\u{0}', '\u{0}']), + ('\u{3c7}', ['\u{3a7}', '\u{0}', '\u{0}']), ('\u{3c8}', ['\u{3a8}', '\u{0}', '\u{0}']), + ('\u{3c9}', ['\u{3a9}', '\u{0}', '\u{0}']), ('\u{3ca}', ['\u{3aa}', '\u{0}', '\u{0}']), + ('\u{3cb}', ['\u{3ab}', '\u{0}', '\u{0}']), ('\u{3cc}', ['\u{38c}', '\u{0}', '\u{0}']), + ('\u{3cd}', ['\u{38e}', '\u{0}', '\u{0}']), ('\u{3ce}', ['\u{38f}', '\u{0}', '\u{0}']), + ('\u{3d0}', ['\u{392}', '\u{0}', '\u{0}']), ('\u{3d1}', ['\u{398}', '\u{0}', '\u{0}']), + ('\u{3d5}', ['\u{3a6}', '\u{0}', '\u{0}']), ('\u{3d6}', ['\u{3a0}', '\u{0}', '\u{0}']), + ('\u{3d7}', ['\u{3cf}', '\u{0}', '\u{0}']), ('\u{3d9}', ['\u{3d8}', '\u{0}', '\u{0}']), + ('\u{3db}', ['\u{3da}', '\u{0}', '\u{0}']), ('\u{3dd}', ['\u{3dc}', '\u{0}', '\u{0}']), + ('\u{3df}', ['\u{3de}', '\u{0}', '\u{0}']), ('\u{3e1}', ['\u{3e0}', '\u{0}', '\u{0}']), + ('\u{3e3}', ['\u{3e2}', '\u{0}', '\u{0}']), ('\u{3e5}', ['\u{3e4}', '\u{0}', '\u{0}']), + ('\u{3e7}', ['\u{3e6}', '\u{0}', '\u{0}']), ('\u{3e9}', ['\u{3e8}', '\u{0}', '\u{0}']), + ('\u{3eb}', ['\u{3ea}', '\u{0}', '\u{0}']), ('\u{3ed}', ['\u{3ec}', '\u{0}', '\u{0}']), + ('\u{3ef}', ['\u{3ee}', '\u{0}', '\u{0}']), ('\u{3f0}', ['\u{39a}', '\u{0}', '\u{0}']), + ('\u{3f1}', ['\u{3a1}', '\u{0}', '\u{0}']), ('\u{3f2}', ['\u{3f9}', '\u{0}', '\u{0}']), + ('\u{3f3}', ['\u{37f}', '\u{0}', '\u{0}']), ('\u{3f5}', ['\u{395}', '\u{0}', '\u{0}']), + ('\u{3f8}', ['\u{3f7}', '\u{0}', '\u{0}']), ('\u{3fb}', ['\u{3fa}', '\u{0}', '\u{0}']), + ('\u{430}', ['\u{410}', '\u{0}', '\u{0}']), ('\u{431}', ['\u{411}', '\u{0}', '\u{0}']), + ('\u{432}', ['\u{412}', '\u{0}', '\u{0}']), ('\u{433}', ['\u{413}', '\u{0}', '\u{0}']), + ('\u{434}', ['\u{414}', '\u{0}', '\u{0}']), ('\u{435}', ['\u{415}', '\u{0}', '\u{0}']), + ('\u{436}', ['\u{416}', '\u{0}', '\u{0}']), ('\u{437}', ['\u{417}', '\u{0}', '\u{0}']), + ('\u{438}', ['\u{418}', '\u{0}', '\u{0}']), ('\u{439}', ['\u{419}', '\u{0}', '\u{0}']), + ('\u{43a}', ['\u{41a}', '\u{0}', '\u{0}']), ('\u{43b}', ['\u{41b}', '\u{0}', '\u{0}']), + ('\u{43c}', ['\u{41c}', '\u{0}', '\u{0}']), ('\u{43d}', ['\u{41d}', '\u{0}', '\u{0}']), + ('\u{43e}', ['\u{41e}', '\u{0}', '\u{0}']), ('\u{43f}', ['\u{41f}', '\u{0}', '\u{0}']), + ('\u{440}', ['\u{420}', '\u{0}', '\u{0}']), ('\u{441}', ['\u{421}', '\u{0}', '\u{0}']), + ('\u{442}', ['\u{422}', '\u{0}', '\u{0}']), ('\u{443}', ['\u{423}', '\u{0}', '\u{0}']), + ('\u{444}', ['\u{424}', '\u{0}', '\u{0}']), ('\u{445}', ['\u{425}', '\u{0}', '\u{0}']), + ('\u{446}', ['\u{426}', '\u{0}', '\u{0}']), ('\u{447}', ['\u{427}', '\u{0}', '\u{0}']), + ('\u{448}', ['\u{428}', '\u{0}', '\u{0}']), ('\u{449}', ['\u{429}', '\u{0}', '\u{0}']), + ('\u{44a}', ['\u{42a}', '\u{0}', '\u{0}']), ('\u{44b}', ['\u{42b}', '\u{0}', '\u{0}']), + ('\u{44c}', ['\u{42c}', '\u{0}', '\u{0}']), ('\u{44d}', ['\u{42d}', '\u{0}', '\u{0}']), + ('\u{44e}', ['\u{42e}', '\u{0}', '\u{0}']), ('\u{44f}', ['\u{42f}', '\u{0}', '\u{0}']), + ('\u{450}', ['\u{400}', '\u{0}', '\u{0}']), ('\u{451}', ['\u{401}', '\u{0}', '\u{0}']), + ('\u{452}', ['\u{402}', '\u{0}', '\u{0}']), ('\u{453}', ['\u{403}', '\u{0}', '\u{0}']), + ('\u{454}', ['\u{404}', '\u{0}', '\u{0}']), ('\u{455}', ['\u{405}', '\u{0}', '\u{0}']), + ('\u{456}', ['\u{406}', '\u{0}', '\u{0}']), ('\u{457}', ['\u{407}', '\u{0}', '\u{0}']), + ('\u{458}', ['\u{408}', '\u{0}', '\u{0}']), ('\u{459}', ['\u{409}', '\u{0}', '\u{0}']), + ('\u{45a}', ['\u{40a}', '\u{0}', '\u{0}']), ('\u{45b}', ['\u{40b}', '\u{0}', '\u{0}']), + ('\u{45c}', ['\u{40c}', '\u{0}', '\u{0}']), ('\u{45d}', ['\u{40d}', '\u{0}', '\u{0}']), + ('\u{45e}', ['\u{40e}', '\u{0}', '\u{0}']), ('\u{45f}', ['\u{40f}', '\u{0}', '\u{0}']), + ('\u{461}', ['\u{460}', '\u{0}', '\u{0}']), ('\u{463}', ['\u{462}', '\u{0}', '\u{0}']), + ('\u{465}', ['\u{464}', '\u{0}', '\u{0}']), ('\u{467}', ['\u{466}', '\u{0}', '\u{0}']), + ('\u{469}', ['\u{468}', '\u{0}', '\u{0}']), ('\u{46b}', ['\u{46a}', '\u{0}', '\u{0}']), + ('\u{46d}', ['\u{46c}', '\u{0}', '\u{0}']), ('\u{46f}', ['\u{46e}', '\u{0}', '\u{0}']), + ('\u{471}', ['\u{470}', '\u{0}', '\u{0}']), ('\u{473}', ['\u{472}', '\u{0}', '\u{0}']), + ('\u{475}', ['\u{474}', '\u{0}', '\u{0}']), ('\u{477}', ['\u{476}', '\u{0}', '\u{0}']), + ('\u{479}', ['\u{478}', '\u{0}', '\u{0}']), ('\u{47b}', ['\u{47a}', '\u{0}', '\u{0}']), + ('\u{47d}', ['\u{47c}', '\u{0}', '\u{0}']), ('\u{47f}', ['\u{47e}', '\u{0}', '\u{0}']), + ('\u{481}', ['\u{480}', '\u{0}', '\u{0}']), ('\u{48b}', ['\u{48a}', '\u{0}', '\u{0}']), + ('\u{48d}', ['\u{48c}', '\u{0}', '\u{0}']), ('\u{48f}', ['\u{48e}', '\u{0}', '\u{0}']), + ('\u{491}', ['\u{490}', '\u{0}', '\u{0}']), ('\u{493}', ['\u{492}', '\u{0}', '\u{0}']), + ('\u{495}', ['\u{494}', '\u{0}', '\u{0}']), ('\u{497}', ['\u{496}', '\u{0}', '\u{0}']), + ('\u{499}', ['\u{498}', '\u{0}', '\u{0}']), ('\u{49b}', ['\u{49a}', '\u{0}', '\u{0}']), + ('\u{49d}', ['\u{49c}', '\u{0}', '\u{0}']), ('\u{49f}', ['\u{49e}', '\u{0}', '\u{0}']), + ('\u{4a1}', ['\u{4a0}', '\u{0}', '\u{0}']), ('\u{4a3}', ['\u{4a2}', '\u{0}', '\u{0}']), + ('\u{4a5}', ['\u{4a4}', '\u{0}', '\u{0}']), ('\u{4a7}', ['\u{4a6}', '\u{0}', '\u{0}']), + ('\u{4a9}', ['\u{4a8}', '\u{0}', '\u{0}']), ('\u{4ab}', ['\u{4aa}', '\u{0}', '\u{0}']), + ('\u{4ad}', ['\u{4ac}', '\u{0}', '\u{0}']), ('\u{4af}', ['\u{4ae}', '\u{0}', '\u{0}']), + ('\u{4b1}', ['\u{4b0}', '\u{0}', '\u{0}']), ('\u{4b3}', ['\u{4b2}', '\u{0}', '\u{0}']), + ('\u{4b5}', ['\u{4b4}', '\u{0}', '\u{0}']), ('\u{4b7}', ['\u{4b6}', '\u{0}', '\u{0}']), + ('\u{4b9}', ['\u{4b8}', '\u{0}', '\u{0}']), ('\u{4bb}', ['\u{4ba}', '\u{0}', '\u{0}']), + ('\u{4bd}', ['\u{4bc}', '\u{0}', '\u{0}']), ('\u{4bf}', ['\u{4be}', '\u{0}', '\u{0}']), + ('\u{4c2}', ['\u{4c1}', '\u{0}', '\u{0}']), ('\u{4c4}', ['\u{4c3}', '\u{0}', '\u{0}']), + ('\u{4c6}', ['\u{4c5}', '\u{0}', '\u{0}']), ('\u{4c8}', ['\u{4c7}', '\u{0}', '\u{0}']), + ('\u{4ca}', ['\u{4c9}', '\u{0}', '\u{0}']), ('\u{4cc}', ['\u{4cb}', '\u{0}', '\u{0}']), + ('\u{4ce}', ['\u{4cd}', '\u{0}', '\u{0}']), ('\u{4cf}', ['\u{4c0}', '\u{0}', '\u{0}']), + ('\u{4d1}', ['\u{4d0}', '\u{0}', '\u{0}']), ('\u{4d3}', ['\u{4d2}', '\u{0}', '\u{0}']), + ('\u{4d5}', ['\u{4d4}', '\u{0}', '\u{0}']), ('\u{4d7}', ['\u{4d6}', '\u{0}', '\u{0}']), + ('\u{4d9}', ['\u{4d8}', '\u{0}', '\u{0}']), ('\u{4db}', ['\u{4da}', '\u{0}', '\u{0}']), + ('\u{4dd}', ['\u{4dc}', '\u{0}', '\u{0}']), ('\u{4df}', ['\u{4de}', '\u{0}', '\u{0}']), + ('\u{4e1}', ['\u{4e0}', '\u{0}', '\u{0}']), ('\u{4e3}', ['\u{4e2}', '\u{0}', '\u{0}']), + ('\u{4e5}', ['\u{4e4}', '\u{0}', '\u{0}']), ('\u{4e7}', ['\u{4e6}', '\u{0}', '\u{0}']), + ('\u{4e9}', ['\u{4e8}', '\u{0}', '\u{0}']), ('\u{4eb}', ['\u{4ea}', '\u{0}', '\u{0}']), + ('\u{4ed}', ['\u{4ec}', '\u{0}', '\u{0}']), ('\u{4ef}', ['\u{4ee}', '\u{0}', '\u{0}']), + ('\u{4f1}', ['\u{4f0}', '\u{0}', '\u{0}']), ('\u{4f3}', ['\u{4f2}', '\u{0}', '\u{0}']), + ('\u{4f5}', ['\u{4f4}', '\u{0}', '\u{0}']), ('\u{4f7}', ['\u{4f6}', '\u{0}', '\u{0}']), + ('\u{4f9}', ['\u{4f8}', '\u{0}', '\u{0}']), ('\u{4fb}', ['\u{4fa}', '\u{0}', '\u{0}']), + ('\u{4fd}', ['\u{4fc}', '\u{0}', '\u{0}']), ('\u{4ff}', ['\u{4fe}', '\u{0}', '\u{0}']), + ('\u{501}', ['\u{500}', '\u{0}', '\u{0}']), ('\u{503}', ['\u{502}', '\u{0}', '\u{0}']), + ('\u{505}', ['\u{504}', '\u{0}', '\u{0}']), ('\u{507}', ['\u{506}', '\u{0}', '\u{0}']), + ('\u{509}', ['\u{508}', '\u{0}', '\u{0}']), ('\u{50b}', ['\u{50a}', '\u{0}', '\u{0}']), + ('\u{50d}', ['\u{50c}', '\u{0}', '\u{0}']), ('\u{50f}', ['\u{50e}', '\u{0}', '\u{0}']), + ('\u{511}', ['\u{510}', '\u{0}', '\u{0}']), ('\u{513}', ['\u{512}', '\u{0}', '\u{0}']), + ('\u{515}', ['\u{514}', '\u{0}', '\u{0}']), ('\u{517}', ['\u{516}', '\u{0}', '\u{0}']), + ('\u{519}', ['\u{518}', '\u{0}', '\u{0}']), ('\u{51b}', ['\u{51a}', '\u{0}', '\u{0}']), + ('\u{51d}', ['\u{51c}', '\u{0}', '\u{0}']), ('\u{51f}', ['\u{51e}', '\u{0}', '\u{0}']), + ('\u{521}', ['\u{520}', '\u{0}', '\u{0}']), ('\u{523}', ['\u{522}', '\u{0}', '\u{0}']), + ('\u{525}', ['\u{524}', '\u{0}', '\u{0}']), ('\u{527}', ['\u{526}', '\u{0}', '\u{0}']), + ('\u{529}', ['\u{528}', '\u{0}', '\u{0}']), ('\u{52b}', ['\u{52a}', '\u{0}', '\u{0}']), + ('\u{52d}', ['\u{52c}', '\u{0}', '\u{0}']), ('\u{52f}', ['\u{52e}', '\u{0}', '\u{0}']), + ('\u{561}', ['\u{531}', '\u{0}', '\u{0}']), ('\u{562}', ['\u{532}', '\u{0}', '\u{0}']), + ('\u{563}', ['\u{533}', '\u{0}', '\u{0}']), ('\u{564}', ['\u{534}', '\u{0}', '\u{0}']), + ('\u{565}', ['\u{535}', '\u{0}', '\u{0}']), ('\u{566}', ['\u{536}', '\u{0}', '\u{0}']), + ('\u{567}', ['\u{537}', '\u{0}', '\u{0}']), ('\u{568}', ['\u{538}', '\u{0}', '\u{0}']), + ('\u{569}', ['\u{539}', '\u{0}', '\u{0}']), ('\u{56a}', ['\u{53a}', '\u{0}', '\u{0}']), + ('\u{56b}', ['\u{53b}', '\u{0}', '\u{0}']), ('\u{56c}', ['\u{53c}', '\u{0}', '\u{0}']), + ('\u{56d}', ['\u{53d}', '\u{0}', '\u{0}']), ('\u{56e}', ['\u{53e}', '\u{0}', '\u{0}']), + ('\u{56f}', ['\u{53f}', '\u{0}', '\u{0}']), ('\u{570}', ['\u{540}', '\u{0}', '\u{0}']), + ('\u{571}', ['\u{541}', '\u{0}', '\u{0}']), ('\u{572}', ['\u{542}', '\u{0}', '\u{0}']), + ('\u{573}', ['\u{543}', '\u{0}', '\u{0}']), ('\u{574}', ['\u{544}', '\u{0}', '\u{0}']), + ('\u{575}', ['\u{545}', '\u{0}', '\u{0}']), ('\u{576}', ['\u{546}', '\u{0}', '\u{0}']), + ('\u{577}', ['\u{547}', '\u{0}', '\u{0}']), ('\u{578}', ['\u{548}', '\u{0}', '\u{0}']), + ('\u{579}', ['\u{549}', '\u{0}', '\u{0}']), ('\u{57a}', ['\u{54a}', '\u{0}', '\u{0}']), + ('\u{57b}', ['\u{54b}', '\u{0}', '\u{0}']), ('\u{57c}', ['\u{54c}', '\u{0}', '\u{0}']), + ('\u{57d}', ['\u{54d}', '\u{0}', '\u{0}']), ('\u{57e}', ['\u{54e}', '\u{0}', '\u{0}']), + ('\u{57f}', ['\u{54f}', '\u{0}', '\u{0}']), ('\u{580}', ['\u{550}', '\u{0}', '\u{0}']), + ('\u{581}', ['\u{551}', '\u{0}', '\u{0}']), ('\u{582}', ['\u{552}', '\u{0}', '\u{0}']), + ('\u{583}', ['\u{553}', '\u{0}', '\u{0}']), ('\u{584}', ['\u{554}', '\u{0}', '\u{0}']), + ('\u{585}', ['\u{555}', '\u{0}', '\u{0}']), ('\u{586}', ['\u{556}', '\u{0}', '\u{0}']), + ('\u{587}', ['\u{535}', '\u{552}', '\u{0}']), ('\u{10d0}', ['\u{1c90}', '\u{0}', '\u{0}']), + ('\u{10d1}', ['\u{1c91}', '\u{0}', '\u{0}']), ('\u{10d2}', ['\u{1c92}', '\u{0}', '\u{0}']), + ('\u{10d3}', ['\u{1c93}', '\u{0}', '\u{0}']), ('\u{10d4}', ['\u{1c94}', '\u{0}', '\u{0}']), + ('\u{10d5}', ['\u{1c95}', '\u{0}', '\u{0}']), ('\u{10d6}', ['\u{1c96}', '\u{0}', '\u{0}']), + ('\u{10d7}', ['\u{1c97}', '\u{0}', '\u{0}']), ('\u{10d8}', ['\u{1c98}', '\u{0}', '\u{0}']), + ('\u{10d9}', ['\u{1c99}', '\u{0}', '\u{0}']), ('\u{10da}', ['\u{1c9a}', '\u{0}', '\u{0}']), + ('\u{10db}', ['\u{1c9b}', '\u{0}', '\u{0}']), ('\u{10dc}', ['\u{1c9c}', '\u{0}', '\u{0}']), + ('\u{10dd}', ['\u{1c9d}', '\u{0}', '\u{0}']), ('\u{10de}', ['\u{1c9e}', '\u{0}', '\u{0}']), + ('\u{10df}', ['\u{1c9f}', '\u{0}', '\u{0}']), ('\u{10e0}', ['\u{1ca0}', '\u{0}', '\u{0}']), + ('\u{10e1}', ['\u{1ca1}', '\u{0}', '\u{0}']), ('\u{10e2}', ['\u{1ca2}', '\u{0}', '\u{0}']), + ('\u{10e3}', ['\u{1ca3}', '\u{0}', '\u{0}']), ('\u{10e4}', ['\u{1ca4}', '\u{0}', '\u{0}']), + ('\u{10e5}', ['\u{1ca5}', '\u{0}', '\u{0}']), ('\u{10e6}', ['\u{1ca6}', '\u{0}', '\u{0}']), + ('\u{10e7}', ['\u{1ca7}', '\u{0}', '\u{0}']), ('\u{10e8}', ['\u{1ca8}', '\u{0}', '\u{0}']), + ('\u{10e9}', ['\u{1ca9}', '\u{0}', '\u{0}']), ('\u{10ea}', ['\u{1caa}', '\u{0}', '\u{0}']), + ('\u{10eb}', ['\u{1cab}', '\u{0}', '\u{0}']), ('\u{10ec}', ['\u{1cac}', '\u{0}', '\u{0}']), + ('\u{10ed}', ['\u{1cad}', '\u{0}', '\u{0}']), ('\u{10ee}', ['\u{1cae}', '\u{0}', '\u{0}']), + ('\u{10ef}', ['\u{1caf}', '\u{0}', '\u{0}']), ('\u{10f0}', ['\u{1cb0}', '\u{0}', '\u{0}']), + ('\u{10f1}', ['\u{1cb1}', '\u{0}', '\u{0}']), ('\u{10f2}', ['\u{1cb2}', '\u{0}', '\u{0}']), + ('\u{10f3}', ['\u{1cb3}', '\u{0}', '\u{0}']), ('\u{10f4}', ['\u{1cb4}', '\u{0}', '\u{0}']), + ('\u{10f5}', ['\u{1cb5}', '\u{0}', '\u{0}']), ('\u{10f6}', ['\u{1cb6}', '\u{0}', '\u{0}']), + ('\u{10f7}', ['\u{1cb7}', '\u{0}', '\u{0}']), ('\u{10f8}', ['\u{1cb8}', '\u{0}', '\u{0}']), + ('\u{10f9}', ['\u{1cb9}', '\u{0}', '\u{0}']), ('\u{10fa}', ['\u{1cba}', '\u{0}', '\u{0}']), + ('\u{10fd}', ['\u{1cbd}', '\u{0}', '\u{0}']), ('\u{10fe}', ['\u{1cbe}', '\u{0}', '\u{0}']), + ('\u{10ff}', ['\u{1cbf}', '\u{0}', '\u{0}']), ('\u{13f8}', ['\u{13f0}', '\u{0}', '\u{0}']), + ('\u{13f9}', ['\u{13f1}', '\u{0}', '\u{0}']), ('\u{13fa}', ['\u{13f2}', '\u{0}', '\u{0}']), + ('\u{13fb}', ['\u{13f3}', '\u{0}', '\u{0}']), ('\u{13fc}', ['\u{13f4}', '\u{0}', '\u{0}']), + ('\u{13fd}', ['\u{13f5}', '\u{0}', '\u{0}']), ('\u{1c80}', ['\u{412}', '\u{0}', '\u{0}']), + ('\u{1c81}', ['\u{414}', '\u{0}', '\u{0}']), ('\u{1c82}', ['\u{41e}', '\u{0}', '\u{0}']), + ('\u{1c83}', ['\u{421}', '\u{0}', '\u{0}']), ('\u{1c84}', ['\u{422}', '\u{0}', '\u{0}']), + ('\u{1c85}', ['\u{422}', '\u{0}', '\u{0}']), ('\u{1c86}', ['\u{42a}', '\u{0}', '\u{0}']), + ('\u{1c87}', ['\u{462}', '\u{0}', '\u{0}']), ('\u{1c88}', ['\u{a64a}', '\u{0}', '\u{0}']), + ('\u{1d79}', ['\u{a77d}', '\u{0}', '\u{0}']), ('\u{1d7d}', ['\u{2c63}', '\u{0}', '\u{0}']), + ('\u{1d8e}', ['\u{a7c6}', '\u{0}', '\u{0}']), ('\u{1e01}', ['\u{1e00}', '\u{0}', '\u{0}']), + ('\u{1e03}', ['\u{1e02}', '\u{0}', '\u{0}']), ('\u{1e05}', ['\u{1e04}', '\u{0}', '\u{0}']), + ('\u{1e07}', ['\u{1e06}', '\u{0}', '\u{0}']), ('\u{1e09}', ['\u{1e08}', '\u{0}', '\u{0}']), + ('\u{1e0b}', ['\u{1e0a}', '\u{0}', '\u{0}']), ('\u{1e0d}', ['\u{1e0c}', '\u{0}', '\u{0}']), + ('\u{1e0f}', ['\u{1e0e}', '\u{0}', '\u{0}']), ('\u{1e11}', ['\u{1e10}', '\u{0}', '\u{0}']), + ('\u{1e13}', ['\u{1e12}', '\u{0}', '\u{0}']), ('\u{1e15}', ['\u{1e14}', '\u{0}', '\u{0}']), + ('\u{1e17}', ['\u{1e16}', '\u{0}', '\u{0}']), ('\u{1e19}', ['\u{1e18}', '\u{0}', '\u{0}']), + ('\u{1e1b}', ['\u{1e1a}', '\u{0}', '\u{0}']), ('\u{1e1d}', ['\u{1e1c}', '\u{0}', '\u{0}']), + ('\u{1e1f}', ['\u{1e1e}', '\u{0}', '\u{0}']), ('\u{1e21}', ['\u{1e20}', '\u{0}', '\u{0}']), + ('\u{1e23}', ['\u{1e22}', '\u{0}', '\u{0}']), ('\u{1e25}', ['\u{1e24}', '\u{0}', '\u{0}']), + ('\u{1e27}', ['\u{1e26}', '\u{0}', '\u{0}']), ('\u{1e29}', ['\u{1e28}', '\u{0}', '\u{0}']), + ('\u{1e2b}', ['\u{1e2a}', '\u{0}', '\u{0}']), ('\u{1e2d}', ['\u{1e2c}', '\u{0}', '\u{0}']), + ('\u{1e2f}', ['\u{1e2e}', '\u{0}', '\u{0}']), ('\u{1e31}', ['\u{1e30}', '\u{0}', '\u{0}']), + ('\u{1e33}', ['\u{1e32}', '\u{0}', '\u{0}']), ('\u{1e35}', ['\u{1e34}', '\u{0}', '\u{0}']), + ('\u{1e37}', ['\u{1e36}', '\u{0}', '\u{0}']), ('\u{1e39}', ['\u{1e38}', '\u{0}', '\u{0}']), + ('\u{1e3b}', ['\u{1e3a}', '\u{0}', '\u{0}']), ('\u{1e3d}', ['\u{1e3c}', '\u{0}', '\u{0}']), + ('\u{1e3f}', ['\u{1e3e}', '\u{0}', '\u{0}']), ('\u{1e41}', ['\u{1e40}', '\u{0}', '\u{0}']), + ('\u{1e43}', ['\u{1e42}', '\u{0}', '\u{0}']), ('\u{1e45}', ['\u{1e44}', '\u{0}', '\u{0}']), + ('\u{1e47}', ['\u{1e46}', '\u{0}', '\u{0}']), ('\u{1e49}', ['\u{1e48}', '\u{0}', '\u{0}']), + ('\u{1e4b}', ['\u{1e4a}', '\u{0}', '\u{0}']), ('\u{1e4d}', ['\u{1e4c}', '\u{0}', '\u{0}']), + ('\u{1e4f}', ['\u{1e4e}', '\u{0}', '\u{0}']), ('\u{1e51}', ['\u{1e50}', '\u{0}', '\u{0}']), + ('\u{1e53}', ['\u{1e52}', '\u{0}', '\u{0}']), ('\u{1e55}', ['\u{1e54}', '\u{0}', '\u{0}']), + ('\u{1e57}', ['\u{1e56}', '\u{0}', '\u{0}']), ('\u{1e59}', ['\u{1e58}', '\u{0}', '\u{0}']), + ('\u{1e5b}', ['\u{1e5a}', '\u{0}', '\u{0}']), ('\u{1e5d}', ['\u{1e5c}', '\u{0}', '\u{0}']), + ('\u{1e5f}', ['\u{1e5e}', '\u{0}', '\u{0}']), ('\u{1e61}', ['\u{1e60}', '\u{0}', '\u{0}']), + ('\u{1e63}', ['\u{1e62}', '\u{0}', '\u{0}']), ('\u{1e65}', ['\u{1e64}', '\u{0}', '\u{0}']), + ('\u{1e67}', ['\u{1e66}', '\u{0}', '\u{0}']), ('\u{1e69}', ['\u{1e68}', '\u{0}', '\u{0}']), + ('\u{1e6b}', ['\u{1e6a}', '\u{0}', '\u{0}']), ('\u{1e6d}', ['\u{1e6c}', '\u{0}', '\u{0}']), + ('\u{1e6f}', ['\u{1e6e}', '\u{0}', '\u{0}']), ('\u{1e71}', ['\u{1e70}', '\u{0}', '\u{0}']), + ('\u{1e73}', ['\u{1e72}', '\u{0}', '\u{0}']), ('\u{1e75}', ['\u{1e74}', '\u{0}', '\u{0}']), + ('\u{1e77}', ['\u{1e76}', '\u{0}', '\u{0}']), ('\u{1e79}', ['\u{1e78}', '\u{0}', '\u{0}']), + ('\u{1e7b}', ['\u{1e7a}', '\u{0}', '\u{0}']), ('\u{1e7d}', ['\u{1e7c}', '\u{0}', '\u{0}']), + ('\u{1e7f}', ['\u{1e7e}', '\u{0}', '\u{0}']), ('\u{1e81}', ['\u{1e80}', '\u{0}', '\u{0}']), + ('\u{1e83}', ['\u{1e82}', '\u{0}', '\u{0}']), ('\u{1e85}', ['\u{1e84}', '\u{0}', '\u{0}']), + ('\u{1e87}', ['\u{1e86}', '\u{0}', '\u{0}']), ('\u{1e89}', ['\u{1e88}', '\u{0}', '\u{0}']), + ('\u{1e8b}', ['\u{1e8a}', '\u{0}', '\u{0}']), ('\u{1e8d}', ['\u{1e8c}', '\u{0}', '\u{0}']), + ('\u{1e8f}', ['\u{1e8e}', '\u{0}', '\u{0}']), ('\u{1e91}', ['\u{1e90}', '\u{0}', '\u{0}']), + ('\u{1e93}', ['\u{1e92}', '\u{0}', '\u{0}']), ('\u{1e95}', ['\u{1e94}', '\u{0}', '\u{0}']), + ('\u{1e96}', ['H', '\u{331}', '\u{0}']), ('\u{1e97}', ['T', '\u{308}', '\u{0}']), + ('\u{1e98}', ['W', '\u{30a}', '\u{0}']), ('\u{1e99}', ['Y', '\u{30a}', '\u{0}']), + ('\u{1e9a}', ['A', '\u{2be}', '\u{0}']), ('\u{1e9b}', ['\u{1e60}', '\u{0}', '\u{0}']), + ('\u{1ea1}', ['\u{1ea0}', '\u{0}', '\u{0}']), ('\u{1ea3}', ['\u{1ea2}', '\u{0}', '\u{0}']), + ('\u{1ea5}', ['\u{1ea4}', '\u{0}', '\u{0}']), ('\u{1ea7}', ['\u{1ea6}', '\u{0}', '\u{0}']), + ('\u{1ea9}', ['\u{1ea8}', '\u{0}', '\u{0}']), ('\u{1eab}', ['\u{1eaa}', '\u{0}', '\u{0}']), + ('\u{1ead}', ['\u{1eac}', '\u{0}', '\u{0}']), ('\u{1eaf}', ['\u{1eae}', '\u{0}', '\u{0}']), + ('\u{1eb1}', ['\u{1eb0}', '\u{0}', '\u{0}']), ('\u{1eb3}', ['\u{1eb2}', '\u{0}', '\u{0}']), + ('\u{1eb5}', ['\u{1eb4}', '\u{0}', '\u{0}']), ('\u{1eb7}', ['\u{1eb6}', '\u{0}', '\u{0}']), + ('\u{1eb9}', ['\u{1eb8}', '\u{0}', '\u{0}']), ('\u{1ebb}', ['\u{1eba}', '\u{0}', '\u{0}']), + ('\u{1ebd}', ['\u{1ebc}', '\u{0}', '\u{0}']), ('\u{1ebf}', ['\u{1ebe}', '\u{0}', '\u{0}']), + ('\u{1ec1}', ['\u{1ec0}', '\u{0}', '\u{0}']), ('\u{1ec3}', ['\u{1ec2}', '\u{0}', '\u{0}']), + ('\u{1ec5}', ['\u{1ec4}', '\u{0}', '\u{0}']), ('\u{1ec7}', ['\u{1ec6}', '\u{0}', '\u{0}']), + ('\u{1ec9}', ['\u{1ec8}', '\u{0}', '\u{0}']), ('\u{1ecb}', ['\u{1eca}', '\u{0}', '\u{0}']), + ('\u{1ecd}', ['\u{1ecc}', '\u{0}', '\u{0}']), ('\u{1ecf}', ['\u{1ece}', '\u{0}', '\u{0}']), + ('\u{1ed1}', ['\u{1ed0}', '\u{0}', '\u{0}']), ('\u{1ed3}', ['\u{1ed2}', '\u{0}', '\u{0}']), + ('\u{1ed5}', ['\u{1ed4}', '\u{0}', '\u{0}']), ('\u{1ed7}', ['\u{1ed6}', '\u{0}', '\u{0}']), + ('\u{1ed9}', ['\u{1ed8}', '\u{0}', '\u{0}']), ('\u{1edb}', ['\u{1eda}', '\u{0}', '\u{0}']), + ('\u{1edd}', ['\u{1edc}', '\u{0}', '\u{0}']), ('\u{1edf}', ['\u{1ede}', '\u{0}', '\u{0}']), + ('\u{1ee1}', ['\u{1ee0}', '\u{0}', '\u{0}']), ('\u{1ee3}', ['\u{1ee2}', '\u{0}', '\u{0}']), + ('\u{1ee5}', ['\u{1ee4}', '\u{0}', '\u{0}']), ('\u{1ee7}', ['\u{1ee6}', '\u{0}', '\u{0}']), + ('\u{1ee9}', ['\u{1ee8}', '\u{0}', '\u{0}']), ('\u{1eeb}', ['\u{1eea}', '\u{0}', '\u{0}']), + ('\u{1eed}', ['\u{1eec}', '\u{0}', '\u{0}']), ('\u{1eef}', ['\u{1eee}', '\u{0}', '\u{0}']), + ('\u{1ef1}', ['\u{1ef0}', '\u{0}', '\u{0}']), ('\u{1ef3}', ['\u{1ef2}', '\u{0}', '\u{0}']), + ('\u{1ef5}', ['\u{1ef4}', '\u{0}', '\u{0}']), ('\u{1ef7}', ['\u{1ef6}', '\u{0}', '\u{0}']), + ('\u{1ef9}', ['\u{1ef8}', '\u{0}', '\u{0}']), ('\u{1efb}', ['\u{1efa}', '\u{0}', '\u{0}']), + ('\u{1efd}', ['\u{1efc}', '\u{0}', '\u{0}']), ('\u{1eff}', ['\u{1efe}', '\u{0}', '\u{0}']), + ('\u{1f00}', ['\u{1f08}', '\u{0}', '\u{0}']), ('\u{1f01}', ['\u{1f09}', '\u{0}', '\u{0}']), + ('\u{1f02}', ['\u{1f0a}', '\u{0}', '\u{0}']), ('\u{1f03}', ['\u{1f0b}', '\u{0}', '\u{0}']), + ('\u{1f04}', ['\u{1f0c}', '\u{0}', '\u{0}']), ('\u{1f05}', ['\u{1f0d}', '\u{0}', '\u{0}']), + ('\u{1f06}', ['\u{1f0e}', '\u{0}', '\u{0}']), ('\u{1f07}', ['\u{1f0f}', '\u{0}', '\u{0}']), + ('\u{1f10}', ['\u{1f18}', '\u{0}', '\u{0}']), ('\u{1f11}', ['\u{1f19}', '\u{0}', '\u{0}']), + ('\u{1f12}', ['\u{1f1a}', '\u{0}', '\u{0}']), ('\u{1f13}', ['\u{1f1b}', '\u{0}', '\u{0}']), + ('\u{1f14}', ['\u{1f1c}', '\u{0}', '\u{0}']), ('\u{1f15}', ['\u{1f1d}', '\u{0}', '\u{0}']), + ('\u{1f20}', ['\u{1f28}', '\u{0}', '\u{0}']), ('\u{1f21}', ['\u{1f29}', '\u{0}', '\u{0}']), + ('\u{1f22}', ['\u{1f2a}', '\u{0}', '\u{0}']), ('\u{1f23}', ['\u{1f2b}', '\u{0}', '\u{0}']), + ('\u{1f24}', ['\u{1f2c}', '\u{0}', '\u{0}']), ('\u{1f25}', ['\u{1f2d}', '\u{0}', '\u{0}']), + ('\u{1f26}', ['\u{1f2e}', '\u{0}', '\u{0}']), ('\u{1f27}', ['\u{1f2f}', '\u{0}', '\u{0}']), + ('\u{1f30}', ['\u{1f38}', '\u{0}', '\u{0}']), ('\u{1f31}', ['\u{1f39}', '\u{0}', '\u{0}']), + ('\u{1f32}', ['\u{1f3a}', '\u{0}', '\u{0}']), ('\u{1f33}', ['\u{1f3b}', '\u{0}', '\u{0}']), + ('\u{1f34}', ['\u{1f3c}', '\u{0}', '\u{0}']), ('\u{1f35}', ['\u{1f3d}', '\u{0}', '\u{0}']), + ('\u{1f36}', ['\u{1f3e}', '\u{0}', '\u{0}']), ('\u{1f37}', ['\u{1f3f}', '\u{0}', '\u{0}']), + ('\u{1f40}', ['\u{1f48}', '\u{0}', '\u{0}']), ('\u{1f41}', ['\u{1f49}', '\u{0}', '\u{0}']), + ('\u{1f42}', ['\u{1f4a}', '\u{0}', '\u{0}']), ('\u{1f43}', ['\u{1f4b}', '\u{0}', '\u{0}']), + ('\u{1f44}', ['\u{1f4c}', '\u{0}', '\u{0}']), ('\u{1f45}', ['\u{1f4d}', '\u{0}', '\u{0}']), + ('\u{1f50}', ['\u{3a5}', '\u{313}', '\u{0}']), ('\u{1f51}', ['\u{1f59}', '\u{0}', '\u{0}']), + ('\u{1f52}', ['\u{3a5}', '\u{313}', '\u{300}']), + ('\u{1f53}', ['\u{1f5b}', '\u{0}', '\u{0}']), + ('\u{1f54}', ['\u{3a5}', '\u{313}', '\u{301}']), + ('\u{1f55}', ['\u{1f5d}', '\u{0}', '\u{0}']), + ('\u{1f56}', ['\u{3a5}', '\u{313}', '\u{342}']), + ('\u{1f57}', ['\u{1f5f}', '\u{0}', '\u{0}']), ('\u{1f60}', ['\u{1f68}', '\u{0}', '\u{0}']), + ('\u{1f61}', ['\u{1f69}', '\u{0}', '\u{0}']), ('\u{1f62}', ['\u{1f6a}', '\u{0}', '\u{0}']), + ('\u{1f63}', ['\u{1f6b}', '\u{0}', '\u{0}']), ('\u{1f64}', ['\u{1f6c}', '\u{0}', '\u{0}']), + ('\u{1f65}', ['\u{1f6d}', '\u{0}', '\u{0}']), ('\u{1f66}', ['\u{1f6e}', '\u{0}', '\u{0}']), + ('\u{1f67}', ['\u{1f6f}', '\u{0}', '\u{0}']), ('\u{1f70}', ['\u{1fba}', '\u{0}', '\u{0}']), + ('\u{1f71}', ['\u{1fbb}', '\u{0}', '\u{0}']), ('\u{1f72}', ['\u{1fc8}', '\u{0}', '\u{0}']), + ('\u{1f73}', ['\u{1fc9}', '\u{0}', '\u{0}']), ('\u{1f74}', ['\u{1fca}', '\u{0}', '\u{0}']), + ('\u{1f75}', ['\u{1fcb}', '\u{0}', '\u{0}']), ('\u{1f76}', ['\u{1fda}', '\u{0}', '\u{0}']), + ('\u{1f77}', ['\u{1fdb}', '\u{0}', '\u{0}']), ('\u{1f78}', ['\u{1ff8}', '\u{0}', '\u{0}']), + ('\u{1f79}', ['\u{1ff9}', '\u{0}', '\u{0}']), ('\u{1f7a}', ['\u{1fea}', '\u{0}', '\u{0}']), + ('\u{1f7b}', ['\u{1feb}', '\u{0}', '\u{0}']), ('\u{1f7c}', ['\u{1ffa}', '\u{0}', '\u{0}']), + ('\u{1f7d}', ['\u{1ffb}', '\u{0}', '\u{0}']), + ('\u{1f80}', ['\u{1f08}', '\u{399}', '\u{0}']), + ('\u{1f81}', ['\u{1f09}', '\u{399}', '\u{0}']), + ('\u{1f82}', ['\u{1f0a}', '\u{399}', '\u{0}']), + ('\u{1f83}', ['\u{1f0b}', '\u{399}', '\u{0}']), + ('\u{1f84}', ['\u{1f0c}', '\u{399}', '\u{0}']), + ('\u{1f85}', ['\u{1f0d}', '\u{399}', '\u{0}']), + ('\u{1f86}', ['\u{1f0e}', '\u{399}', '\u{0}']), + ('\u{1f87}', ['\u{1f0f}', '\u{399}', '\u{0}']), + ('\u{1f88}', ['\u{1f08}', '\u{399}', '\u{0}']), + ('\u{1f89}', ['\u{1f09}', '\u{399}', '\u{0}']), + ('\u{1f8a}', ['\u{1f0a}', '\u{399}', '\u{0}']), + ('\u{1f8b}', ['\u{1f0b}', '\u{399}', '\u{0}']), + ('\u{1f8c}', ['\u{1f0c}', '\u{399}', '\u{0}']), + ('\u{1f8d}', ['\u{1f0d}', '\u{399}', '\u{0}']), + ('\u{1f8e}', ['\u{1f0e}', '\u{399}', '\u{0}']), + ('\u{1f8f}', ['\u{1f0f}', '\u{399}', '\u{0}']), + ('\u{1f90}', ['\u{1f28}', '\u{399}', '\u{0}']), + ('\u{1f91}', ['\u{1f29}', '\u{399}', '\u{0}']), + ('\u{1f92}', ['\u{1f2a}', '\u{399}', '\u{0}']), + ('\u{1f93}', ['\u{1f2b}', '\u{399}', '\u{0}']), + ('\u{1f94}', ['\u{1f2c}', '\u{399}', '\u{0}']), + ('\u{1f95}', ['\u{1f2d}', '\u{399}', '\u{0}']), + ('\u{1f96}', ['\u{1f2e}', '\u{399}', '\u{0}']), + ('\u{1f97}', ['\u{1f2f}', '\u{399}', '\u{0}']), + ('\u{1f98}', ['\u{1f28}', '\u{399}', '\u{0}']), + ('\u{1f99}', ['\u{1f29}', '\u{399}', '\u{0}']), + ('\u{1f9a}', ['\u{1f2a}', '\u{399}', '\u{0}']), + ('\u{1f9b}', ['\u{1f2b}', '\u{399}', '\u{0}']), + ('\u{1f9c}', ['\u{1f2c}', '\u{399}', '\u{0}']), + ('\u{1f9d}', ['\u{1f2d}', '\u{399}', '\u{0}']), + ('\u{1f9e}', ['\u{1f2e}', '\u{399}', '\u{0}']), + ('\u{1f9f}', ['\u{1f2f}', '\u{399}', '\u{0}']), + ('\u{1fa0}', ['\u{1f68}', '\u{399}', '\u{0}']), + ('\u{1fa1}', ['\u{1f69}', '\u{399}', '\u{0}']), + ('\u{1fa2}', ['\u{1f6a}', '\u{399}', '\u{0}']), + ('\u{1fa3}', ['\u{1f6b}', '\u{399}', '\u{0}']), + ('\u{1fa4}', ['\u{1f6c}', '\u{399}', '\u{0}']), + ('\u{1fa5}', ['\u{1f6d}', '\u{399}', '\u{0}']), + ('\u{1fa6}', ['\u{1f6e}', '\u{399}', '\u{0}']), + ('\u{1fa7}', ['\u{1f6f}', '\u{399}', '\u{0}']), + ('\u{1fa8}', ['\u{1f68}', '\u{399}', '\u{0}']), + ('\u{1fa9}', ['\u{1f69}', '\u{399}', '\u{0}']), + ('\u{1faa}', ['\u{1f6a}', '\u{399}', '\u{0}']), + ('\u{1fab}', ['\u{1f6b}', '\u{399}', '\u{0}']), + ('\u{1fac}', ['\u{1f6c}', '\u{399}', '\u{0}']), + ('\u{1fad}', ['\u{1f6d}', '\u{399}', '\u{0}']), + ('\u{1fae}', ['\u{1f6e}', '\u{399}', '\u{0}']), + ('\u{1faf}', ['\u{1f6f}', '\u{399}', '\u{0}']), + ('\u{1fb0}', ['\u{1fb8}', '\u{0}', '\u{0}']), ('\u{1fb1}', ['\u{1fb9}', '\u{0}', '\u{0}']), + ('\u{1fb2}', ['\u{1fba}', '\u{399}', '\u{0}']), + ('\u{1fb3}', ['\u{391}', '\u{399}', '\u{0}']), + ('\u{1fb4}', ['\u{386}', '\u{399}', '\u{0}']), + ('\u{1fb6}', ['\u{391}', '\u{342}', '\u{0}']), + ('\u{1fb7}', ['\u{391}', '\u{342}', '\u{399}']), + ('\u{1fbc}', ['\u{391}', '\u{399}', '\u{0}']), ('\u{1fbe}', ['\u{399}', '\u{0}', '\u{0}']), + ('\u{1fc2}', ['\u{1fca}', '\u{399}', '\u{0}']), + ('\u{1fc3}', ['\u{397}', '\u{399}', '\u{0}']), + ('\u{1fc4}', ['\u{389}', '\u{399}', '\u{0}']), + ('\u{1fc6}', ['\u{397}', '\u{342}', '\u{0}']), + ('\u{1fc7}', ['\u{397}', '\u{342}', '\u{399}']), + ('\u{1fcc}', ['\u{397}', '\u{399}', '\u{0}']), ('\u{1fd0}', ['\u{1fd8}', '\u{0}', '\u{0}']), + ('\u{1fd1}', ['\u{1fd9}', '\u{0}', '\u{0}']), + ('\u{1fd2}', ['\u{399}', '\u{308}', '\u{300}']), + ('\u{1fd3}', ['\u{399}', '\u{308}', '\u{301}']), + ('\u{1fd6}', ['\u{399}', '\u{342}', '\u{0}']), + ('\u{1fd7}', ['\u{399}', '\u{308}', '\u{342}']), + ('\u{1fe0}', ['\u{1fe8}', '\u{0}', '\u{0}']), ('\u{1fe1}', ['\u{1fe9}', '\u{0}', '\u{0}']), + ('\u{1fe2}', ['\u{3a5}', '\u{308}', '\u{300}']), + ('\u{1fe3}', ['\u{3a5}', '\u{308}', '\u{301}']), + ('\u{1fe4}', ['\u{3a1}', '\u{313}', '\u{0}']), ('\u{1fe5}', ['\u{1fec}', '\u{0}', '\u{0}']), + ('\u{1fe6}', ['\u{3a5}', '\u{342}', '\u{0}']), + ('\u{1fe7}', ['\u{3a5}', '\u{308}', '\u{342}']), + ('\u{1ff2}', ['\u{1ffa}', '\u{399}', '\u{0}']), + ('\u{1ff3}', ['\u{3a9}', '\u{399}', '\u{0}']), + ('\u{1ff4}', ['\u{38f}', '\u{399}', '\u{0}']), + ('\u{1ff6}', ['\u{3a9}', '\u{342}', '\u{0}']), + ('\u{1ff7}', ['\u{3a9}', '\u{342}', '\u{399}']), + ('\u{1ffc}', ['\u{3a9}', '\u{399}', '\u{0}']), ('\u{214e}', ['\u{2132}', '\u{0}', '\u{0}']), + ('\u{2170}', ['\u{2160}', '\u{0}', '\u{0}']), ('\u{2171}', ['\u{2161}', '\u{0}', '\u{0}']), + ('\u{2172}', ['\u{2162}', '\u{0}', '\u{0}']), ('\u{2173}', ['\u{2163}', '\u{0}', '\u{0}']), + ('\u{2174}', ['\u{2164}', '\u{0}', '\u{0}']), ('\u{2175}', ['\u{2165}', '\u{0}', '\u{0}']), + ('\u{2176}', ['\u{2166}', '\u{0}', '\u{0}']), ('\u{2177}', ['\u{2167}', '\u{0}', '\u{0}']), + ('\u{2178}', ['\u{2168}', '\u{0}', '\u{0}']), ('\u{2179}', ['\u{2169}', '\u{0}', '\u{0}']), + ('\u{217a}', ['\u{216a}', '\u{0}', '\u{0}']), ('\u{217b}', ['\u{216b}', '\u{0}', '\u{0}']), + ('\u{217c}', ['\u{216c}', '\u{0}', '\u{0}']), ('\u{217d}', ['\u{216d}', '\u{0}', '\u{0}']), + ('\u{217e}', ['\u{216e}', '\u{0}', '\u{0}']), ('\u{217f}', ['\u{216f}', '\u{0}', '\u{0}']), + ('\u{2184}', ['\u{2183}', '\u{0}', '\u{0}']), ('\u{24d0}', ['\u{24b6}', '\u{0}', '\u{0}']), + ('\u{24d1}', ['\u{24b7}', '\u{0}', '\u{0}']), ('\u{24d2}', ['\u{24b8}', '\u{0}', '\u{0}']), + ('\u{24d3}', ['\u{24b9}', '\u{0}', '\u{0}']), ('\u{24d4}', ['\u{24ba}', '\u{0}', '\u{0}']), + ('\u{24d5}', ['\u{24bb}', '\u{0}', '\u{0}']), ('\u{24d6}', ['\u{24bc}', '\u{0}', '\u{0}']), + ('\u{24d7}', ['\u{24bd}', '\u{0}', '\u{0}']), ('\u{24d8}', ['\u{24be}', '\u{0}', '\u{0}']), + ('\u{24d9}', ['\u{24bf}', '\u{0}', '\u{0}']), ('\u{24da}', ['\u{24c0}', '\u{0}', '\u{0}']), + ('\u{24db}', ['\u{24c1}', '\u{0}', '\u{0}']), ('\u{24dc}', ['\u{24c2}', '\u{0}', '\u{0}']), + ('\u{24dd}', ['\u{24c3}', '\u{0}', '\u{0}']), ('\u{24de}', ['\u{24c4}', '\u{0}', '\u{0}']), + ('\u{24df}', ['\u{24c5}', '\u{0}', '\u{0}']), ('\u{24e0}', ['\u{24c6}', '\u{0}', '\u{0}']), + ('\u{24e1}', ['\u{24c7}', '\u{0}', '\u{0}']), ('\u{24e2}', ['\u{24c8}', '\u{0}', '\u{0}']), + ('\u{24e3}', ['\u{24c9}', '\u{0}', '\u{0}']), ('\u{24e4}', ['\u{24ca}', '\u{0}', '\u{0}']), + ('\u{24e5}', ['\u{24cb}', '\u{0}', '\u{0}']), ('\u{24e6}', ['\u{24cc}', '\u{0}', '\u{0}']), + ('\u{24e7}', ['\u{24cd}', '\u{0}', '\u{0}']), ('\u{24e8}', ['\u{24ce}', '\u{0}', '\u{0}']), + ('\u{24e9}', ['\u{24cf}', '\u{0}', '\u{0}']), ('\u{2c30}', ['\u{2c00}', '\u{0}', '\u{0}']), + ('\u{2c31}', ['\u{2c01}', '\u{0}', '\u{0}']), ('\u{2c32}', ['\u{2c02}', '\u{0}', '\u{0}']), + ('\u{2c33}', ['\u{2c03}', '\u{0}', '\u{0}']), ('\u{2c34}', ['\u{2c04}', '\u{0}', '\u{0}']), + ('\u{2c35}', ['\u{2c05}', '\u{0}', '\u{0}']), ('\u{2c36}', ['\u{2c06}', '\u{0}', '\u{0}']), + ('\u{2c37}', ['\u{2c07}', '\u{0}', '\u{0}']), ('\u{2c38}', ['\u{2c08}', '\u{0}', '\u{0}']), + ('\u{2c39}', ['\u{2c09}', '\u{0}', '\u{0}']), ('\u{2c3a}', ['\u{2c0a}', '\u{0}', '\u{0}']), + ('\u{2c3b}', ['\u{2c0b}', '\u{0}', '\u{0}']), ('\u{2c3c}', ['\u{2c0c}', '\u{0}', '\u{0}']), + ('\u{2c3d}', ['\u{2c0d}', '\u{0}', '\u{0}']), ('\u{2c3e}', ['\u{2c0e}', '\u{0}', '\u{0}']), + ('\u{2c3f}', ['\u{2c0f}', '\u{0}', '\u{0}']), ('\u{2c40}', ['\u{2c10}', '\u{0}', '\u{0}']), + ('\u{2c41}', ['\u{2c11}', '\u{0}', '\u{0}']), ('\u{2c42}', ['\u{2c12}', '\u{0}', '\u{0}']), + ('\u{2c43}', ['\u{2c13}', '\u{0}', '\u{0}']), ('\u{2c44}', ['\u{2c14}', '\u{0}', '\u{0}']), + ('\u{2c45}', ['\u{2c15}', '\u{0}', '\u{0}']), ('\u{2c46}', ['\u{2c16}', '\u{0}', '\u{0}']), + ('\u{2c47}', ['\u{2c17}', '\u{0}', '\u{0}']), ('\u{2c48}', ['\u{2c18}', '\u{0}', '\u{0}']), + ('\u{2c49}', ['\u{2c19}', '\u{0}', '\u{0}']), ('\u{2c4a}', ['\u{2c1a}', '\u{0}', '\u{0}']), + ('\u{2c4b}', ['\u{2c1b}', '\u{0}', '\u{0}']), ('\u{2c4c}', ['\u{2c1c}', '\u{0}', '\u{0}']), + ('\u{2c4d}', ['\u{2c1d}', '\u{0}', '\u{0}']), ('\u{2c4e}', ['\u{2c1e}', '\u{0}', '\u{0}']), + ('\u{2c4f}', ['\u{2c1f}', '\u{0}', '\u{0}']), ('\u{2c50}', ['\u{2c20}', '\u{0}', '\u{0}']), + ('\u{2c51}', ['\u{2c21}', '\u{0}', '\u{0}']), ('\u{2c52}', ['\u{2c22}', '\u{0}', '\u{0}']), + ('\u{2c53}', ['\u{2c23}', '\u{0}', '\u{0}']), ('\u{2c54}', ['\u{2c24}', '\u{0}', '\u{0}']), + ('\u{2c55}', ['\u{2c25}', '\u{0}', '\u{0}']), ('\u{2c56}', ['\u{2c26}', '\u{0}', '\u{0}']), + ('\u{2c57}', ['\u{2c27}', '\u{0}', '\u{0}']), ('\u{2c58}', ['\u{2c28}', '\u{0}', '\u{0}']), + ('\u{2c59}', ['\u{2c29}', '\u{0}', '\u{0}']), ('\u{2c5a}', ['\u{2c2a}', '\u{0}', '\u{0}']), + ('\u{2c5b}', ['\u{2c2b}', '\u{0}', '\u{0}']), ('\u{2c5c}', ['\u{2c2c}', '\u{0}', '\u{0}']), + ('\u{2c5d}', ['\u{2c2d}', '\u{0}', '\u{0}']), ('\u{2c5e}', ['\u{2c2e}', '\u{0}', '\u{0}']), + ('\u{2c61}', ['\u{2c60}', '\u{0}', '\u{0}']), ('\u{2c65}', ['\u{23a}', '\u{0}', '\u{0}']), + ('\u{2c66}', ['\u{23e}', '\u{0}', '\u{0}']), ('\u{2c68}', ['\u{2c67}', '\u{0}', '\u{0}']), + ('\u{2c6a}', ['\u{2c69}', '\u{0}', '\u{0}']), ('\u{2c6c}', ['\u{2c6b}', '\u{0}', '\u{0}']), + ('\u{2c73}', ['\u{2c72}', '\u{0}', '\u{0}']), ('\u{2c76}', ['\u{2c75}', '\u{0}', '\u{0}']), + ('\u{2c81}', ['\u{2c80}', '\u{0}', '\u{0}']), ('\u{2c83}', ['\u{2c82}', '\u{0}', '\u{0}']), + ('\u{2c85}', ['\u{2c84}', '\u{0}', '\u{0}']), ('\u{2c87}', ['\u{2c86}', '\u{0}', '\u{0}']), + ('\u{2c89}', ['\u{2c88}', '\u{0}', '\u{0}']), ('\u{2c8b}', ['\u{2c8a}', '\u{0}', '\u{0}']), + ('\u{2c8d}', ['\u{2c8c}', '\u{0}', '\u{0}']), ('\u{2c8f}', ['\u{2c8e}', '\u{0}', '\u{0}']), + ('\u{2c91}', ['\u{2c90}', '\u{0}', '\u{0}']), ('\u{2c93}', ['\u{2c92}', '\u{0}', '\u{0}']), + ('\u{2c95}', ['\u{2c94}', '\u{0}', '\u{0}']), ('\u{2c97}', ['\u{2c96}', '\u{0}', '\u{0}']), + ('\u{2c99}', ['\u{2c98}', '\u{0}', '\u{0}']), ('\u{2c9b}', ['\u{2c9a}', '\u{0}', '\u{0}']), + ('\u{2c9d}', ['\u{2c9c}', '\u{0}', '\u{0}']), ('\u{2c9f}', ['\u{2c9e}', '\u{0}', '\u{0}']), + ('\u{2ca1}', ['\u{2ca0}', '\u{0}', '\u{0}']), ('\u{2ca3}', ['\u{2ca2}', '\u{0}', '\u{0}']), + ('\u{2ca5}', ['\u{2ca4}', '\u{0}', '\u{0}']), ('\u{2ca7}', ['\u{2ca6}', '\u{0}', '\u{0}']), + ('\u{2ca9}', ['\u{2ca8}', '\u{0}', '\u{0}']), ('\u{2cab}', ['\u{2caa}', '\u{0}', '\u{0}']), + ('\u{2cad}', ['\u{2cac}', '\u{0}', '\u{0}']), ('\u{2caf}', ['\u{2cae}', '\u{0}', '\u{0}']), + ('\u{2cb1}', ['\u{2cb0}', '\u{0}', '\u{0}']), ('\u{2cb3}', ['\u{2cb2}', '\u{0}', '\u{0}']), + ('\u{2cb5}', ['\u{2cb4}', '\u{0}', '\u{0}']), ('\u{2cb7}', ['\u{2cb6}', '\u{0}', '\u{0}']), + ('\u{2cb9}', ['\u{2cb8}', '\u{0}', '\u{0}']), ('\u{2cbb}', ['\u{2cba}', '\u{0}', '\u{0}']), + ('\u{2cbd}', ['\u{2cbc}', '\u{0}', '\u{0}']), ('\u{2cbf}', ['\u{2cbe}', '\u{0}', '\u{0}']), + ('\u{2cc1}', ['\u{2cc0}', '\u{0}', '\u{0}']), ('\u{2cc3}', ['\u{2cc2}', '\u{0}', '\u{0}']), + ('\u{2cc5}', ['\u{2cc4}', '\u{0}', '\u{0}']), ('\u{2cc7}', ['\u{2cc6}', '\u{0}', '\u{0}']), + ('\u{2cc9}', ['\u{2cc8}', '\u{0}', '\u{0}']), ('\u{2ccb}', ['\u{2cca}', '\u{0}', '\u{0}']), + ('\u{2ccd}', ['\u{2ccc}', '\u{0}', '\u{0}']), ('\u{2ccf}', ['\u{2cce}', '\u{0}', '\u{0}']), + ('\u{2cd1}', ['\u{2cd0}', '\u{0}', '\u{0}']), ('\u{2cd3}', ['\u{2cd2}', '\u{0}', '\u{0}']), + ('\u{2cd5}', ['\u{2cd4}', '\u{0}', '\u{0}']), ('\u{2cd7}', ['\u{2cd6}', '\u{0}', '\u{0}']), + ('\u{2cd9}', ['\u{2cd8}', '\u{0}', '\u{0}']), ('\u{2cdb}', ['\u{2cda}', '\u{0}', '\u{0}']), + ('\u{2cdd}', ['\u{2cdc}', '\u{0}', '\u{0}']), ('\u{2cdf}', ['\u{2cde}', '\u{0}', '\u{0}']), + ('\u{2ce1}', ['\u{2ce0}', '\u{0}', '\u{0}']), ('\u{2ce3}', ['\u{2ce2}', '\u{0}', '\u{0}']), + ('\u{2cec}', ['\u{2ceb}', '\u{0}', '\u{0}']), ('\u{2cee}', ['\u{2ced}', '\u{0}', '\u{0}']), + ('\u{2cf3}', ['\u{2cf2}', '\u{0}', '\u{0}']), ('\u{2d00}', ['\u{10a0}', '\u{0}', '\u{0}']), + ('\u{2d01}', ['\u{10a1}', '\u{0}', '\u{0}']), ('\u{2d02}', ['\u{10a2}', '\u{0}', '\u{0}']), + ('\u{2d03}', ['\u{10a3}', '\u{0}', '\u{0}']), ('\u{2d04}', ['\u{10a4}', '\u{0}', '\u{0}']), + ('\u{2d05}', ['\u{10a5}', '\u{0}', '\u{0}']), ('\u{2d06}', ['\u{10a6}', '\u{0}', '\u{0}']), + ('\u{2d07}', ['\u{10a7}', '\u{0}', '\u{0}']), ('\u{2d08}', ['\u{10a8}', '\u{0}', '\u{0}']), + ('\u{2d09}', ['\u{10a9}', '\u{0}', '\u{0}']), ('\u{2d0a}', ['\u{10aa}', '\u{0}', '\u{0}']), + ('\u{2d0b}', ['\u{10ab}', '\u{0}', '\u{0}']), ('\u{2d0c}', ['\u{10ac}', '\u{0}', '\u{0}']), + ('\u{2d0d}', ['\u{10ad}', '\u{0}', '\u{0}']), ('\u{2d0e}', ['\u{10ae}', '\u{0}', '\u{0}']), + ('\u{2d0f}', ['\u{10af}', '\u{0}', '\u{0}']), ('\u{2d10}', ['\u{10b0}', '\u{0}', '\u{0}']), + ('\u{2d11}', ['\u{10b1}', '\u{0}', '\u{0}']), ('\u{2d12}', ['\u{10b2}', '\u{0}', '\u{0}']), + ('\u{2d13}', ['\u{10b3}', '\u{0}', '\u{0}']), ('\u{2d14}', ['\u{10b4}', '\u{0}', '\u{0}']), + ('\u{2d15}', ['\u{10b5}', '\u{0}', '\u{0}']), ('\u{2d16}', ['\u{10b6}', '\u{0}', '\u{0}']), + ('\u{2d17}', ['\u{10b7}', '\u{0}', '\u{0}']), ('\u{2d18}', ['\u{10b8}', '\u{0}', '\u{0}']), + ('\u{2d19}', ['\u{10b9}', '\u{0}', '\u{0}']), ('\u{2d1a}', ['\u{10ba}', '\u{0}', '\u{0}']), + ('\u{2d1b}', ['\u{10bb}', '\u{0}', '\u{0}']), ('\u{2d1c}', ['\u{10bc}', '\u{0}', '\u{0}']), + ('\u{2d1d}', ['\u{10bd}', '\u{0}', '\u{0}']), ('\u{2d1e}', ['\u{10be}', '\u{0}', '\u{0}']), + ('\u{2d1f}', ['\u{10bf}', '\u{0}', '\u{0}']), ('\u{2d20}', ['\u{10c0}', '\u{0}', '\u{0}']), + ('\u{2d21}', ['\u{10c1}', '\u{0}', '\u{0}']), ('\u{2d22}', ['\u{10c2}', '\u{0}', '\u{0}']), + ('\u{2d23}', ['\u{10c3}', '\u{0}', '\u{0}']), ('\u{2d24}', ['\u{10c4}', '\u{0}', '\u{0}']), + ('\u{2d25}', ['\u{10c5}', '\u{0}', '\u{0}']), ('\u{2d27}', ['\u{10c7}', '\u{0}', '\u{0}']), + ('\u{2d2d}', ['\u{10cd}', '\u{0}', '\u{0}']), ('\u{a641}', ['\u{a640}', '\u{0}', '\u{0}']), + ('\u{a643}', ['\u{a642}', '\u{0}', '\u{0}']), ('\u{a645}', ['\u{a644}', '\u{0}', '\u{0}']), + ('\u{a647}', ['\u{a646}', '\u{0}', '\u{0}']), ('\u{a649}', ['\u{a648}', '\u{0}', '\u{0}']), + ('\u{a64b}', ['\u{a64a}', '\u{0}', '\u{0}']), ('\u{a64d}', ['\u{a64c}', '\u{0}', '\u{0}']), + ('\u{a64f}', ['\u{a64e}', '\u{0}', '\u{0}']), ('\u{a651}', ['\u{a650}', '\u{0}', '\u{0}']), + ('\u{a653}', ['\u{a652}', '\u{0}', '\u{0}']), ('\u{a655}', ['\u{a654}', '\u{0}', '\u{0}']), + ('\u{a657}', ['\u{a656}', '\u{0}', '\u{0}']), ('\u{a659}', ['\u{a658}', '\u{0}', '\u{0}']), + ('\u{a65b}', ['\u{a65a}', '\u{0}', '\u{0}']), ('\u{a65d}', ['\u{a65c}', '\u{0}', '\u{0}']), + ('\u{a65f}', ['\u{a65e}', '\u{0}', '\u{0}']), ('\u{a661}', ['\u{a660}', '\u{0}', '\u{0}']), + ('\u{a663}', ['\u{a662}', '\u{0}', '\u{0}']), ('\u{a665}', ['\u{a664}', '\u{0}', '\u{0}']), + ('\u{a667}', ['\u{a666}', '\u{0}', '\u{0}']), ('\u{a669}', ['\u{a668}', '\u{0}', '\u{0}']), + ('\u{a66b}', ['\u{a66a}', '\u{0}', '\u{0}']), ('\u{a66d}', ['\u{a66c}', '\u{0}', '\u{0}']), + ('\u{a681}', ['\u{a680}', '\u{0}', '\u{0}']), ('\u{a683}', ['\u{a682}', '\u{0}', '\u{0}']), + ('\u{a685}', ['\u{a684}', '\u{0}', '\u{0}']), ('\u{a687}', ['\u{a686}', '\u{0}', '\u{0}']), + ('\u{a689}', ['\u{a688}', '\u{0}', '\u{0}']), ('\u{a68b}', ['\u{a68a}', '\u{0}', '\u{0}']), + ('\u{a68d}', ['\u{a68c}', '\u{0}', '\u{0}']), ('\u{a68f}', ['\u{a68e}', '\u{0}', '\u{0}']), + ('\u{a691}', ['\u{a690}', '\u{0}', '\u{0}']), ('\u{a693}', ['\u{a692}', '\u{0}', '\u{0}']), + ('\u{a695}', ['\u{a694}', '\u{0}', '\u{0}']), ('\u{a697}', ['\u{a696}', '\u{0}', '\u{0}']), + ('\u{a699}', ['\u{a698}', '\u{0}', '\u{0}']), ('\u{a69b}', ['\u{a69a}', '\u{0}', '\u{0}']), + ('\u{a723}', ['\u{a722}', '\u{0}', '\u{0}']), ('\u{a725}', ['\u{a724}', '\u{0}', '\u{0}']), + ('\u{a727}', ['\u{a726}', '\u{0}', '\u{0}']), ('\u{a729}', ['\u{a728}', '\u{0}', '\u{0}']), + ('\u{a72b}', ['\u{a72a}', '\u{0}', '\u{0}']), ('\u{a72d}', ['\u{a72c}', '\u{0}', '\u{0}']), + ('\u{a72f}', ['\u{a72e}', '\u{0}', '\u{0}']), ('\u{a733}', ['\u{a732}', '\u{0}', '\u{0}']), + ('\u{a735}', ['\u{a734}', '\u{0}', '\u{0}']), ('\u{a737}', ['\u{a736}', '\u{0}', '\u{0}']), + ('\u{a739}', ['\u{a738}', '\u{0}', '\u{0}']), ('\u{a73b}', ['\u{a73a}', '\u{0}', '\u{0}']), + ('\u{a73d}', ['\u{a73c}', '\u{0}', '\u{0}']), ('\u{a73f}', ['\u{a73e}', '\u{0}', '\u{0}']), + ('\u{a741}', ['\u{a740}', '\u{0}', '\u{0}']), ('\u{a743}', ['\u{a742}', '\u{0}', '\u{0}']), + ('\u{a745}', ['\u{a744}', '\u{0}', '\u{0}']), ('\u{a747}', ['\u{a746}', '\u{0}', '\u{0}']), + ('\u{a749}', ['\u{a748}', '\u{0}', '\u{0}']), ('\u{a74b}', ['\u{a74a}', '\u{0}', '\u{0}']), + ('\u{a74d}', ['\u{a74c}', '\u{0}', '\u{0}']), ('\u{a74f}', ['\u{a74e}', '\u{0}', '\u{0}']), + ('\u{a751}', ['\u{a750}', '\u{0}', '\u{0}']), ('\u{a753}', ['\u{a752}', '\u{0}', '\u{0}']), + ('\u{a755}', ['\u{a754}', '\u{0}', '\u{0}']), ('\u{a757}', ['\u{a756}', '\u{0}', '\u{0}']), + ('\u{a759}', ['\u{a758}', '\u{0}', '\u{0}']), ('\u{a75b}', ['\u{a75a}', '\u{0}', '\u{0}']), + ('\u{a75d}', ['\u{a75c}', '\u{0}', '\u{0}']), ('\u{a75f}', ['\u{a75e}', '\u{0}', '\u{0}']), + ('\u{a761}', ['\u{a760}', '\u{0}', '\u{0}']), ('\u{a763}', ['\u{a762}', '\u{0}', '\u{0}']), + ('\u{a765}', ['\u{a764}', '\u{0}', '\u{0}']), ('\u{a767}', ['\u{a766}', '\u{0}', '\u{0}']), + ('\u{a769}', ['\u{a768}', '\u{0}', '\u{0}']), ('\u{a76b}', ['\u{a76a}', '\u{0}', '\u{0}']), + ('\u{a76d}', ['\u{a76c}', '\u{0}', '\u{0}']), ('\u{a76f}', ['\u{a76e}', '\u{0}', '\u{0}']), + ('\u{a77a}', ['\u{a779}', '\u{0}', '\u{0}']), ('\u{a77c}', ['\u{a77b}', '\u{0}', '\u{0}']), + ('\u{a77f}', ['\u{a77e}', '\u{0}', '\u{0}']), ('\u{a781}', ['\u{a780}', '\u{0}', '\u{0}']), + ('\u{a783}', ['\u{a782}', '\u{0}', '\u{0}']), ('\u{a785}', ['\u{a784}', '\u{0}', '\u{0}']), + ('\u{a787}', ['\u{a786}', '\u{0}', '\u{0}']), ('\u{a78c}', ['\u{a78b}', '\u{0}', '\u{0}']), + ('\u{a791}', ['\u{a790}', '\u{0}', '\u{0}']), ('\u{a793}', ['\u{a792}', '\u{0}', '\u{0}']), + ('\u{a794}', ['\u{a7c4}', '\u{0}', '\u{0}']), ('\u{a797}', ['\u{a796}', '\u{0}', '\u{0}']), + ('\u{a799}', ['\u{a798}', '\u{0}', '\u{0}']), ('\u{a79b}', ['\u{a79a}', '\u{0}', '\u{0}']), + ('\u{a79d}', ['\u{a79c}', '\u{0}', '\u{0}']), ('\u{a79f}', ['\u{a79e}', '\u{0}', '\u{0}']), + ('\u{a7a1}', ['\u{a7a0}', '\u{0}', '\u{0}']), ('\u{a7a3}', ['\u{a7a2}', '\u{0}', '\u{0}']), + ('\u{a7a5}', ['\u{a7a4}', '\u{0}', '\u{0}']), ('\u{a7a7}', ['\u{a7a6}', '\u{0}', '\u{0}']), + ('\u{a7a9}', ['\u{a7a8}', '\u{0}', '\u{0}']), ('\u{a7b5}', ['\u{a7b4}', '\u{0}', '\u{0}']), + ('\u{a7b7}', ['\u{a7b6}', '\u{0}', '\u{0}']), ('\u{a7b9}', ['\u{a7b8}', '\u{0}', '\u{0}']), + ('\u{a7bb}', ['\u{a7ba}', '\u{0}', '\u{0}']), ('\u{a7bd}', ['\u{a7bc}', '\u{0}', '\u{0}']), + ('\u{a7bf}', ['\u{a7be}', '\u{0}', '\u{0}']), ('\u{a7c3}', ['\u{a7c2}', '\u{0}', '\u{0}']), + ('\u{ab53}', ['\u{a7b3}', '\u{0}', '\u{0}']), ('\u{ab70}', ['\u{13a0}', '\u{0}', '\u{0}']), + ('\u{ab71}', ['\u{13a1}', '\u{0}', '\u{0}']), ('\u{ab72}', ['\u{13a2}', '\u{0}', '\u{0}']), + ('\u{ab73}', ['\u{13a3}', '\u{0}', '\u{0}']), ('\u{ab74}', ['\u{13a4}', '\u{0}', '\u{0}']), + ('\u{ab75}', ['\u{13a5}', '\u{0}', '\u{0}']), ('\u{ab76}', ['\u{13a6}', '\u{0}', '\u{0}']), + ('\u{ab77}', ['\u{13a7}', '\u{0}', '\u{0}']), ('\u{ab78}', ['\u{13a8}', '\u{0}', '\u{0}']), + ('\u{ab79}', ['\u{13a9}', '\u{0}', '\u{0}']), ('\u{ab7a}', ['\u{13aa}', '\u{0}', '\u{0}']), + ('\u{ab7b}', ['\u{13ab}', '\u{0}', '\u{0}']), ('\u{ab7c}', ['\u{13ac}', '\u{0}', '\u{0}']), + ('\u{ab7d}', ['\u{13ad}', '\u{0}', '\u{0}']), ('\u{ab7e}', ['\u{13ae}', '\u{0}', '\u{0}']), + ('\u{ab7f}', ['\u{13af}', '\u{0}', '\u{0}']), ('\u{ab80}', ['\u{13b0}', '\u{0}', '\u{0}']), + ('\u{ab81}', ['\u{13b1}', '\u{0}', '\u{0}']), ('\u{ab82}', ['\u{13b2}', '\u{0}', '\u{0}']), + ('\u{ab83}', ['\u{13b3}', '\u{0}', '\u{0}']), ('\u{ab84}', ['\u{13b4}', '\u{0}', '\u{0}']), + ('\u{ab85}', ['\u{13b5}', '\u{0}', '\u{0}']), ('\u{ab86}', ['\u{13b6}', '\u{0}', '\u{0}']), + ('\u{ab87}', ['\u{13b7}', '\u{0}', '\u{0}']), ('\u{ab88}', ['\u{13b8}', '\u{0}', '\u{0}']), + ('\u{ab89}', ['\u{13b9}', '\u{0}', '\u{0}']), ('\u{ab8a}', ['\u{13ba}', '\u{0}', '\u{0}']), + ('\u{ab8b}', ['\u{13bb}', '\u{0}', '\u{0}']), ('\u{ab8c}', ['\u{13bc}', '\u{0}', '\u{0}']), + ('\u{ab8d}', ['\u{13bd}', '\u{0}', '\u{0}']), ('\u{ab8e}', ['\u{13be}', '\u{0}', '\u{0}']), + ('\u{ab8f}', ['\u{13bf}', '\u{0}', '\u{0}']), ('\u{ab90}', ['\u{13c0}', '\u{0}', '\u{0}']), + ('\u{ab91}', ['\u{13c1}', '\u{0}', '\u{0}']), ('\u{ab92}', ['\u{13c2}', '\u{0}', '\u{0}']), + ('\u{ab93}', ['\u{13c3}', '\u{0}', '\u{0}']), ('\u{ab94}', ['\u{13c4}', '\u{0}', '\u{0}']), + ('\u{ab95}', ['\u{13c5}', '\u{0}', '\u{0}']), ('\u{ab96}', ['\u{13c6}', '\u{0}', '\u{0}']), + ('\u{ab97}', ['\u{13c7}', '\u{0}', '\u{0}']), ('\u{ab98}', ['\u{13c8}', '\u{0}', '\u{0}']), + ('\u{ab99}', ['\u{13c9}', '\u{0}', '\u{0}']), ('\u{ab9a}', ['\u{13ca}', '\u{0}', '\u{0}']), + ('\u{ab9b}', ['\u{13cb}', '\u{0}', '\u{0}']), ('\u{ab9c}', ['\u{13cc}', '\u{0}', '\u{0}']), + ('\u{ab9d}', ['\u{13cd}', '\u{0}', '\u{0}']), ('\u{ab9e}', ['\u{13ce}', '\u{0}', '\u{0}']), + ('\u{ab9f}', ['\u{13cf}', '\u{0}', '\u{0}']), ('\u{aba0}', ['\u{13d0}', '\u{0}', '\u{0}']), + ('\u{aba1}', ['\u{13d1}', '\u{0}', '\u{0}']), ('\u{aba2}', ['\u{13d2}', '\u{0}', '\u{0}']), + ('\u{aba3}', ['\u{13d3}', '\u{0}', '\u{0}']), ('\u{aba4}', ['\u{13d4}', '\u{0}', '\u{0}']), + ('\u{aba5}', ['\u{13d5}', '\u{0}', '\u{0}']), ('\u{aba6}', ['\u{13d6}', '\u{0}', '\u{0}']), + ('\u{aba7}', ['\u{13d7}', '\u{0}', '\u{0}']), ('\u{aba8}', ['\u{13d8}', '\u{0}', '\u{0}']), + ('\u{aba9}', ['\u{13d9}', '\u{0}', '\u{0}']), ('\u{abaa}', ['\u{13da}', '\u{0}', '\u{0}']), + ('\u{abab}', ['\u{13db}', '\u{0}', '\u{0}']), ('\u{abac}', ['\u{13dc}', '\u{0}', '\u{0}']), + ('\u{abad}', ['\u{13dd}', '\u{0}', '\u{0}']), ('\u{abae}', ['\u{13de}', '\u{0}', '\u{0}']), + ('\u{abaf}', ['\u{13df}', '\u{0}', '\u{0}']), ('\u{abb0}', ['\u{13e0}', '\u{0}', '\u{0}']), + ('\u{abb1}', ['\u{13e1}', '\u{0}', '\u{0}']), ('\u{abb2}', ['\u{13e2}', '\u{0}', '\u{0}']), + ('\u{abb3}', ['\u{13e3}', '\u{0}', '\u{0}']), ('\u{abb4}', ['\u{13e4}', '\u{0}', '\u{0}']), + ('\u{abb5}', ['\u{13e5}', '\u{0}', '\u{0}']), ('\u{abb6}', ['\u{13e6}', '\u{0}', '\u{0}']), + ('\u{abb7}', ['\u{13e7}', '\u{0}', '\u{0}']), ('\u{abb8}', ['\u{13e8}', '\u{0}', '\u{0}']), + ('\u{abb9}', ['\u{13e9}', '\u{0}', '\u{0}']), ('\u{abba}', ['\u{13ea}', '\u{0}', '\u{0}']), + ('\u{abbb}', ['\u{13eb}', '\u{0}', '\u{0}']), ('\u{abbc}', ['\u{13ec}', '\u{0}', '\u{0}']), + ('\u{abbd}', ['\u{13ed}', '\u{0}', '\u{0}']), ('\u{abbe}', ['\u{13ee}', '\u{0}', '\u{0}']), + ('\u{abbf}', ['\u{13ef}', '\u{0}', '\u{0}']), ('\u{fb00}', ['F', 'F', '\u{0}']), + ('\u{fb01}', ['F', 'I', '\u{0}']), ('\u{fb02}', ['F', 'L', '\u{0}']), + ('\u{fb03}', ['F', 'F', 'I']), ('\u{fb04}', ['F', 'F', 'L']), + ('\u{fb05}', ['S', 'T', '\u{0}']), ('\u{fb06}', ['S', 'T', '\u{0}']), + ('\u{fb13}', ['\u{544}', '\u{546}', '\u{0}']), + ('\u{fb14}', ['\u{544}', '\u{535}', '\u{0}']), + ('\u{fb15}', ['\u{544}', '\u{53b}', '\u{0}']), + ('\u{fb16}', ['\u{54e}', '\u{546}', '\u{0}']), + ('\u{fb17}', ['\u{544}', '\u{53d}', '\u{0}']), ('\u{ff41}', ['\u{ff21}', '\u{0}', '\u{0}']), + ('\u{ff42}', ['\u{ff22}', '\u{0}', '\u{0}']), ('\u{ff43}', ['\u{ff23}', '\u{0}', '\u{0}']), + ('\u{ff44}', ['\u{ff24}', '\u{0}', '\u{0}']), ('\u{ff45}', ['\u{ff25}', '\u{0}', '\u{0}']), + ('\u{ff46}', ['\u{ff26}', '\u{0}', '\u{0}']), ('\u{ff47}', ['\u{ff27}', '\u{0}', '\u{0}']), + ('\u{ff48}', ['\u{ff28}', '\u{0}', '\u{0}']), ('\u{ff49}', ['\u{ff29}', '\u{0}', '\u{0}']), + ('\u{ff4a}', ['\u{ff2a}', '\u{0}', '\u{0}']), ('\u{ff4b}', ['\u{ff2b}', '\u{0}', '\u{0}']), + ('\u{ff4c}', ['\u{ff2c}', '\u{0}', '\u{0}']), ('\u{ff4d}', ['\u{ff2d}', '\u{0}', '\u{0}']), + ('\u{ff4e}', ['\u{ff2e}', '\u{0}', '\u{0}']), ('\u{ff4f}', ['\u{ff2f}', '\u{0}', '\u{0}']), + ('\u{ff50}', ['\u{ff30}', '\u{0}', '\u{0}']), ('\u{ff51}', ['\u{ff31}', '\u{0}', '\u{0}']), + ('\u{ff52}', ['\u{ff32}', '\u{0}', '\u{0}']), ('\u{ff53}', ['\u{ff33}', '\u{0}', '\u{0}']), + ('\u{ff54}', ['\u{ff34}', '\u{0}', '\u{0}']), ('\u{ff55}', ['\u{ff35}', '\u{0}', '\u{0}']), + ('\u{ff56}', ['\u{ff36}', '\u{0}', '\u{0}']), ('\u{ff57}', ['\u{ff37}', '\u{0}', '\u{0}']), + ('\u{ff58}', ['\u{ff38}', '\u{0}', '\u{0}']), ('\u{ff59}', ['\u{ff39}', '\u{0}', '\u{0}']), + ('\u{ff5a}', ['\u{ff3a}', '\u{0}', '\u{0}']), + ('\u{10428}', ['\u{10400}', '\u{0}', '\u{0}']), + ('\u{10429}', ['\u{10401}', '\u{0}', '\u{0}']), + ('\u{1042a}', ['\u{10402}', '\u{0}', '\u{0}']), + ('\u{1042b}', ['\u{10403}', '\u{0}', '\u{0}']), + ('\u{1042c}', ['\u{10404}', '\u{0}', '\u{0}']), + ('\u{1042d}', ['\u{10405}', '\u{0}', '\u{0}']), + ('\u{1042e}', ['\u{10406}', '\u{0}', '\u{0}']), + ('\u{1042f}', ['\u{10407}', '\u{0}', '\u{0}']), + ('\u{10430}', ['\u{10408}', '\u{0}', '\u{0}']), + ('\u{10431}', ['\u{10409}', '\u{0}', '\u{0}']), + ('\u{10432}', ['\u{1040a}', '\u{0}', '\u{0}']), + ('\u{10433}', ['\u{1040b}', '\u{0}', '\u{0}']), + ('\u{10434}', ['\u{1040c}', '\u{0}', '\u{0}']), + ('\u{10435}', ['\u{1040d}', '\u{0}', '\u{0}']), + ('\u{10436}', ['\u{1040e}', '\u{0}', '\u{0}']), + ('\u{10437}', ['\u{1040f}', '\u{0}', '\u{0}']), + ('\u{10438}', ['\u{10410}', '\u{0}', '\u{0}']), + ('\u{10439}', ['\u{10411}', '\u{0}', '\u{0}']), + ('\u{1043a}', ['\u{10412}', '\u{0}', '\u{0}']), + ('\u{1043b}', ['\u{10413}', '\u{0}', '\u{0}']), + ('\u{1043c}', ['\u{10414}', '\u{0}', '\u{0}']), + ('\u{1043d}', ['\u{10415}', '\u{0}', '\u{0}']), + ('\u{1043e}', ['\u{10416}', '\u{0}', '\u{0}']), + ('\u{1043f}', ['\u{10417}', '\u{0}', '\u{0}']), + ('\u{10440}', ['\u{10418}', '\u{0}', '\u{0}']), + ('\u{10441}', ['\u{10419}', '\u{0}', '\u{0}']), + ('\u{10442}', ['\u{1041a}', '\u{0}', '\u{0}']), + ('\u{10443}', ['\u{1041b}', '\u{0}', '\u{0}']), + ('\u{10444}', ['\u{1041c}', '\u{0}', '\u{0}']), + ('\u{10445}', ['\u{1041d}', '\u{0}', '\u{0}']), + ('\u{10446}', ['\u{1041e}', '\u{0}', '\u{0}']), + ('\u{10447}', ['\u{1041f}', '\u{0}', '\u{0}']), + ('\u{10448}', ['\u{10420}', '\u{0}', '\u{0}']), + ('\u{10449}', ['\u{10421}', '\u{0}', '\u{0}']), + ('\u{1044a}', ['\u{10422}', '\u{0}', '\u{0}']), + ('\u{1044b}', ['\u{10423}', '\u{0}', '\u{0}']), + ('\u{1044c}', ['\u{10424}', '\u{0}', '\u{0}']), + ('\u{1044d}', ['\u{10425}', '\u{0}', '\u{0}']), + ('\u{1044e}', ['\u{10426}', '\u{0}', '\u{0}']), + ('\u{1044f}', ['\u{10427}', '\u{0}', '\u{0}']), + ('\u{104d8}', ['\u{104b0}', '\u{0}', '\u{0}']), + ('\u{104d9}', ['\u{104b1}', '\u{0}', '\u{0}']), + ('\u{104da}', ['\u{104b2}', '\u{0}', '\u{0}']), + ('\u{104db}', ['\u{104b3}', '\u{0}', '\u{0}']), + ('\u{104dc}', ['\u{104b4}', '\u{0}', '\u{0}']), + ('\u{104dd}', ['\u{104b5}', '\u{0}', '\u{0}']), + ('\u{104de}', ['\u{104b6}', '\u{0}', '\u{0}']), + ('\u{104df}', ['\u{104b7}', '\u{0}', '\u{0}']), + ('\u{104e0}', ['\u{104b8}', '\u{0}', '\u{0}']), + ('\u{104e1}', ['\u{104b9}', '\u{0}', '\u{0}']), + ('\u{104e2}', ['\u{104ba}', '\u{0}', '\u{0}']), + ('\u{104e3}', ['\u{104bb}', '\u{0}', '\u{0}']), + ('\u{104e4}', ['\u{104bc}', '\u{0}', '\u{0}']), + ('\u{104e5}', ['\u{104bd}', '\u{0}', '\u{0}']), + ('\u{104e6}', ['\u{104be}', '\u{0}', '\u{0}']), + ('\u{104e7}', ['\u{104bf}', '\u{0}', '\u{0}']), + ('\u{104e8}', ['\u{104c0}', '\u{0}', '\u{0}']), + ('\u{104e9}', ['\u{104c1}', '\u{0}', '\u{0}']), + ('\u{104ea}', ['\u{104c2}', '\u{0}', '\u{0}']), + ('\u{104eb}', ['\u{104c3}', '\u{0}', '\u{0}']), + ('\u{104ec}', ['\u{104c4}', '\u{0}', '\u{0}']), + ('\u{104ed}', ['\u{104c5}', '\u{0}', '\u{0}']), + ('\u{104ee}', ['\u{104c6}', '\u{0}', '\u{0}']), + ('\u{104ef}', ['\u{104c7}', '\u{0}', '\u{0}']), + ('\u{104f0}', ['\u{104c8}', '\u{0}', '\u{0}']), + ('\u{104f1}', ['\u{104c9}', '\u{0}', '\u{0}']), + ('\u{104f2}', ['\u{104ca}', '\u{0}', '\u{0}']), + ('\u{104f3}', ['\u{104cb}', '\u{0}', '\u{0}']), + ('\u{104f4}', ['\u{104cc}', '\u{0}', '\u{0}']), + ('\u{104f5}', ['\u{104cd}', '\u{0}', '\u{0}']), + ('\u{104f6}', ['\u{104ce}', '\u{0}', '\u{0}']), + ('\u{104f7}', ['\u{104cf}', '\u{0}', '\u{0}']), + ('\u{104f8}', ['\u{104d0}', '\u{0}', '\u{0}']), + ('\u{104f9}', ['\u{104d1}', '\u{0}', '\u{0}']), + ('\u{104fa}', ['\u{104d2}', '\u{0}', '\u{0}']), + ('\u{104fb}', ['\u{104d3}', '\u{0}', '\u{0}']), + ('\u{10cc0}', ['\u{10c80}', '\u{0}', '\u{0}']), + ('\u{10cc1}', ['\u{10c81}', '\u{0}', '\u{0}']), + ('\u{10cc2}', ['\u{10c82}', '\u{0}', '\u{0}']), + ('\u{10cc3}', ['\u{10c83}', '\u{0}', '\u{0}']), + ('\u{10cc4}', ['\u{10c84}', '\u{0}', '\u{0}']), + ('\u{10cc5}', ['\u{10c85}', '\u{0}', '\u{0}']), + ('\u{10cc6}', ['\u{10c86}', '\u{0}', '\u{0}']), + ('\u{10cc7}', ['\u{10c87}', '\u{0}', '\u{0}']), + ('\u{10cc8}', ['\u{10c88}', '\u{0}', '\u{0}']), + ('\u{10cc9}', ['\u{10c89}', '\u{0}', '\u{0}']), + ('\u{10cca}', ['\u{10c8a}', '\u{0}', '\u{0}']), + ('\u{10ccb}', ['\u{10c8b}', '\u{0}', '\u{0}']), + ('\u{10ccc}', ['\u{10c8c}', '\u{0}', '\u{0}']), + ('\u{10ccd}', ['\u{10c8d}', '\u{0}', '\u{0}']), + ('\u{10cce}', ['\u{10c8e}', '\u{0}', '\u{0}']), + ('\u{10ccf}', ['\u{10c8f}', '\u{0}', '\u{0}']), + ('\u{10cd0}', ['\u{10c90}', '\u{0}', '\u{0}']), + ('\u{10cd1}', ['\u{10c91}', '\u{0}', '\u{0}']), + ('\u{10cd2}', ['\u{10c92}', '\u{0}', '\u{0}']), + ('\u{10cd3}', ['\u{10c93}', '\u{0}', '\u{0}']), + ('\u{10cd4}', ['\u{10c94}', '\u{0}', '\u{0}']), + ('\u{10cd5}', ['\u{10c95}', '\u{0}', '\u{0}']), + ('\u{10cd6}', ['\u{10c96}', '\u{0}', '\u{0}']), + ('\u{10cd7}', ['\u{10c97}', '\u{0}', '\u{0}']), + ('\u{10cd8}', ['\u{10c98}', '\u{0}', '\u{0}']), + ('\u{10cd9}', ['\u{10c99}', '\u{0}', '\u{0}']), + ('\u{10cda}', ['\u{10c9a}', '\u{0}', '\u{0}']), + ('\u{10cdb}', ['\u{10c9b}', '\u{0}', '\u{0}']), + ('\u{10cdc}', ['\u{10c9c}', '\u{0}', '\u{0}']), + ('\u{10cdd}', ['\u{10c9d}', '\u{0}', '\u{0}']), + ('\u{10cde}', ['\u{10c9e}', '\u{0}', '\u{0}']), + ('\u{10cdf}', ['\u{10c9f}', '\u{0}', '\u{0}']), + ('\u{10ce0}', ['\u{10ca0}', '\u{0}', '\u{0}']), + ('\u{10ce1}', ['\u{10ca1}', '\u{0}', '\u{0}']), + ('\u{10ce2}', ['\u{10ca2}', '\u{0}', '\u{0}']), + ('\u{10ce3}', ['\u{10ca3}', '\u{0}', '\u{0}']), + ('\u{10ce4}', ['\u{10ca4}', '\u{0}', '\u{0}']), + ('\u{10ce5}', ['\u{10ca5}', '\u{0}', '\u{0}']), + ('\u{10ce6}', ['\u{10ca6}', '\u{0}', '\u{0}']), + ('\u{10ce7}', ['\u{10ca7}', '\u{0}', '\u{0}']), + ('\u{10ce8}', ['\u{10ca8}', '\u{0}', '\u{0}']), + ('\u{10ce9}', ['\u{10ca9}', '\u{0}', '\u{0}']), + ('\u{10cea}', ['\u{10caa}', '\u{0}', '\u{0}']), + ('\u{10ceb}', ['\u{10cab}', '\u{0}', '\u{0}']), + ('\u{10cec}', ['\u{10cac}', '\u{0}', '\u{0}']), + ('\u{10ced}', ['\u{10cad}', '\u{0}', '\u{0}']), + ('\u{10cee}', ['\u{10cae}', '\u{0}', '\u{0}']), + ('\u{10cef}', ['\u{10caf}', '\u{0}', '\u{0}']), + ('\u{10cf0}', ['\u{10cb0}', '\u{0}', '\u{0}']), + ('\u{10cf1}', ['\u{10cb1}', '\u{0}', '\u{0}']), + ('\u{10cf2}', ['\u{10cb2}', '\u{0}', '\u{0}']), + ('\u{118c0}', ['\u{118a0}', '\u{0}', '\u{0}']), + ('\u{118c1}', ['\u{118a1}', '\u{0}', '\u{0}']), + ('\u{118c2}', ['\u{118a2}', '\u{0}', '\u{0}']), + ('\u{118c3}', ['\u{118a3}', '\u{0}', '\u{0}']), + ('\u{118c4}', ['\u{118a4}', '\u{0}', '\u{0}']), + ('\u{118c5}', ['\u{118a5}', '\u{0}', '\u{0}']), + ('\u{118c6}', ['\u{118a6}', '\u{0}', '\u{0}']), + ('\u{118c7}', ['\u{118a7}', '\u{0}', '\u{0}']), + ('\u{118c8}', ['\u{118a8}', '\u{0}', '\u{0}']), + ('\u{118c9}', ['\u{118a9}', '\u{0}', '\u{0}']), + ('\u{118ca}', ['\u{118aa}', '\u{0}', '\u{0}']), + ('\u{118cb}', ['\u{118ab}', '\u{0}', '\u{0}']), + ('\u{118cc}', ['\u{118ac}', '\u{0}', '\u{0}']), + ('\u{118cd}', ['\u{118ad}', '\u{0}', '\u{0}']), + ('\u{118ce}', ['\u{118ae}', '\u{0}', '\u{0}']), + ('\u{118cf}', ['\u{118af}', '\u{0}', '\u{0}']), + ('\u{118d0}', ['\u{118b0}', '\u{0}', '\u{0}']), + ('\u{118d1}', ['\u{118b1}', '\u{0}', '\u{0}']), + ('\u{118d2}', ['\u{118b2}', '\u{0}', '\u{0}']), + ('\u{118d3}', ['\u{118b3}', '\u{0}', '\u{0}']), + ('\u{118d4}', ['\u{118b4}', '\u{0}', '\u{0}']), + ('\u{118d5}', ['\u{118b5}', '\u{0}', '\u{0}']), + ('\u{118d6}', ['\u{118b6}', '\u{0}', '\u{0}']), + ('\u{118d7}', ['\u{118b7}', '\u{0}', '\u{0}']), + ('\u{118d8}', ['\u{118b8}', '\u{0}', '\u{0}']), + ('\u{118d9}', ['\u{118b9}', '\u{0}', '\u{0}']), + ('\u{118da}', ['\u{118ba}', '\u{0}', '\u{0}']), + ('\u{118db}', ['\u{118bb}', '\u{0}', '\u{0}']), + ('\u{118dc}', ['\u{118bc}', '\u{0}', '\u{0}']), + ('\u{118dd}', ['\u{118bd}', '\u{0}', '\u{0}']), + ('\u{118de}', ['\u{118be}', '\u{0}', '\u{0}']), + ('\u{118df}', ['\u{118bf}', '\u{0}', '\u{0}']), + ('\u{16e60}', ['\u{16e40}', '\u{0}', '\u{0}']), + ('\u{16e61}', ['\u{16e41}', '\u{0}', '\u{0}']), + ('\u{16e62}', ['\u{16e42}', '\u{0}', '\u{0}']), + ('\u{16e63}', ['\u{16e43}', '\u{0}', '\u{0}']), + ('\u{16e64}', ['\u{16e44}', '\u{0}', '\u{0}']), + ('\u{16e65}', ['\u{16e45}', '\u{0}', '\u{0}']), + ('\u{16e66}', ['\u{16e46}', '\u{0}', '\u{0}']), + ('\u{16e67}', ['\u{16e47}', '\u{0}', '\u{0}']), + ('\u{16e68}', ['\u{16e48}', '\u{0}', '\u{0}']), + ('\u{16e69}', ['\u{16e49}', '\u{0}', '\u{0}']), + ('\u{16e6a}', ['\u{16e4a}', '\u{0}', '\u{0}']), + ('\u{16e6b}', ['\u{16e4b}', '\u{0}', '\u{0}']), + ('\u{16e6c}', ['\u{16e4c}', '\u{0}', '\u{0}']), + ('\u{16e6d}', ['\u{16e4d}', '\u{0}', '\u{0}']), + ('\u{16e6e}', ['\u{16e4e}', '\u{0}', '\u{0}']), + ('\u{16e6f}', ['\u{16e4f}', '\u{0}', '\u{0}']), + ('\u{16e70}', ['\u{16e50}', '\u{0}', '\u{0}']), + ('\u{16e71}', ['\u{16e51}', '\u{0}', '\u{0}']), + ('\u{16e72}', ['\u{16e52}', '\u{0}', '\u{0}']), + ('\u{16e73}', ['\u{16e53}', '\u{0}', '\u{0}']), + ('\u{16e74}', ['\u{16e54}', '\u{0}', '\u{0}']), + ('\u{16e75}', ['\u{16e55}', '\u{0}', '\u{0}']), + ('\u{16e76}', ['\u{16e56}', '\u{0}', '\u{0}']), + ('\u{16e77}', ['\u{16e57}', '\u{0}', '\u{0}']), + ('\u{16e78}', ['\u{16e58}', '\u{0}', '\u{0}']), + ('\u{16e79}', ['\u{16e59}', '\u{0}', '\u{0}']), + ('\u{16e7a}', ['\u{16e5a}', '\u{0}', '\u{0}']), + ('\u{16e7b}', ['\u{16e5b}', '\u{0}', '\u{0}']), + ('\u{16e7c}', ['\u{16e5c}', '\u{0}', '\u{0}']), + ('\u{16e7d}', ['\u{16e5d}', '\u{0}', '\u{0}']), + ('\u{16e7e}', ['\u{16e5e}', '\u{0}', '\u{0}']), + ('\u{16e7f}', ['\u{16e5f}', '\u{0}', '\u{0}']), + ('\u{1e922}', ['\u{1e900}', '\u{0}', '\u{0}']), + ('\u{1e923}', ['\u{1e901}', '\u{0}', '\u{0}']), + ('\u{1e924}', ['\u{1e902}', '\u{0}', '\u{0}']), + ('\u{1e925}', ['\u{1e903}', '\u{0}', '\u{0}']), + ('\u{1e926}', ['\u{1e904}', '\u{0}', '\u{0}']), + ('\u{1e927}', ['\u{1e905}', '\u{0}', '\u{0}']), + ('\u{1e928}', ['\u{1e906}', '\u{0}', '\u{0}']), + ('\u{1e929}', ['\u{1e907}', '\u{0}', '\u{0}']), + ('\u{1e92a}', ['\u{1e908}', '\u{0}', '\u{0}']), + ('\u{1e92b}', ['\u{1e909}', '\u{0}', '\u{0}']), + ('\u{1e92c}', ['\u{1e90a}', '\u{0}', '\u{0}']), + ('\u{1e92d}', ['\u{1e90b}', '\u{0}', '\u{0}']), + ('\u{1e92e}', ['\u{1e90c}', '\u{0}', '\u{0}']), + ('\u{1e92f}', ['\u{1e90d}', '\u{0}', '\u{0}']), + ('\u{1e930}', ['\u{1e90e}', '\u{0}', '\u{0}']), + ('\u{1e931}', ['\u{1e90f}', '\u{0}', '\u{0}']), + ('\u{1e932}', ['\u{1e910}', '\u{0}', '\u{0}']), + ('\u{1e933}', ['\u{1e911}', '\u{0}', '\u{0}']), + ('\u{1e934}', ['\u{1e912}', '\u{0}', '\u{0}']), + ('\u{1e935}', ['\u{1e913}', '\u{0}', '\u{0}']), + ('\u{1e936}', ['\u{1e914}', '\u{0}', '\u{0}']), + ('\u{1e937}', ['\u{1e915}', '\u{0}', '\u{0}']), + ('\u{1e938}', ['\u{1e916}', '\u{0}', '\u{0}']), + ('\u{1e939}', ['\u{1e917}', '\u{0}', '\u{0}']), + ('\u{1e93a}', ['\u{1e918}', '\u{0}', '\u{0}']), + ('\u{1e93b}', ['\u{1e919}', '\u{0}', '\u{0}']), + ('\u{1e93c}', ['\u{1e91a}', '\u{0}', '\u{0}']), + ('\u{1e93d}', ['\u{1e91b}', '\u{0}', '\u{0}']), + ('\u{1e93e}', ['\u{1e91c}', '\u{0}', '\u{0}']), + ('\u{1e93f}', ['\u{1e91d}', '\u{0}', '\u{0}']), + ('\u{1e940}', ['\u{1e91e}', '\u{0}', '\u{0}']), + ('\u{1e941}', ['\u{1e91f}', '\u{0}', '\u{0}']), + ('\u{1e942}', ['\u{1e920}', '\u{0}', '\u{0}']), + ('\u{1e943}', ['\u{1e921}', '\u{0}', '\u{0}']), + ]; +} From 268a1ff3fbd234ecdacf8b2ac0985f18d91c9851 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 14 Jan 2020 16:18:21 -0800 Subject: [PATCH 062/169] Account for `Path`s on `is_suggestable_infer_ty` Fix #68162. --- src/librustc_typeck/collect.rs | 27 ++++-- .../ui/typeck/typeck_type_placeholder_item.rs | 7 ++ .../typeck_type_placeholder_item.stderr | 97 +++++++++++-------- 3 files changed, 86 insertions(+), 45 deletions(-) diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index ad750d5ab8341..dca3289747e4c 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1806,6 +1806,16 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { } } +fn are_suggestable_generic_args(generic_args: &[hir::GenericArg<'_>]) -> bool { + generic_args + .iter() + .filter_map(|arg| match arg { + hir::GenericArg::Type(ty) => Some(ty), + _ => None, + }) + .any(is_suggestable_infer_ty) +} + /// Whether `ty` is a type with `_` placeholders that can be infered. Used in diagnostics only to /// use inference to provide suggestions for the appropriate type if possible. fn is_suggestable_infer_ty(ty: &hir::Ty<'_>) -> bool { @@ -1815,13 +1825,16 @@ fn is_suggestable_infer_ty(ty: &hir::Ty<'_>) -> bool { Slice(ty) | Array(ty, _) => is_suggestable_infer_ty(ty), Tup(tys) => tys.iter().any(is_suggestable_infer_ty), Ptr(mut_ty) | Rptr(_, mut_ty) => is_suggestable_infer_ty(mut_ty.ty), - Def(_, generic_args) => generic_args - .iter() - .filter_map(|arg| match arg { - hir::GenericArg::Type(ty) => Some(ty), - _ => None, - }) - .any(is_suggestable_infer_ty), + Def(_, generic_args) => are_suggestable_generic_args(generic_args), + Path(hir::QPath::TypeRelative(ty, segment)) => { + is_suggestable_infer_ty(ty) || are_suggestable_generic_args(segment.generic_args().args) + } + Path(hir::QPath::Resolved(ty_opt, hir::Path { segments, .. })) => { + ty_opt.map_or(false, is_suggestable_infer_ty) + || segments + .iter() + .any(|segment| are_suggestable_generic_args(segment.generic_args().args)) + } _ => false, } } diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.rs b/src/test/ui/typeck/typeck_type_placeholder_item.rs index adecbd7e5b40e..86c7c52b27166 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.rs +++ b/src/test/ui/typeck/typeck_type_placeholder_item.rs @@ -68,6 +68,13 @@ struct Test10 { } pub fn main() { + static A = 42; + //~^ ERROR missing type for `static` item + static B: _ = 42; + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + static C: Option<_> = Some(42); + //~^ ERROR the type placeholder `_` is not allowed within types on item signatures + fn fn_test() -> _ { 5 } //~^ ERROR the type placeholder `_` is not allowed within types on item signatures diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.stderr b/src/test/ui/typeck/typeck_type_placeholder_item.stderr index 05326a3e07a93..f740a9f7f34b1 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.stderr +++ b/src/test/ui/typeck/typeck_type_placeholder_item.stderr @@ -1,35 +1,35 @@ error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:146:18 + --> $DIR/typeck_type_placeholder_item.rs:153:18 | LL | struct BadStruct<_>(_); | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:149:16 + --> $DIR/typeck_type_placeholder_item.rs:156:16 | LL | trait BadTrait<_> {} | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:159:19 + --> $DIR/typeck_type_placeholder_item.rs:166:19 | LL | struct BadStruct1<_, _>(_); | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:159:22 + --> $DIR/typeck_type_placeholder_item.rs:166:22 | LL | struct BadStruct1<_, _>(_); | ^ expected identifier, found reserved identifier error: expected identifier, found reserved identifier `_` - --> $DIR/typeck_type_placeholder_item.rs:164:19 + --> $DIR/typeck_type_placeholder_item.rs:171:19 | LL | struct BadStruct2<_, T>(_, T); | ^ expected identifier, found reserved identifier error[E0403]: the name `_` is already used for a generic parameter in this item's generic parameters - --> $DIR/typeck_type_placeholder_item.rs:159:22 + --> $DIR/typeck_type_placeholder_item.rs:166:22 | LL | struct BadStruct1<_, _>(_); | - ^ already used @@ -177,8 +177,29 @@ LL | LL | b: (T, T), | +error: missing type for `static` item + --> $DIR/typeck_type_placeholder_item.rs:71:12 + | +LL | static A = 42; + | ^ help: provide a type for the item: `A: i32` + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:73:15 + | +LL | static B: _ = 42; + | ^ + | | + | not allowed in type signatures + | help: replace `_` with the correct type: `i32` + +error[E0121]: the type placeholder `_` is not allowed within types on item signatures + --> $DIR/typeck_type_placeholder_item.rs:75:15 + | +LL | static C: Option<_> = Some(42); + | ^^^^^^^^^ not allowed in type signatures + error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:71:21 + --> $DIR/typeck_type_placeholder_item.rs:78:21 | LL | fn fn_test() -> _ { 5 } | ^ @@ -187,7 +208,7 @@ LL | fn fn_test() -> _ { 5 } | help: replace with the correct return type: `i32` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:74:23 + --> $DIR/typeck_type_placeholder_item.rs:81:23 | LL | fn fn_test2() -> (_, _) { (5, 5) } | -^--^- @@ -197,7 +218,7 @@ LL | fn fn_test2() -> (_, _) { (5, 5) } | help: replace with the correct return type: `(i32, i32)` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:77:22 + --> $DIR/typeck_type_placeholder_item.rs:84:22 | LL | static FN_TEST3: _ = "test"; | ^ @@ -206,7 +227,7 @@ LL | static FN_TEST3: _ = "test"; | help: replace `_` with the correct type: `&'static str` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:80:22 + --> $DIR/typeck_type_placeholder_item.rs:87:22 | LL | static FN_TEST4: _ = 145; | ^ @@ -215,13 +236,13 @@ LL | static FN_TEST4: _ = 145; | help: replace `_` with the correct type: `i32` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:83:22 + --> $DIR/typeck_type_placeholder_item.rs:90:22 | LL | static FN_TEST5: (_, _) = (1, 2); | ^^^^^^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:86:20 + --> $DIR/typeck_type_placeholder_item.rs:93:20 | LL | fn fn_test6(_: _) { } | ^ not allowed in type signatures @@ -232,7 +253,7 @@ LL | fn fn_test6(_: T) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:89:20 + --> $DIR/typeck_type_placeholder_item.rs:96:20 | LL | fn fn_test7(x: _) { let _x: usize = x; } | ^ not allowed in type signatures @@ -243,13 +264,13 @@ LL | fn fn_test7(x: T) { let _x: usize = x; } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:92:29 + --> $DIR/typeck_type_placeholder_item.rs:99:29 | LL | fn fn_test8(_f: fn() -> _) { } | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:92:29 + --> $DIR/typeck_type_placeholder_item.rs:99:29 | LL | fn fn_test8(_f: fn() -> _) { } | ^ not allowed in type signatures @@ -260,7 +281,7 @@ LL | fn fn_test8(_f: fn() -> T) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:115:12 + --> $DIR/typeck_type_placeholder_item.rs:122:12 | LL | a: _, | ^ not allowed in type signatures @@ -279,13 +300,13 @@ LL | b: (T, T), | error[E0282]: type annotations needed - --> $DIR/typeck_type_placeholder_item.rs:120:27 + --> $DIR/typeck_type_placeholder_item.rs:127:27 | LL | fn fn_test11(_: _) -> (_, _) { panic!() } | ^^^^^^ cannot infer type error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:120:28 + --> $DIR/typeck_type_placeholder_item.rs:127:28 | LL | fn fn_test11(_: _) -> (_, _) { panic!() } | ^ ^ not allowed in type signatures @@ -293,7 +314,7 @@ LL | fn fn_test11(_: _) -> (_, _) { panic!() } | not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:124:30 + --> $DIR/typeck_type_placeholder_item.rs:131:30 | LL | fn fn_test12(x: i32) -> (_, _) { (x, x) } | -^--^- @@ -303,7 +324,7 @@ LL | fn fn_test12(x: i32) -> (_, _) { (x, x) } | help: replace with the correct return type: `(i32, i32)` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:127:33 + --> $DIR/typeck_type_placeholder_item.rs:134:33 | LL | fn fn_test13(x: _) -> (i32, _) { (x, x) } | ------^- @@ -312,7 +333,7 @@ LL | fn fn_test13(x: _) -> (i32, _) { (x, x) } | help: replace with the correct return type: `(i32, i32)` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:146:21 + --> $DIR/typeck_type_placeholder_item.rs:153:21 | LL | struct BadStruct<_>(_); | ^ not allowed in type signatures @@ -323,7 +344,7 @@ LL | struct BadStruct(T); | ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:151:15 + --> $DIR/typeck_type_placeholder_item.rs:158:15 | LL | impl BadTrait<_> for BadStruct<_> {} | ^ ^ not allowed in type signatures @@ -336,13 +357,13 @@ LL | impl BadTrait for BadStruct {} | ^^^ ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:154:34 + --> $DIR/typeck_type_placeholder_item.rs:161:34 | LL | fn impl_trait() -> impl BadTrait<_> { | ^ not allowed in type signatures error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:159:25 + --> $DIR/typeck_type_placeholder_item.rs:166:25 | LL | struct BadStruct1<_, _>(_); | ^ not allowed in type signatures @@ -353,7 +374,7 @@ LL | struct BadStruct1(T); | ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:164:25 + --> $DIR/typeck_type_placeholder_item.rs:171:25 | LL | struct BadStruct2<_, T>(_, T); | ^ not allowed in type signatures @@ -364,7 +385,7 @@ LL | struct BadStruct2(K, T); | ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:168:14 + --> $DIR/typeck_type_placeholder_item.rs:175:14 | LL | type X = Box<_>; | ^ not allowed in type signatures @@ -381,7 +402,7 @@ LL | fn test10(&self, _x : T) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:132:31 + --> $DIR/typeck_type_placeholder_item.rs:139:31 | LL | fn method_test1(&self, x: _); | ^ not allowed in type signatures @@ -392,7 +413,7 @@ LL | fn method_test1(&self, x: T); | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:134:31 + --> $DIR/typeck_type_placeholder_item.rs:141:31 | LL | fn method_test2(&self, x: _) -> _; | ^ ^ not allowed in type signatures @@ -405,7 +426,7 @@ LL | fn method_test2(&self, x: T) -> T; | ^^^ ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:136:31 + --> $DIR/typeck_type_placeholder_item.rs:143:31 | LL | fn method_test3(&self) -> _; | ^ not allowed in type signatures @@ -416,7 +437,7 @@ LL | fn method_test3(&self) -> T; | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:138:26 + --> $DIR/typeck_type_placeholder_item.rs:145:26 | LL | fn assoc_fn_test1(x: _); | ^ not allowed in type signatures @@ -427,7 +448,7 @@ LL | fn assoc_fn_test1(x: T); | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:140:26 + --> $DIR/typeck_type_placeholder_item.rs:147:26 | LL | fn assoc_fn_test2(x: _) -> _; | ^ ^ not allowed in type signatures @@ -440,7 +461,7 @@ LL | fn assoc_fn_test2(x: T) -> T; | ^^^ ^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:142:28 + --> $DIR/typeck_type_placeholder_item.rs:149:28 | LL | fn assoc_fn_test3() -> _; | ^ not allowed in type signatures @@ -462,7 +483,7 @@ LL | fn clone_from(&mut self, other: T) { *self = Test9; } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:102:34 + --> $DIR/typeck_type_placeholder_item.rs:109:34 | LL | fn fn_test10(&self, _x : _) { } | ^ not allowed in type signatures @@ -473,7 +494,7 @@ LL | fn fn_test10(&self, _x : T) { } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:110:41 + --> $DIR/typeck_type_placeholder_item.rs:117:41 | LL | fn clone_from(&mut self, other: _) { *self = FnTest9; } | ^ not allowed in type signatures @@ -484,7 +505,7 @@ LL | fn clone_from(&mut self, other: T) { *self = FnTest9; } | ^^^ ^ error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:174:21 + --> $DIR/typeck_type_placeholder_item.rs:181:21 | LL | type Y = impl Trait<_>; | ^ not allowed in type signatures @@ -508,7 +529,7 @@ LL | fn clone(&self) -> _ { Test9 } | help: replace with the correct return type: `Test9` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:99:31 + --> $DIR/typeck_type_placeholder_item.rs:106:31 | LL | fn fn_test9(&self) -> _ { () } | ^ @@ -517,7 +538,7 @@ LL | fn fn_test9(&self) -> _ { () } | help: replace with the correct return type: `()` error[E0121]: the type placeholder `_` is not allowed within types on item signatures - --> $DIR/typeck_type_placeholder_item.rs:107:28 + --> $DIR/typeck_type_placeholder_item.rs:114:28 | LL | fn clone(&self) -> _ { FnTest9 } | ^ @@ -525,7 +546,7 @@ LL | fn clone(&self) -> _ { FnTest9 } | not allowed in type signatures | help: replace with the correct return type: `main::FnTest9` -error: aborting due to 55 previous errors +error: aborting due to 58 previous errors Some errors have detailed explanations: E0121, E0282, E0403. For more information about an error, try `rustc --explain E0121`. From 6801cf436bf3549db72c364a912da43ac38d0e79 Mon Sep 17 00:00:00 2001 From: Dylan DPC Date: Wed, 15 Jan 2020 11:52:21 +0530 Subject: [PATCH 063/169] Update E0170.md --- src/librustc_error_codes/error_codes/E0170.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_error_codes/error_codes/E0170.md b/src/librustc_error_codes/error_codes/E0170.md index 56e1b5aa241d2..9678cd173b7ca 100644 --- a/src/librustc_error_codes/error_codes/E0170.md +++ b/src/librustc_error_codes/error_codes/E0170.md @@ -1,4 +1,4 @@ -A pattern binding is using the same name as one of the variants a type. +A pattern binding is using the same name as one of the variants of a type. Erroneous code example: From 4eb47ded54610300c54291aee74d5585a711e75b Mon Sep 17 00:00:00 2001 From: csmoe Date: Wed, 15 Jan 2020 15:13:51 +0800 Subject: [PATCH 064/169] wrap expr id into GeneratorInteriorTypeCause --- src/librustc/traits/error_reporting.rs | 7 +++---- src/librustc/ty/context.rs | 7 ++++--- .../check/generator_interior.rs | 21 ++++++++++++------- src/test/ui/generator/not-send-sync.stderr | 2 +- .../recursive-impl-trait-type-indirect.stderr | 4 ++-- 5 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index aaad0be9a048c..c1df1149bbdfc 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -2456,7 +2456,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let target_span = tables .generator_interior_types .iter() - .find(|(ty::GeneratorInteriorTypeCause { ty, .. }, _)| { + .find(|ty::GeneratorInteriorTypeCause { ty, .. }| { // Careful: the regions for types that appear in the // generator interior are not generally known, so we // want to erase them when comparing (and anyway, @@ -2479,7 +2479,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ); eq }) - .map(|(ty::GeneratorInteriorTypeCause { span, scope_span, .. }, expr)| { + .map(|ty::GeneratorInteriorTypeCause { span, scope_span, expr, .. }| { (span, source_map.span_to_snippet(*span), scope_span, expr) }); @@ -2585,8 +2585,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { }; // Look at the last interior type to get a span for the `.await`. - let await_span = - tables.generator_interior_types.iter().map(|(i, _)| i.span).last().unwrap(); + let await_span = tables.generator_interior_types.iter().map(|t| t.span).last().unwrap(); let mut span = MultiSpan::from_span(await_span); span.push_span_label( await_span, diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index d64e049c47b54..ef776c88a8f7c 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -315,8 +315,7 @@ pub struct ResolvedOpaqueTy<'tcx> { /// /// Here, we would store the type `T`, the span of the value `x`, and the "scope-span" for /// the scope that contains `x`. -#[derive(RustcEncodable, RustcDecodable, Clone, Debug, Eq, Hash, PartialEq)] -#[derive(HashStable, TypeFoldable)] +#[derive(RustcEncodable, RustcDecodable, Clone, Debug, Eq, Hash, PartialEq, HashStable)] pub struct GeneratorInteriorTypeCause<'tcx> { /// Type of the captured binding. pub ty: Ty<'tcx>, @@ -324,6 +323,8 @@ pub struct GeneratorInteriorTypeCause<'tcx> { pub span: Span, /// Span of the scope of the captured binding. pub scope_span: Option, + /// Expr which the type evaluated from. + pub expr: Option, } #[derive(RustcEncodable, RustcDecodable, Debug)] @@ -438,7 +439,7 @@ pub struct TypeckTables<'tcx> { /// Stores the type, expression, span and optional scope span of all types /// that are live across the yield of this generator (if a generator). - pub generator_interior_types: Vec<(GeneratorInteriorTypeCause<'tcx>, Option)>, + pub generator_interior_types: Vec>, } impl<'tcx> TypeckTables<'tcx> { diff --git a/src/librustc_typeck/check/generator_interior.rs b/src/librustc_typeck/check/generator_interior.rs index 7185de76fcbb6..fc02d17a50f37 100644 --- a/src/librustc_typeck/check/generator_interior.rs +++ b/src/librustc_typeck/check/generator_interior.rs @@ -18,7 +18,6 @@ use rustc_span::Span; struct InteriorVisitor<'a, 'tcx> { fcx: &'a FnCtxt<'a, 'tcx>, types: FxHashMap, usize>, - exprs: Vec>, region_scope_tree: &'tcx region::ScopeTree, expr_count: usize, kind: hir::GeneratorKind, @@ -98,9 +97,9 @@ impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> { span: source_span, ty: &ty, scope_span, + expr: expr.map(|e| e.hir_id), }) .or_insert(entries); - self.exprs.push(expr.map(|e| e.hir_id)); } } else { debug!( @@ -138,7 +137,6 @@ pub fn resolve_interior<'a, 'tcx>( expr_count: 0, kind, prev_unresolved_span: None, - exprs: vec![], }; intravisit::walk_body(&mut visitor, body); @@ -167,18 +165,25 @@ pub fn resolve_interior<'a, 'tcx>( // which means that none of the regions inside relate to any other, even if // typeck had previously found constraints that would cause them to be related. let mut counter = 0; - let types = fcx.tcx.fold_regions(&types, &mut false, |_, current_depth| { + let fold_types: Vec<_> = types.iter().map(|(t, _)| t.ty).collect(); + let folded_types = fcx.tcx.fold_regions(&fold_types, &mut false, |_, current_depth| { counter += 1; fcx.tcx.mk_region(ty::ReLateBound(current_depth, ty::BrAnon(counter))) }); // Store the generator types and spans into the tables for this generator. - let interior_types = - types.iter().zip(visitor.exprs).map(|(t, e)| (t.0.clone(), e)).collect::>(); - visitor.fcx.inh.tables.borrow_mut().generator_interior_types = interior_types; + let types = types + .into_iter() + .zip(&folded_types) + .map(|((mut interior_cause, _), ty)| { + interior_cause.ty = ty; + interior_cause + }) + .collect(); + visitor.fcx.inh.tables.borrow_mut().generator_interior_types = types; // Extract type components - let type_list = fcx.tcx.mk_type_list(types.into_iter().map(|t| (t.0).ty)); + let type_list = fcx.tcx.mk_type_list(folded_types.iter()); let witness = fcx.tcx.mk_generator_witness(ty::Binder::bind(type_list)); diff --git a/src/test/ui/generator/not-send-sync.stderr b/src/test/ui/generator/not-send-sync.stderr index 0ac1d189b79b0..18d9012b3acf6 100644 --- a/src/test/ui/generator/not-send-sync.stderr +++ b/src/test/ui/generator/not-send-sync.stderr @@ -20,7 +20,7 @@ LL | fn assert_sync(_: T) {} LL | assert_sync(|| { | ^^^^^^^^^^^ future returned by `main` is not `Sync` | - = help: within `[generator@$DIR/not-send-sync.rs:9:17: 13:6 {std::cell::Cell, ()}]`, the trait `std::marker::Sync` is not implemented for `std::cell::Cell` + = help: within `[generator@$DIR/not-send-sync.rs:9:17: 13:6 {std::cell::Cell, (), ()}]`, the trait `std::marker::Sync` is not implemented for `std::cell::Cell` note: future is not `Sync` as this value is used across an yield --> $DIR/not-send-sync.rs:12:9 | diff --git a/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.stderr b/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.stderr index b7ba0d6ab177c..15a028f60ae11 100644 --- a/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.stderr +++ b/src/test/ui/impl-trait/recursive-impl-trait-type-indirect.stderr @@ -76,7 +76,7 @@ error[E0720]: opaque type expands to a recursive type LL | fn generator_capture() -> impl Sized { | ^^^^^^^^^^ expands to a recursive type | - = note: expanded type is `[generator@$DIR/recursive-impl-trait-type-indirect.rs:50:5: 50:26 x:impl Sized {()}]` + = note: expanded type is `[generator@$DIR/recursive-impl-trait-type-indirect.rs:50:5: 50:26 x:impl Sized {(), ()}]` error[E0720]: opaque type expands to a recursive type --> $DIR/recursive-impl-trait-type-indirect.rs:53:26 @@ -92,7 +92,7 @@ error[E0720]: opaque type expands to a recursive type LL | fn generator_hold() -> impl Sized { | ^^^^^^^^^^ expands to a recursive type | - = note: expanded type is `[generator@$DIR/recursive-impl-trait-type-indirect.rs:58:5: 62:6 {impl Sized, ()}]` + = note: expanded type is `[generator@$DIR/recursive-impl-trait-type-indirect.rs:58:5: 62:6 {impl Sized, (), ()}]` error[E0720]: opaque type expands to a recursive type --> $DIR/recursive-impl-trait-type-indirect.rs:69:26 From 0e14b9ff268b6987f935847d7857969a69b7ee7d Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 15 Jan 2020 10:30:26 +0100 Subject: [PATCH 065/169] Add tests --- src/test/ui/consts/huge-values.rs | 6 +++++ src/test/ui/consts/validate_never_arrays.rs | 6 ++++- .../ui/consts/validate_never_arrays.stderr | 22 ++++++++++++++++--- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/test/ui/consts/huge-values.rs b/src/test/ui/consts/huge-values.rs index ab09922d7614a..70a5b10e9be99 100644 --- a/src/test/ui/consts/huge-values.rs +++ b/src/test/ui/consts/huge-values.rs @@ -1,6 +1,10 @@ // build-pass // ignore-32bit +// This test is a canary test that will essentially not compile in a reasonable time frame +// (so it'll take hours) if any of the optimizations regress. With the optimizations, these compile +// in milliseconds just as if the length were set to `1`. + #[derive(Clone, Copy)] struct Foo; @@ -8,4 +12,6 @@ fn main() { let _ = [(); 4_000_000_000]; let _ = [0u8; 4_000_000_000]; let _ = [Foo; 4_000_000_000]; + let _ = [(Foo, (), Foo, ((), Foo, [0; 0])); 4_000_000_000]; + let _ = [[0; 0]; 4_000_000_000]; } diff --git a/src/test/ui/consts/validate_never_arrays.rs b/src/test/ui/consts/validate_never_arrays.rs index 9610b7b22f161..c7144f05ec7a4 100644 --- a/src/test/ui/consts/validate_never_arrays.rs +++ b/src/test/ui/consts/validate_never_arrays.rs @@ -1,5 +1,9 @@ #![feature(const_raw_ptr_deref, never_type)] -const FOO: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; //~ ERROR undefined behavior +const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; //~ ERROR undefined behavior +const _: &[!; 0] = unsafe { &*(1_usize as *const [!; 0]) }; // ok +const _: &[!] = unsafe { &*(1_usize as *const [!; 0]) }; // ok +const _: &[!] = unsafe { &*(1_usize as *const [!; 1]) }; //~ ERROR undefined behavior +const _: &[!] = unsafe { &*(1_usize as *const [!; 42]) }; //~ ERROR undefined behavior fn main() {} diff --git a/src/test/ui/consts/validate_never_arrays.stderr b/src/test/ui/consts/validate_never_arrays.stderr index c4c7a33718279..cb995b8216f4e 100644 --- a/src/test/ui/consts/validate_never_arrays.stderr +++ b/src/test/ui/consts/validate_never_arrays.stderr @@ -1,11 +1,27 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/validate_never_arrays.rs:3:1 | -LL | const FOO: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of an uninhabited type at . +LL | const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of an uninhabited type at . | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. -error: aborting due to previous error +error[E0080]: it is undefined behavior to use this value + --> $DIR/validate_never_arrays.rs:6:1 + | +LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 1]) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of an uninhabited type at .[0] + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + +error[E0080]: it is undefined behavior to use this value + --> $DIR/validate_never_arrays.rs:7:1 + | +LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 42]) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of an uninhabited type at .[0] + | + = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0080`. From 10f439a0116df86f737d83cc620289b14c88660f Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 25 Dec 2019 13:58:02 +0100 Subject: [PATCH 066/169] Promoteds can contain raw pointers, but these must still only point to immutable allocations --- src/librustc_mir/const_eval.rs | 4 +- src/librustc_mir/const_eval/eval_queries.rs | 13 ++++-- src/librustc_mir/interpret/intern.rs | 46 ++++++++++++++++----- src/librustc_mir/interpret/mod.rs | 2 +- src/librustc_mir/transform/const_prop.rs | 8 ++-- src/test/ui/consts/raw_pointer_promoted.rs | 5 +++ 6 files changed, 56 insertions(+), 22 deletions(-) create mode 100644 src/test/ui/consts/raw_pointer_promoted.rs diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index aa7be3d80e1dc..aad0e1629359a 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -5,7 +5,7 @@ use rustc::ty::layout::VariantIdx; use rustc::ty::{self, TyCtxt}; use rustc_span::{source_map::DUMMY_SP, symbol::Symbol}; -use crate::interpret::{intern_const_alloc_recursive, ConstValue, InterpCx}; +use crate::interpret::{intern_const_alloc_recursive, ConstValue, InternKind, InterpCx}; mod error; mod eval_queries; @@ -52,7 +52,7 @@ pub(crate) fn const_caller_location<'tcx>( let loc_ty = tcx.caller_location_ty(); let loc_place = ecx.alloc_caller_location(file, line, col); - intern_const_alloc_recursive(&mut ecx, None, loc_place, false).unwrap(); + intern_const_alloc_recursive(&mut ecx, InternKind::Constant, loc_place, false).unwrap(); let loc_const = ty::Const { ty: loc_ty, val: ty::ConstKind::Value(ConstValue::Scalar(loc_place.ptr.into())), diff --git a/src/librustc_mir/const_eval/eval_queries.rs b/src/librustc_mir/const_eval/eval_queries.rs index d260a6808d120..442baf85f2baf 100644 --- a/src/librustc_mir/const_eval/eval_queries.rs +++ b/src/librustc_mir/const_eval/eval_queries.rs @@ -1,9 +1,9 @@ use super::{error_to_const_error, CompileTimeEvalContext, CompileTimeInterpreter, MemoryExtra}; use crate::interpret::eval_nullary_intrinsic; use crate::interpret::{ - intern_const_alloc_recursive, Allocation, ConstValue, GlobalId, ImmTy, Immediate, InterpCx, - InterpResult, MPlaceTy, MemoryKind, OpTy, RawConst, RefTracking, Scalar, ScalarMaybeUndef, - StackPopCleanup, + intern_const_alloc_recursive, Allocation, ConstValue, GlobalId, ImmTy, Immediate, InternKind, + InterpCx, InterpResult, MPlaceTy, MemoryKind, OpTy, RawConst, RefTracking, Scalar, + ScalarMaybeUndef, StackPopCleanup, }; use rustc::mir; use rustc::mir::interpret::{ConstEvalErr, ErrorHandled}; @@ -56,9 +56,14 @@ fn eval_body_using_ecx<'mir, 'tcx>( ecx.run()?; // Intern the result + let intern_kind = match tcx.static_mutability(cid.instance.def_id()) { + Some(m) => InternKind::Static(m), + None if cid.promoted.is_some() => InternKind::Promoted, + _ => InternKind::Constant, + }; intern_const_alloc_recursive( ecx, - tcx.static_mutability(cid.instance.def_id()), + intern_kind, ret, body.ignore_interior_mut_in_const_validation, )?; diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index 220761ce28d81..8ff78ffb5baf9 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -268,19 +268,27 @@ impl<'rt, 'mir, 'tcx, M: CompileTimeMachine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx } } +pub enum InternKind { + /// The `mutability` of the static, ignoring the type which may have interior mutability. + Static(hir::Mutability), + Constant, + Promoted, + ConstProp, +} + pub fn intern_const_alloc_recursive>( ecx: &mut InterpCx<'mir, 'tcx, M>, - // The `mutability` of the place, ignoring the type. - place_mut: Option, + intern_kind: InternKind, ret: MPlaceTy<'tcx>, ignore_interior_mut_in_const_validation: bool, ) -> InterpResult<'tcx> { let tcx = ecx.tcx; - let (base_mutability, base_intern_mode) = match place_mut { + let (base_mutability, base_intern_mode) = match intern_kind { // `static mut` doesn't care about interior mutability, it's mutable anyway - Some(mutbl) => (mutbl, InternMode::Static), - // consts, promoteds. FIXME: what about array lengths, array initializers? - None => (Mutability::Not, InternMode::ConstBase), + InternKind::Static(mutbl) => (mutbl, InternMode::Static), + // FIXME: what about array lengths, array initializers? + InternKind::Constant | InternKind::ConstProp => (Mutability::Not, InternMode::ConstBase), + InternKind::Promoted => (Mutability::Not, InternMode::ConstBase), }; // Type based interning. @@ -338,10 +346,23 @@ pub fn intern_const_alloc_recursive>( // We can't call the `intern_shallow` method here, as its logic is tailored to safe // references and a `leftover_allocations` set (where we only have a todo-list here). // So we hand-roll the interning logic here again. - match base_intern_mode { - InternMode::Static => {} - InternMode::Const | InternMode::ConstBase => { - // If it's not a static, it *must* be immutable. + match intern_kind { + // Mutable statics may contain mutable allocations even behind relocations + InternKind::Static(hir::Mutability::Mut) => {} + // Once we get heap allocations we need to revisit whether immutable statics can + // refer to mutable (e.g. via interior mutability) allocations. + InternKind::Static(hir::Mutability::Not) => { + alloc.mutability = Mutability::Not; + } + // Raw pointers in promoteds may only point to immutable things so we mark + // everything as immutable. Creating a promoted with interior mutability is UB, but + // there's no way we can check whether the user is using raw pointers correctly. + // So all we can do is mark this as immutable here. + InternKind::Promoted => { + alloc.mutability = Mutability::Not; + } + InternKind::Constant | InternKind::ConstProp => { + // If it's a constant, it *must* be immutable. // We cannot have mutable memory inside a constant. // We use `delay_span_bug` here, because this can be reached in the presence // of fancy transmutes. @@ -363,7 +384,10 @@ pub fn intern_const_alloc_recursive>( } else if ecx.memory.dead_alloc_map.contains_key(&alloc_id) { // dangling pointer throw_unsup!(ValidationFailure("encountered dangling pointer in final constant".into())) - } else if ecx.tcx.alloc_map.lock().get(alloc_id).is_none() { + } else if let Some(_) = ecx.tcx.alloc_map.lock().get(alloc_id) { + // FIXME: check if the allocation is ok as per the interning rules as if we interned + // it right here. + } else { span_bug!(ecx.tcx.span, "encountered unknown alloc id {:?}", alloc_id); } } diff --git a/src/librustc_mir/interpret/mod.rs b/src/librustc_mir/interpret/mod.rs index 2e8fbb95ca2e5..a519f38e71208 100644 --- a/src/librustc_mir/interpret/mod.rs +++ b/src/librustc_mir/interpret/mod.rs @@ -32,6 +32,6 @@ pub use self::visitor::{MutValueVisitor, ValueVisitor}; pub use self::validity::RefTracking; -pub use self::intern::intern_const_alloc_recursive; +pub use self::intern::{intern_const_alloc_recursive, InternKind}; crate use self::intrinsics::eval_nullary_intrinsic; diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 1d5a643484a73..7dd82e6a6f9dc 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -29,9 +29,9 @@ use syntax::ast::Mutability; use crate::const_eval::error_to_const_error; use crate::interpret::{ - self, intern_const_alloc_recursive, AllocId, Allocation, Frame, ImmTy, Immediate, InterpCx, - LocalState, LocalValue, Memory, MemoryKind, OpTy, Operand as InterpOperand, PlaceTy, Pointer, - ScalarMaybeUndef, StackPopCleanup, + self, intern_const_alloc_recursive, AllocId, Allocation, Frame, ImmTy, Immediate, InternKind, + InterpCx, LocalState, LocalValue, Memory, MemoryKind, OpTy, Operand as InterpOperand, PlaceTy, + Pointer, ScalarMaybeUndef, StackPopCleanup, }; use crate::transform::{MirPass, MirSource}; @@ -726,7 +726,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { )) => l.is_bits() && r.is_bits(), interpret::Operand::Indirect(_) if mir_opt_level >= 2 => { let mplace = op.assert_mem_place(&self.ecx); - intern_const_alloc_recursive(&mut self.ecx, None, mplace, false) + intern_const_alloc_recursive(&mut self.ecx, InternKind::ConstProp, mplace, false) .expect("failed to intern alloc"); true } diff --git a/src/test/ui/consts/raw_pointer_promoted.rs b/src/test/ui/consts/raw_pointer_promoted.rs new file mode 100644 index 0000000000000..4c62ad444a512 --- /dev/null +++ b/src/test/ui/consts/raw_pointer_promoted.rs @@ -0,0 +1,5 @@ +// check-pass + +pub const FOO: &'static *const i32 = &(&0 as _); + +fn main() {} From 658c27b011b88dff18fd0137559123991a05f380 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Thu, 26 Dec 2019 00:30:02 +0100 Subject: [PATCH 067/169] Elaborate on comments --- src/librustc_mir/interpret/intern.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index 8ff78ffb5baf9..4c7dab338ab25 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -351,6 +351,9 @@ pub fn intern_const_alloc_recursive>( InternKind::Static(hir::Mutability::Mut) => {} // Once we get heap allocations we need to revisit whether immutable statics can // refer to mutable (e.g. via interior mutability) allocations. + // Note: this is never the base value of the static, we can only get here for + // pointers encountered inside the base allocation, and then only for ones not at + // reference type, as that is checked by the type based main interner. InternKind::Static(hir::Mutability::Not) => { alloc.mutability = Mutability::Not; } @@ -385,6 +388,17 @@ pub fn intern_const_alloc_recursive>( // dangling pointer throw_unsup!(ValidationFailure("encountered dangling pointer in final constant".into())) } else if let Some(_) = ecx.tcx.alloc_map.lock().get(alloc_id) { + // If we encounter an `AllocId` that points to a mutable `Allocation`, + // (directly or via relocations in its `Allocation`), we should panic, + // the static rules should prevent this. + // We may hit an `AllocId` that belongs to an already interned static, + // and are thus not interning any further. + // But since we are also checking things during interning, + // we should probably continue doing those checks no matter what we encounter. + + // E.g. this should be unreachable for `InternKind::Promoted` except for allocations + // created for string and byte string literals. + // FIXME: check if the allocation is ok as per the interning rules as if we interned // it right here. } else { From 1ea44663c562ac40fbb81f59698e3861d622695b Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 8 Jan 2020 10:16:47 +0100 Subject: [PATCH 068/169] Elaborate on the details in some comments --- src/librustc_mir/interpret/intern.rs | 29 +++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index 4c7dab338ab25..6008834a5731c 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -361,6 +361,9 @@ pub fn intern_const_alloc_recursive>( // everything as immutable. Creating a promoted with interior mutability is UB, but // there's no way we can check whether the user is using raw pointers correctly. // So all we can do is mark this as immutable here. + // It is UB to mutate through a raw pointer obtained via an immutable reference. + // Since all references and pointers inside a promoted must by their very definition + // be created from an immutable reference, mutating though them would be UB. InternKind::Promoted => { alloc.mutability = Mutability::Not; } @@ -388,19 +391,27 @@ pub fn intern_const_alloc_recursive>( // dangling pointer throw_unsup!(ValidationFailure("encountered dangling pointer in final constant".into())) } else if let Some(_) = ecx.tcx.alloc_map.lock().get(alloc_id) { - // If we encounter an `AllocId` that points to a mutable `Allocation`, - // (directly or via relocations in its `Allocation`), we should panic, - // the static rules should prevent this. - // We may hit an `AllocId` that belongs to an already interned static, + // We have hit an `AllocId` that belongs to an already interned static, // and are thus not interning any further. - // But since we are also checking things during interning, - // we should probably continue doing those checks no matter what we encounter. // E.g. this should be unreachable for `InternKind::Promoted` except for allocations - // created for string and byte string literals. + // created for string and byte string literals, since these are interned immediately + // at creation time. - // FIXME: check if the allocation is ok as per the interning rules as if we interned - // it right here. + // FIXME(oli-obk): Since we are also checking things during interning, + // we should probably continue doing those checks no matter what we encounter. + // So we basically have to check if the allocation is ok as per the interning rules as + // if we interned it right here. + // This should be as simple as + /* + for &(_, ((), reloc)) in alloc.relocations().iter() { + if leftover_allocations.insert(reloc) { + todo.push(reloc); + } + } + */ + // But I (oli-obk) haven't thought about the ramnificatons yet. This also would cause + // compile-time regressions, so we should think about caching these. } else { span_bug!(ecx.tcx.span, "encountered unknown alloc id {:?}", alloc_id); } From eadfd63e3fc136aee68fa32e98ea91213ef2e075 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Thu, 9 Jan 2020 17:14:54 +0100 Subject: [PATCH 069/169] Clean up comment --- src/librustc_mir/interpret/intern.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index 6008834a5731c..0cafd7cbbc0d6 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -358,12 +358,12 @@ pub fn intern_const_alloc_recursive>( alloc.mutability = Mutability::Not; } // Raw pointers in promoteds may only point to immutable things so we mark - // everything as immutable. Creating a promoted with interior mutability is UB, but - // there's no way we can check whether the user is using raw pointers correctly. - // So all we can do is mark this as immutable here. + // everything as immutable. // It is UB to mutate through a raw pointer obtained via an immutable reference. // Since all references and pointers inside a promoted must by their very definition // be created from an immutable reference, mutating though them would be UB. + // There's no way we can check whether the user is using raw pointers correctly, + // so all we can do is mark this as immutable here. InternKind::Promoted => { alloc.mutability = Mutability::Not; } @@ -394,7 +394,7 @@ pub fn intern_const_alloc_recursive>( // We have hit an `AllocId` that belongs to an already interned static, // and are thus not interning any further. - // E.g. this should be unreachable for `InternKind::Promoted` except for allocations + // For `InternKind::Promoted` this is only reachable for allocations // created for string and byte string literals, since these are interned immediately // at creation time. From b2c43dc1adcf1d264b981a506b1840ba42eeea7f Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Sat, 11 Jan 2020 14:45:00 +0100 Subject: [PATCH 070/169] Update src/librustc_mir/interpret/intern.rs Co-Authored-By: Ralf Jung --- src/librustc_mir/interpret/intern.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index 0cafd7cbbc0d6..6fd15cc79a22a 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -361,7 +361,8 @@ pub fn intern_const_alloc_recursive>( // everything as immutable. // It is UB to mutate through a raw pointer obtained via an immutable reference. // Since all references and pointers inside a promoted must by their very definition - // be created from an immutable reference, mutating though them would be UB. + // be created from an immutable reference (and promotion also excludes interior + // mutability), mutating though them would be UB. // There's no way we can check whether the user is using raw pointers correctly, // so all we can do is mark this as immutable here. InternKind::Promoted => { From a81784a09a084e63add1e4618dd82e8a7035c4f5 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Sat, 11 Jan 2020 15:01:58 +0100 Subject: [PATCH 071/169] Undo a change not neceesary for this bugfix --- src/librustc_mir/interpret/intern.rs | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index 6fd15cc79a22a..68ac945ca89a9 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -347,16 +347,10 @@ pub fn intern_const_alloc_recursive>( // references and a `leftover_allocations` set (where we only have a todo-list here). // So we hand-roll the interning logic here again. match intern_kind { - // Mutable statics may contain mutable allocations even behind relocations - InternKind::Static(hir::Mutability::Mut) => {} - // Once we get heap allocations we need to revisit whether immutable statics can - // refer to mutable (e.g. via interior mutability) allocations. - // Note: this is never the base value of the static, we can only get here for - // pointers encountered inside the base allocation, and then only for ones not at - // reference type, as that is checked by the type based main interner. - InternKind::Static(hir::Mutability::Not) => { - alloc.mutability = Mutability::Not; - } + // Statics may contain mutable allocations even behind relocations. + // Even for immutable statics it would be ok to have mutable allocations behind + // raw pointers, e.g. for `static FOO: *const AtomicUsize = &AtomicUsize::new(42)`. + InternKind::Static(_) => {} // Raw pointers in promoteds may only point to immutable things so we mark // everything as immutable. // It is UB to mutate through a raw pointer obtained via an immutable reference. From 7bd01ed3c46183253dd0c28d9efa8678c426599e Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 15 Jan 2020 11:33:49 +0100 Subject: [PATCH 072/169] Typo --- src/librustc_mir/interpret/intern.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index 68ac945ca89a9..cb028d286fa3d 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -356,7 +356,7 @@ pub fn intern_const_alloc_recursive>( // It is UB to mutate through a raw pointer obtained via an immutable reference. // Since all references and pointers inside a promoted must by their very definition // be created from an immutable reference (and promotion also excludes interior - // mutability), mutating though them would be UB. + // mutability), mutating through them would be UB. // There's no way we can check whether the user is using raw pointers correctly, // so all we can do is mark this as immutable here. InternKind::Promoted => { From 69ffe7bb1314ccfdbde419d242cf636413dfd5f6 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Wed, 15 Jan 2020 11:36:06 +0100 Subject: [PATCH 073/169] Address review comments --- src/librustc_mir/interpret/intern.rs | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/src/librustc_mir/interpret/intern.rs b/src/librustc_mir/interpret/intern.rs index cb028d286fa3d..0c65b77a38240 100644 --- a/src/librustc_mir/interpret/intern.rs +++ b/src/librustc_mir/interpret/intern.rs @@ -385,29 +385,9 @@ pub fn intern_const_alloc_recursive>( } else if ecx.memory.dead_alloc_map.contains_key(&alloc_id) { // dangling pointer throw_unsup!(ValidationFailure("encountered dangling pointer in final constant".into())) - } else if let Some(_) = ecx.tcx.alloc_map.lock().get(alloc_id) { - // We have hit an `AllocId` that belongs to an already interned static, - // and are thus not interning any further. - - // For `InternKind::Promoted` this is only reachable for allocations - // created for string and byte string literals, since these are interned immediately - // at creation time. - - // FIXME(oli-obk): Since we are also checking things during interning, - // we should probably continue doing those checks no matter what we encounter. - // So we basically have to check if the allocation is ok as per the interning rules as - // if we interned it right here. - // This should be as simple as - /* - for &(_, ((), reloc)) in alloc.relocations().iter() { - if leftover_allocations.insert(reloc) { - todo.push(reloc); - } - } - */ - // But I (oli-obk) haven't thought about the ramnificatons yet. This also would cause - // compile-time regressions, so we should think about caching these. - } else { + } else if ecx.tcx.alloc_map.lock().get(alloc_id).is_none() { + // We have hit an `AllocId` that is neither in local or global memory and isn't marked + // as dangling by local memory. span_bug!(ecx.tcx.span, "encountered unknown alloc id {:?}", alloc_id); } } From 12f029b7eecc01a38fbeec0eebe9041aa1bab7a5 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 10 Jan 2020 02:07:13 +0100 Subject: [PATCH 074/169] Fix deref impl on type alias --- src/librustdoc/clean/inline.rs | 18 ++++++++++++ src/librustdoc/clean/mod.rs | 24 ++++++++++++++-- src/librustdoc/clean/types.rs | 8 ++++++ src/librustdoc/html/render.rs | 24 +++++++++++----- src/librustdoc/html/render/cache.rs | 43 +++++++++++++++++------------ 5 files changed, 90 insertions(+), 27 deletions(-) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index c7e0f1e9e704b..fc75bf35b250d 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -273,6 +273,24 @@ fn build_type_alias(cx: &DocContext<'_>, did: DefId) -> clean::Typedef { clean::Typedef { type_: cx.tcx.type_of(did).clean(cx), generics: (cx.tcx.generics_of(did), predicates).clean(cx), + item_type: build_type_alias_type(cx, did), + } +} + +fn build_type_alias_type(cx: &DocContext<'_>, did: DefId) -> Option { + let type_ = cx.tcx.type_of(did).clean(cx); + type_.def_id().and_then(|did| build_ty(cx, did)) +} + +pub fn build_ty(cx: &DocContext, did: DefId) -> Option { + match cx.tcx.def_kind(did)? { + DefKind::Struct | + DefKind::Union | + DefKind::Enum | + DefKind::Const | + DefKind::Static => Some(cx.tcx.type_of(did).clean(cx)), + DefKind::TyAlias => build_type_alias_type(cx, did), + _ => None, } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index be9654612f504..0cc4c55f49be8 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1122,7 +1122,16 @@ impl Clean for hir::ImplItem<'_> { MethodItem((sig, &self.generics, body, Some(self.defaultness)).clean(cx)) } hir::ImplItemKind::TyAlias(ref ty) => { - TypedefItem(Typedef { type_: ty.clean(cx), generics: Generics::default() }, true) + let type_ = ty.clean(cx); + let item_type = type_.def_id().and_then(|did| inline::build_ty(cx, did)); + TypedefItem( + Typedef { + type_, + generics: Generics::default(), + item_type, + }, + true, + ) } hir::ImplItemKind::OpaqueTy(ref bounds) => OpaqueTyItem( OpaqueTy { bounds: bounds.clean(cx), generics: Generics::default() }, @@ -1282,10 +1291,13 @@ impl Clean for ty::AssocItem { AssocTypeItem(bounds, ty.clean(cx)) } else { + let type_ = cx.tcx.type_of(self.def_id).clean(cx); + let item_type = type_.def_id().and_then(|did| inline::build_ty(cx, did)); TypedefItem( Typedef { - type_: cx.tcx.type_of(self.def_id).clean(cx), + type_, generics: Generics { params: Vec::new(), where_predicates: Vec::new() }, + item_type, }, true, ) @@ -1989,6 +2001,8 @@ impl Clean for ast::Name { impl Clean for doctree::Typedef<'_> { fn clean(&self, cx: &DocContext<'_>) -> Item { + let type_ = self.ty.clean(cx); + let item_type = type_.def_id().and_then(|did| inline::build_ty(cx, did)); Item { name: Some(self.name.clean(cx)), attrs: self.attrs.clean(cx), @@ -1998,7 +2012,11 @@ impl Clean for doctree::Typedef<'_> { stability: cx.stability(self.id).clean(cx), deprecation: cx.deprecation(self.id).clean(cx), inner: TypedefItem( - Typedef { type_: self.ty.clean(cx), generics: self.gen.clean(cx) }, + Typedef { + type_, + generics: self.gen.clean(cx), + item_type, + }, false, ), } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 5d8e27ecadb82..79a078ca7a991 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1406,6 +1406,14 @@ pub struct PathSegment { pub struct Typedef { pub type_: Type, pub generics: Generics, + // Type of target item. + pub item_type: Option, +} + +impl GetDefId for Typedef { + fn def_id(&self) -> Option { + self.type_.def_id() + } } #[derive(Clone, Debug)] diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 2d932eb7668c4..69e268f3f80c1 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -3469,22 +3469,27 @@ fn render_deref_methods( deref_mut: bool, ) { let deref_type = impl_.inner_impl().trait_.as_ref().unwrap(); - let target = impl_ + let (target, real_target) = impl_ .inner_impl() .items .iter() .filter_map(|item| match item.inner { - clean::TypedefItem(ref t, true) => Some(&t.type_), + clean::TypedefItem(ref t, true) => { + Some(match *t { + clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, type_), + _ => (&t.type_, &t.type_), + }) + } _ => None, }) .next() .expect("Expected associated type binding"); let what = AssocItemRender::DerefFor { trait_: deref_type, type_: target, deref_mut_: deref_mut }; - if let Some(did) = target.def_id() { + if let Some(did) = real_target.def_id() { render_assoc_items(w, cx, container_item, did, what) } else { - if let Some(prim) = target.primitive_type() { + if let Some(prim) = real_target.primitive_type() { if let Some(&did) = cx.cache.primitive_locations.get(&prim) { render_assoc_items(w, cx, container_item, did, what); } @@ -4123,17 +4128,22 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { .filter(|i| i.inner_impl().trait_.is_some()) .find(|i| i.inner_impl().trait_.def_id() == c.deref_trait_did) { - if let Some(target) = impl_ + if let Some((target, real_target)) = impl_ .inner_impl() .items .iter() .filter_map(|item| match item.inner { - clean::TypedefItem(ref t, true) => Some(&t.type_), + clean::TypedefItem(ref t, true) => { + Some(match *t { + clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, type_), + _ => (&t.type_, &t.type_), + }) + } _ => None, }) .next() { - let inner_impl = target + let inner_impl = real_target .def_id() .or(target .primitive_type() diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index 22507443b0842..cdfd6b3073adf 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -277,7 +277,7 @@ impl DocFolder for Cache { | clean::StructFieldItem(..) | clean::VariantItem(..) => ( ( - Some(*self.parent_stack.last().unwrap()), + Some(*self.parent_stack.last().expect("parent_stack is empty")), Some(&self.stack[..self.stack.len() - 1]), ), false, @@ -286,7 +286,7 @@ impl DocFolder for Cache { if self.parent_stack.is_empty() { ((None, None), false) } else { - let last = self.parent_stack.last().unwrap(); + let last = self.parent_stack.last().expect("parent_stack is empty 2"); let did = *last; let path = match self.paths.get(&did) { // The current stack not necessarily has correlation @@ -468,7 +468,7 @@ impl DocFolder for Cache { self.impls.entry(did).or_insert(vec![]).push(impl_item.clone()); } } else { - let trait_did = impl_item.trait_did().unwrap(); + let trait_did = impl_item.trait_did().expect("no trait did"); self.orphan_trait_impls.push((trait_did, dids, impl_item)); } None @@ -478,10 +478,10 @@ impl DocFolder for Cache { }); if pushed { - self.stack.pop().unwrap(); + self.stack.pop().expect("stack already empty"); } if parent_pushed { - self.parent_stack.pop().unwrap(); + self.parent_stack.pop().expect("parent stack already empty"); } self.stripped_mod = orig_stripped_mod; self.parent_is_trait_impl = orig_parent_is_trait_impl; @@ -574,6 +574,9 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { // has since been learned. for &(did, ref item) in orphan_impl_items { if let Some(&(ref fqp, _)) = paths.get(&did) { + if item.name.is_none() { // this is most likely from a typedef + continue; + } search_index.push(IndexItem { ty: item.type_(), name: item.name.clone().unwrap(), @@ -592,19 +595,25 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { let mut lastpathid = 0usize; for item in search_index { - item.parent_idx = item.parent.map(|nodeid| { - if nodeid_to_pathid.contains_key(&nodeid) { - *nodeid_to_pathid.get(&nodeid).unwrap() - } else { - let pathid = lastpathid; - nodeid_to_pathid.insert(nodeid, pathid); - lastpathid += 1; + item.parent_idx = match item.parent { + Some(nodeid) => { + Some(if nodeid_to_pathid.contains_key(&nodeid) { + *nodeid_to_pathid.get(&nodeid).expect("no pathid") + } else { + let pathid = lastpathid; + nodeid_to_pathid.insert(nodeid, pathid); + lastpathid += 1; - let &(ref fqp, short) = paths.get(&nodeid).unwrap(); - crate_paths.push((short, fqp.last().unwrap().clone())); - pathid + if let Some(&(ref fqp, short)) = paths.get(&nodeid) { + crate_paths.push((short, fqp.last().expect("no fqp").clone())); + } else { + continue + } + pathid + }) } - }); + None => None, + }; // Omit the parent path if it is same to that of the prior item. if lastpath == item.path { @@ -639,7 +648,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { items: crate_items, paths: crate_paths, }) - .unwrap() + .expect("failed serde conversion") ) } From fd4a88f3098ab1b20267716102d49c8a43d151d8 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 10 Jan 2020 14:41:46 +0100 Subject: [PATCH 075/169] Add test for typedef deref --- src/test/rustdoc/deref-typedef.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/test/rustdoc/deref-typedef.rs diff --git a/src/test/rustdoc/deref-typedef.rs b/src/test/rustdoc/deref-typedef.rs new file mode 100644 index 0000000000000..b2dc20a5030e7 --- /dev/null +++ b/src/test/rustdoc/deref-typedef.rs @@ -0,0 +1,19 @@ +#![crate_name = "foo"] + +// @has 'foo/struct.Bar.html' +// @has '-' '//*[@id="deref-methods"]' 'Methods from Deref' +// @has '-' '//*[@class="impl-items"]//*[@id="method.happy"]' 'pub fn happy(&self)' +// @has '-' '//*[@class="sidebar-title"]' 'Methods from Deref' +// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.happy"]' 'happy' +pub struct FooA; +pub type FooB = FooA; + +impl FooA { + pub fn happy(&self) {} +} + +pub struct Bar; +impl std::ops::Deref for Bar { + type Target = FooB; + fn deref(&self) -> &FooB { unimplemented!() } +} From 81a5b94ac60cc1a9c8d365d8c6166c148279276c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 10 Jan 2020 14:46:28 +0100 Subject: [PATCH 076/169] formatting --- src/librustdoc/clean/inline.rs | 8 +++----- src/librustdoc/clean/mod.rs | 18 ++--------------- src/librustdoc/html/render.rs | 20 ++++++++----------- src/librustdoc/html/render/cache.rs | 31 ++++++++++++++--------------- 4 files changed, 28 insertions(+), 49 deletions(-) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index fc75bf35b250d..e54e716e042fe 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -284,11 +284,9 @@ fn build_type_alias_type(cx: &DocContext<'_>, did: DefId) -> Option pub fn build_ty(cx: &DocContext, did: DefId) -> Option { match cx.tcx.def_kind(did)? { - DefKind::Struct | - DefKind::Union | - DefKind::Enum | - DefKind::Const | - DefKind::Static => Some(cx.tcx.type_of(did).clean(cx)), + DefKind::Struct | DefKind::Union | DefKind::Enum | DefKind::Const | DefKind::Static => { + Some(cx.tcx.type_of(did).clean(cx)) + } DefKind::TyAlias => build_type_alias_type(cx, did), _ => None, } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 0cc4c55f49be8..027975a6d3288 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1124,14 +1124,7 @@ impl Clean for hir::ImplItem<'_> { hir::ImplItemKind::TyAlias(ref ty) => { let type_ = ty.clean(cx); let item_type = type_.def_id().and_then(|did| inline::build_ty(cx, did)); - TypedefItem( - Typedef { - type_, - generics: Generics::default(), - item_type, - }, - true, - ) + TypedefItem(Typedef { type_, generics: Generics::default(), item_type }, true) } hir::ImplItemKind::OpaqueTy(ref bounds) => OpaqueTyItem( OpaqueTy { bounds: bounds.clean(cx), generics: Generics::default() }, @@ -2011,14 +2004,7 @@ impl Clean for doctree::Typedef<'_> { visibility: self.vis.clean(cx), stability: cx.stability(self.id).clean(cx), deprecation: cx.deprecation(self.id).clean(cx), - inner: TypedefItem( - Typedef { - type_, - generics: self.gen.clean(cx), - item_type, - }, - false, - ), + inner: TypedefItem(Typedef { type_, generics: self.gen.clean(cx), item_type }, false), } } } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 69e268f3f80c1..86d59a0cccd9a 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -3474,12 +3474,10 @@ fn render_deref_methods( .items .iter() .filter_map(|item| match item.inner { - clean::TypedefItem(ref t, true) => { - Some(match *t { - clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, type_), - _ => (&t.type_, &t.type_), - }) - } + clean::TypedefItem(ref t, true) => Some(match *t { + clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, type_), + _ => (&t.type_, &t.type_), + }), _ => None, }) .next() @@ -4133,12 +4131,10 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { .items .iter() .filter_map(|item| match item.inner { - clean::TypedefItem(ref t, true) => { - Some(match *t { - clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, type_), - _ => (&t.type_, &t.type_), - }) - } + clean::TypedefItem(ref t, true) => Some(match *t { + clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, type_), + _ => (&t.type_, &t.type_), + }), _ => None, }) .next() diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index cdfd6b3073adf..fd9c47d0c4a44 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -574,7 +574,8 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { // has since been learned. for &(did, ref item) in orphan_impl_items { if let Some(&(ref fqp, _)) = paths.get(&did) { - if item.name.is_none() { // this is most likely from a typedef + if item.name.is_none() { + // this is most likely from a typedef continue; } search_index.push(IndexItem { @@ -596,22 +597,20 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { for item in search_index { item.parent_idx = match item.parent { - Some(nodeid) => { - Some(if nodeid_to_pathid.contains_key(&nodeid) { - *nodeid_to_pathid.get(&nodeid).expect("no pathid") - } else { - let pathid = lastpathid; - nodeid_to_pathid.insert(nodeid, pathid); - lastpathid += 1; + Some(nodeid) => Some(if nodeid_to_pathid.contains_key(&nodeid) { + *nodeid_to_pathid.get(&nodeid).expect("no pathid") + } else { + let pathid = lastpathid; + nodeid_to_pathid.insert(nodeid, pathid); + lastpathid += 1; - if let Some(&(ref fqp, short)) = paths.get(&nodeid) { - crate_paths.push((short, fqp.last().expect("no fqp").clone())); - } else { - continue - } - pathid - }) - } + if let Some(&(ref fqp, short)) = paths.get(&nodeid) { + crate_paths.push((short, fqp.last().expect("no fqp").clone())); + } else { + continue; + } + pathid + }), None => None, }; From 312c3a067a090dd7c970ba40c08909ca1281c312 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Wed, 15 Jan 2020 15:00:25 +0100 Subject: [PATCH 077/169] remove redundant clones, found by clippy --- src/librustc_driver/pretty.rs | 2 -- src/librustc_parse/parser/ty.rs | 2 +- src/librustc_resolve/imports.rs | 2 +- src/librustdoc/test.rs | 2 +- src/libtest/lib.rs | 4 ++-- 5 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 8804a05b596ee..6ef6dcf87eddb 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -429,7 +429,6 @@ pub fn print_after_hir_lowering<'tcx>( PpmSource(s) => { // Silently ignores an identified node. let out = &mut out; - let src = src.clone(); call_with_pp_support(&s, tcx.sess, Some(tcx), move |annotation| { debug!("pretty printing source code {:?}", s); let sess = annotation.sess(); @@ -447,7 +446,6 @@ pub fn print_after_hir_lowering<'tcx>( PpmHir(s) => { let out = &mut out; - let src = src.clone(); call_with_pp_support_hir(&s, tcx, move |annotation, krate| { debug!("pretty printing source code {:?}", s); let sess = annotation.sess(); diff --git a/src/librustc_parse/parser/ty.rs b/src/librustc_parse/parser/ty.rs index ea14aa278ac29..065a3b14428c7 100644 --- a/src/librustc_parse/parser/ty.rs +++ b/src/librustc_parse/parser/ty.rs @@ -500,7 +500,7 @@ impl<'a> Parser<'a> { err.span_suggestion_short( lo.to(self.prev_span), "remove the parentheses", - snippet.to_owned(), + snippet, Applicability::MachineApplicable, ); } diff --git a/src/librustc_resolve/imports.rs b/src/librustc_resolve/imports.rs index 8fe17e89444cd..5bd10303162b2 100644 --- a/src/librustc_resolve/imports.rs +++ b/src/librustc_resolve/imports.rs @@ -718,7 +718,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { } if !errors.is_empty() { - self.throw_unresolved_import_error(errors.clone(), None); + self.throw_unresolved_import_error(errors, None); } } diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index b5731ff0fec21..f899e722a5615 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -704,7 +704,7 @@ impl Tester for Collector { debug!("creating test {}: {}", name, test); self.tests.push(testing::TestDescAndFn { desc: testing::TestDesc { - name: testing::DynTestName(name.clone()), + name: testing::DynTestName(name), ignore: match config.ignore { Ignore::All => true, Ignore::None => false, diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 884db85efe0a2..45669d120c7c2 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -553,7 +553,7 @@ fn run_test_in_process( Err(e) => calc_result(&desc, Err(e.as_ref()), &time_opts, &exec_time), }; let stdout = data.lock().unwrap().to_vec(); - let message = CompletedTest::new(desc.clone(), test_result, exec_time, stdout); + let message = CompletedTest::new(desc, test_result, exec_time, stdout); monitor_ch.send(message).unwrap(); } @@ -602,7 +602,7 @@ fn spawn_test_subprocess( (result, test_output, exec_time) })(); - let message = CompletedTest::new(desc.clone(), result, exec_time, test_output); + let message = CompletedTest::new(desc, result, exec_time, test_output); monitor_ch.send(message).unwrap(); } From 6e791464bcabc3d64b8fd5de6f2217c67d81a8b1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 15 Jan 2020 13:56:11 +0100 Subject: [PATCH 078/169] remove unneeded code from cache.rs --- src/librustdoc/html/render/cache.rs | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index fd9c47d0c4a44..f1f83acdda59e 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -574,10 +574,6 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { // has since been learned. for &(did, ref item) in orphan_impl_items { if let Some(&(ref fqp, _)) = paths.get(&did) { - if item.name.is_none() { - // this is most likely from a typedef - continue; - } search_index.push(IndexItem { ty: item.type_(), name: item.name.clone().unwrap(), @@ -596,23 +592,19 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { let mut lastpathid = 0usize; for item in search_index { - item.parent_idx = match item.parent { - Some(nodeid) => Some(if nodeid_to_pathid.contains_key(&nodeid) { + item.parent_idx = item.parent.map(|nodeid| { + if nodeid_to_pathid.contains_key(&nodeid) { *nodeid_to_pathid.get(&nodeid).expect("no pathid") } else { let pathid = lastpathid; nodeid_to_pathid.insert(nodeid, pathid); lastpathid += 1; - if let Some(&(ref fqp, short)) = paths.get(&nodeid) { - crate_paths.push((short, fqp.last().expect("no fqp").clone())); - } else { - continue; - } + let &(ref fqp, short) = paths.get(&nodeid).unwrap(); + crate_paths.push((short, fqp.last().unwrap().clone())); pathid - }), - None => None, - }; + } + }); // Omit the parent path if it is same to that of the prior item. if lastpath == item.path { From 406049df4948a2c93d50f2c72cfa0e2811695ef5 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Wed, 15 Jan 2020 08:34:20 +0900 Subject: [PATCH 079/169] Add test for issue-64848 --- src/test/ui/associated-types/issue-64848.rs | 29 +++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/test/ui/associated-types/issue-64848.rs diff --git a/src/test/ui/associated-types/issue-64848.rs b/src/test/ui/associated-types/issue-64848.rs new file mode 100644 index 0000000000000..77712168a0fd9 --- /dev/null +++ b/src/test/ui/associated-types/issue-64848.rs @@ -0,0 +1,29 @@ +// build-pass + +trait AssociatedConstant { + const DATA: (); +} + +impl AssociatedConstant for F +where + F: FnOnce() -> T, + T: AssociatedConstant, +{ + const DATA: () = T::DATA; +} + +impl AssociatedConstant for () { + const DATA: () = (); +} + +fn foo() -> impl AssociatedConstant { + () +} + +fn get_data(_: T) -> &'static () { + &T::DATA +} + +fn main() { + get_data(foo); +} From ce8fed65f5e6f75b91cff35aec21190714231091 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Wed, 15 Jan 2020 08:34:33 +0900 Subject: [PATCH 080/169] Add test for issue-65918 --- .../ui/type-alias-impl-trait/issue-65918.rs | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/test/ui/type-alias-impl-trait/issue-65918.rs diff --git a/src/test/ui/type-alias-impl-trait/issue-65918.rs b/src/test/ui/type-alias-impl-trait/issue-65918.rs new file mode 100644 index 0000000000000..97efb85ef64c7 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/issue-65918.rs @@ -0,0 +1,49 @@ +// build-pass + +#![feature(type_alias_impl_trait)] + +use std::marker::PhantomData; + +/* copied Index and TryFrom for convinience (and simplicity) */ +trait MyIndex { + type O; + fn my_index(self) -> Self::O; +} +trait MyFrom: Sized { + type Error; + fn my_from(value: T) -> Result; +} + +/* MCVE starts here */ +trait F {} +impl F for () {} +type DummyT = impl F; +fn _dummy_t() -> DummyT {} + +struct Phantom1(PhantomData); +struct Phantom2(PhantomData); +struct Scope(Phantom2>); + +impl Scope { + fn new() -> Self { + unimplemented!() + } +} + +impl MyFrom> for Phantom1 { + type Error = (); + fn my_from(_: Phantom2) -> Result { + unimplemented!() + } +} + +impl>>, U> MyIndex> for Scope { + type O = T; + fn my_index(self) -> Self::O { + MyFrom::my_from(self.0).ok().unwrap() + } +} + +fn main() { + let _pos: Phantom1> = Scope::new().my_index(); +} From 27a810c719a1b9b245bb0b95e5774e3d092f7e6f Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Wed, 15 Jan 2020 08:34:51 +0900 Subject: [PATCH 081/169] Add test for issue-66473 --- src/test/ui/issues/issue-66473.rs | Bin 0 -> 113 bytes src/test/ui/issues/issue-66473.stderr | Bin 0 -> 2632 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/test/ui/issues/issue-66473.rs create mode 100644 src/test/ui/issues/issue-66473.stderr diff --git a/src/test/ui/issues/issue-66473.rs b/src/test/ui/issues/issue-66473.rs new file mode 100644 index 0000000000000000000000000000000000000000..cc298a28b97e5bc6e683fe5faee36d95d64720bf GIT binary patch literal 113 zcmdPbS4b@?$}iF_NGvHyEy}Y}D9y{x%P-GUC@x7XDpAN!Qz*&LPR--e$55DBQIMKk klA5BB5S^f-kd|MX2V|NhaB(T0?O?zFT->r|vJ4Dd0C6%O9{>OV literal 0 HcmV?d00001 diff --git a/src/test/ui/issues/issue-66473.stderr b/src/test/ui/issues/issue-66473.stderr new file mode 100644 index 0000000000000000000000000000000000000000..dbeef44bad0ec68b68ce3c3c06768df43587855c GIT binary patch literal 2632 zcmchZPfNov7>9d~pJDKV9_`%QrrFG4CojTIUX{_!W>N;p$R8D)cfXw9$xvZLWL*#A z&8d*`dqUuS@>A9tDc4fQLW2 g_IIdjtF^Jd)i2Nl6^kJh9ClW{wk9~}8l7Y82jcILL;wH) literal 0 HcmV?d00001 From 3ba15bda53272a73ee04b3d592ffb14d6ee177cb Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Wed, 15 Jan 2020 08:35:44 +0900 Subject: [PATCH 082/169] Set mir-opt-level to 3 to prevent regressions --- src/test/mir-opt/inline/inline-into-box-place.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/mir-opt/inline/inline-into-box-place.rs b/src/test/mir-opt/inline/inline-into-box-place.rs index 0bb9dfa403d58..f368bdef6f8e2 100644 --- a/src/test/mir-opt/inline/inline-into-box-place.rs +++ b/src/test/mir-opt/inline/inline-into-box-place.rs @@ -1,5 +1,6 @@ // ignore-tidy-linelength // ignore-wasm32-bare compiled with panic=abort by default +// compile-flags: -Z mir-opt-level=3 #![feature(box_syntax)] fn main() { From e6ad49aa67b7e6e0d9c5bc4bd68f44a009f91595 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 15 Jan 2020 15:07:27 +0100 Subject: [PATCH 083/169] Include type alias implementations --- src/librustdoc/html/render.rs | 53 +++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 86d59a0cccd9a..aafc7a8a10ff6 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2595,7 +2595,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait) } // If there are methods directly on this trait object, render them here. - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All); + render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All); let mut synthetic_types = Vec::new(); @@ -2942,7 +2942,7 @@ fn item_struct(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Struct } } } - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) } fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union) { @@ -2988,7 +2988,7 @@ fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union) document(w, cx, field); } } - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) } fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum) { @@ -3130,7 +3130,7 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum) { render_stability_since(w, variant, it); } } - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) } fn render_attribute(attr: &ast::MetaItem) -> Option { @@ -3344,7 +3344,7 @@ fn render_assoc_items( cx: &Context, containing_item: &clean::Item, it: DefId, - what: AssocItemRender<'_>, + what: &AssocItemRender<'_>, ) { let c = &cx.cache; let v = match c.impls.get(&it) { @@ -3377,7 +3377,7 @@ fn render_assoc_items( trait_.print(), type_.print() ); - RenderMode::ForDeref { mut_: deref_mut_ } + RenderMode::ForDeref { mut_: *deref_mut_ } } }; for i in &non_trait { @@ -3461,6 +3461,19 @@ fn render_assoc_items( } } +fn get_def_id(real_target: &clean::Type, cx: &Context) -> Option { + if let Some(did) = real_target.def_id() { + return Some(did); + } else { + if let Some(prim) = real_target.primitive_type() { + if let Some(&did) = cx.cache.primitive_locations.get(&prim) { + return Some(did); + } + } + } + None +} + fn render_deref_methods( w: &mut Buffer, cx: &Context, @@ -3475,23 +3488,21 @@ fn render_deref_methods( .iter() .filter_map(|item| match item.inner { clean::TypedefItem(ref t, true) => Some(match *t { - clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, type_), - _ => (&t.type_, &t.type_), + clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, Some(type_)), + _ => (&t.type_, None), }), _ => None, }) .next() .expect("Expected associated type binding"); + let did = get_def_id(&target, cx); let what = AssocItemRender::DerefFor { trait_: deref_type, type_: target, deref_mut_: deref_mut }; - if let Some(did) = real_target.def_id() { - render_assoc_items(w, cx, container_item, did, what) - } else { - if let Some(prim) = real_target.primitive_type() { - if let Some(&did) = cx.cache.primitive_locations.get(&prim) { - render_assoc_items(w, cx, container_item, did, what); - } - } + if let Some(did) = did { + render_assoc_items(w, cx, container_item, did, &what); + } + if let Some(did) = real_target.and_then(|x| get_def_id(x, cx)) { + render_assoc_items(w, cx, container_item, did, &what); } } @@ -3873,7 +3884,7 @@ fn item_opaque_ty(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Opa // won't be visible anywhere in the docs. It would be nice to also show // associated items from the aliased type (see discussion in #32077), but // we need #14072 to make sense of the generics. - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) } fn item_trait_alias(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::TraitAlias) { @@ -3894,7 +3905,7 @@ fn item_trait_alias(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::T // won't be visible anywhere in the docs. It would be nice to also show // associated items from the aliased type (see discussion in #32077), but // we need #14072 to make sense of the generics. - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) } fn item_typedef(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Typedef) { @@ -3915,7 +3926,7 @@ fn item_typedef(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Typed // won't be visible anywhere in the docs. It would be nice to also show // associated items from the aliased type (see discussion in #32077), but // we need #14072 to make sense of the generics. - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) } fn item_foreign_type(w: &mut Buffer, cx: &Context, it: &clean::Item) { @@ -3930,7 +3941,7 @@ fn item_foreign_type(w: &mut Buffer, cx: &Context, it: &clean::Item) { document(w, cx, it); - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) } fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer) { @@ -4602,7 +4613,7 @@ fn item_proc_macro(w: &mut Buffer, cx: &Context, it: &clean::Item, m: &clean::Pr fn item_primitive(w: &mut Buffer, cx: &Context, it: &clean::Item) { document(w, cx, it); - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) } fn item_keyword(w: &mut Buffer, cx: &Context, it: &clean::Item) { From f2fc35128b0592f6cdab3da1cf5da9ad8a0e2847 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Wed, 15 Jan 2020 00:00:00 +0000 Subject: [PATCH 084/169] Remove unused auxiliary file that was replaced with rust_test_helpers --- src/test/ui/rfcs/rfc1717/auxiliary/clibrary.rs | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 src/test/ui/rfcs/rfc1717/auxiliary/clibrary.rs diff --git a/src/test/ui/rfcs/rfc1717/auxiliary/clibrary.rs b/src/test/ui/rfcs/rfc1717/auxiliary/clibrary.rs deleted file mode 100644 index c1c5b70bc04e2..0000000000000 --- a/src/test/ui/rfcs/rfc1717/auxiliary/clibrary.rs +++ /dev/null @@ -1,5 +0,0 @@ -// no-prefer-dynamic -#![crate_type = "staticlib"] - -#[no_mangle] -pub extern "C" fn foo(x:i32) -> i32 { x } From 5d00b5c4aae885a247d783f5c274df9ef0539d0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Wed, 15 Jan 2020 00:00:00 +0000 Subject: [PATCH 085/169] Enable leak sanitizer test case * Use `black_box` to avoid memory leak removal during optimization. * Leak multiple objects to make test case more robust. --- src/test/run-make-fulldeps/sanitizer-leak/Makefile | 6 +----- src/test/run-make-fulldeps/sanitizer-leak/leak.rs | 11 +++++++++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/test/run-make-fulldeps/sanitizer-leak/Makefile b/src/test/run-make-fulldeps/sanitizer-leak/Makefile index d8598b8ac93f9..da370335ca918 100644 --- a/src/test/run-make-fulldeps/sanitizer-leak/Makefile +++ b/src/test/run-make-fulldeps/sanitizer-leak/Makefile @@ -1,11 +1,7 @@ -include ../tools.mk # needs-sanitizer-support -# only-linux -# only-x86_64 -# ignore-test -# FIXME(#46126) ThinLTO for libstd broke this test all: - $(RUSTC) -C opt-level=1 -g -Z sanitizer=leak -Z print-link-args leak.rs | $(CGREP) rustc_rt.lsan + $(RUSTC) -O -Z sanitizer=leak -Z print-link-args leak.rs | $(CGREP) rustc_rt.lsan $(TMPDIR)/leak 2>&1 | $(CGREP) 'detected memory leaks' diff --git a/src/test/run-make-fulldeps/sanitizer-leak/leak.rs b/src/test/run-make-fulldeps/sanitizer-leak/leak.rs index ab8df5c7bfd45..fb0a917dd98b6 100644 --- a/src/test/run-make-fulldeps/sanitizer-leak/leak.rs +++ b/src/test/run-make-fulldeps/sanitizer-leak/leak.rs @@ -1,6 +1,13 @@ +#![feature(test)] + +use std::hint::black_box; use std::mem; fn main() { - let xs = vec![1, 2, 3, 4]; - mem::forget(xs); + for _ in 0..10 { + let xs = vec![1, 2, 3]; + // Prevent compiler from removing the memory allocation. + let xs = black_box(xs); + mem::forget(xs); + } } From 33bc9ef513d632825ea600cfb4bb6d89f4a09269 Mon Sep 17 00:00:00 2001 From: SOFe Date: Wed, 15 Jan 2020 02:07:39 +0800 Subject: [PATCH 086/169] Use 3.6 instead of 3.5 in float fract() documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It is not self-explanatory whether the fract() function inverts the fractional part of negative numbers. Co-Authored-By: Mateusz Mikuła --- src/libstd/f32.rs | 8 ++++---- src/libstd/f64.rs | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs index 267d7013b1e42..209eea4a5ff73 100644 --- a/src/libstd/f32.rs +++ b/src/libstd/f32.rs @@ -131,10 +131,10 @@ impl f32 { /// ``` /// use std::f32; /// - /// let x = 3.5_f32; - /// let y = -3.5_f32; - /// let abs_difference_x = (x.fract() - 0.5).abs(); - /// let abs_difference_y = (y.fract() - (-0.5)).abs(); + /// let x = 3.6_f32; + /// let y = -3.6_f32; + /// let abs_difference_x = (x.fract() - 0.6).abs(); + /// let abs_difference_y = (y.fract() - (-0.6)).abs(); /// /// assert!(abs_difference_x <= f32::EPSILON); /// assert!(abs_difference_y <= f32::EPSILON); diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs index 61ce7b29e26fc..15fbb911d043a 100644 --- a/src/libstd/f64.rs +++ b/src/libstd/f64.rs @@ -109,10 +109,10 @@ impl f64 { /// # Examples /// /// ``` - /// let x = 3.5_f64; - /// let y = -3.5_f64; - /// let abs_difference_x = (x.fract() - 0.5).abs(); - /// let abs_difference_y = (y.fract() - (-0.5)).abs(); + /// let x = 3.6_f64; + /// let y = -3.6_f64; + /// let abs_difference_x = (x.fract() - 0.6).abs(); + /// let abs_difference_y = (y.fract() - (-0.6)).abs(); /// /// assert!(abs_difference_x < 1e-10); /// assert!(abs_difference_y < 1e-10); From d9d7877f0ea5aeca30322e80a26ef3916fc8b88e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 15 Jan 2020 20:03:22 +0100 Subject: [PATCH 087/169] update miri --- src/tools/miri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri b/src/tools/miri index 4e44aa010c4c7..6a0f14bef7784 160000 --- a/src/tools/miri +++ b/src/tools/miri @@ -1 +1 @@ -Subproject commit 4e44aa010c4c7d616182a3078cafb39da6f6c0a2 +Subproject commit 6a0f14bef7784e57a57a996cae3f94dbd2490e7a From d755238172ead0c619ac404487615534abc51ef1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 15 Jan 2020 18:52:04 +0100 Subject: [PATCH 088/169] Simplify deref impls for type aliases --- src/librustdoc/clean/mod.rs | 31 +++++++++++++++-- src/librustdoc/html/render.rs | 63 +++++++++++++++-------------------- 2 files changed, 55 insertions(+), 39 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 027975a6d3288..ae15b458fbaea 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2105,7 +2105,7 @@ impl Clean> for doctree::Impl<'_> { build_deref_target_impls(cx, &items, &mut ret); } - let provided = trait_ + let provided: FxHashSet = trait_ .def_id() .map(|did| { cx.tcx @@ -2116,6 +2116,33 @@ impl Clean> for doctree::Impl<'_> { }) .unwrap_or_default(); + let for_ = self.for_.clean(cx); + let type_alias = for_.def_id().and_then(|did| match cx.tcx.def_kind(did) { + Some(DefKind::TyAlias) => Some(cx.tcx.type_of(did).clean(cx)), + _ => None, + }); + if let Some(type_alias) = type_alias { + ret.push(Item { + name: None, + attrs: self.attrs.clean(cx), + source: self.whence.clean(cx), + def_id, + visibility: self.vis.clean(cx), + stability: cx.stability(self.id).clean(cx), + deprecation: cx.deprecation(self.id).clean(cx), + inner: ImplItem(Impl { + unsafety: self.unsafety, + generics: self.generics.clean(cx), + provided_trait_methods: provided.clone(), + trait_: trait_.clone(), + for_: type_alias, + items: items.clone(), + polarity: Some(cx.tcx.impl_polarity(def_id).clean(cx)), + synthetic: false, + blanket_impl: None, + }), + }); + } ret.push(Item { name: None, attrs: self.attrs.clean(cx), @@ -2129,7 +2156,7 @@ impl Clean> for doctree::Impl<'_> { generics: self.generics.clean(cx), provided_trait_methods: provided, trait_, - for_: self.for_.clean(cx), + for_, items, polarity: Some(cx.tcx.impl_polarity(def_id).clean(cx)), synthetic: false, diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index aafc7a8a10ff6..aaacae045b903 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2595,7 +2595,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait) } // If there are methods directly on this trait object, render them here. - render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All); + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All); let mut synthetic_types = Vec::new(); @@ -2942,7 +2942,7 @@ fn item_struct(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Struct } } } - render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) } fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union) { @@ -2988,7 +2988,7 @@ fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union) document(w, cx, field); } } - render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) } fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum) { @@ -3130,7 +3130,7 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum) { render_stability_since(w, variant, it); } } - render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) } fn render_attribute(attr: &ast::MetaItem) -> Option { @@ -3344,7 +3344,7 @@ fn render_assoc_items( cx: &Context, containing_item: &clean::Item, it: DefId, - what: &AssocItemRender<'_>, + what: AssocItemRender<'_>, ) { let c = &cx.cache; let v = match c.impls.get(&it) { @@ -3377,7 +3377,7 @@ fn render_assoc_items( trait_.print(), type_.print() ); - RenderMode::ForDeref { mut_: *deref_mut_ } + RenderMode::ForDeref { mut_: deref_mut_ } } }; for i in &non_trait { @@ -3461,19 +3461,6 @@ fn render_assoc_items( } } -fn get_def_id(real_target: &clean::Type, cx: &Context) -> Option { - if let Some(did) = real_target.def_id() { - return Some(did); - } else { - if let Some(prim) = real_target.primitive_type() { - if let Some(&did) = cx.cache.primitive_locations.get(&prim) { - return Some(did); - } - } - } - None -} - fn render_deref_methods( w: &mut Buffer, cx: &Context, @@ -3488,21 +3475,23 @@ fn render_deref_methods( .iter() .filter_map(|item| match item.inner { clean::TypedefItem(ref t, true) => Some(match *t { - clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, Some(type_)), - _ => (&t.type_, None), + clean::Typedef { item_type: Some(ref type_), .. } => (type_, &t.type_), + _ => (&t.type_, &t.type_), }), _ => None, }) .next() .expect("Expected associated type binding"); - let did = get_def_id(&target, cx); let what = - AssocItemRender::DerefFor { trait_: deref_type, type_: target, deref_mut_: deref_mut }; - if let Some(did) = did { - render_assoc_items(w, cx, container_item, did, &what); - } - if let Some(did) = real_target.and_then(|x| get_def_id(x, cx)) { - render_assoc_items(w, cx, container_item, did, &what); + AssocItemRender::DerefFor { trait_: deref_type, type_: real_target, deref_mut_: deref_mut }; + if let Some(did) = target.def_id() { + render_assoc_items(w, cx, container_item, did, what); + } else { + if let Some(prim) = target.primitive_type() { + if let Some(&did) = cx.cache.primitive_locations.get(&prim) { + render_assoc_items(w, cx, container_item, did, what); + } + } } } @@ -3884,7 +3873,7 @@ fn item_opaque_ty(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Opa // won't be visible anywhere in the docs. It would be nice to also show // associated items from the aliased type (see discussion in #32077), but // we need #14072 to make sense of the generics. - render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) } fn item_trait_alias(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::TraitAlias) { @@ -3905,7 +3894,7 @@ fn item_trait_alias(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::T // won't be visible anywhere in the docs. It would be nice to also show // associated items from the aliased type (see discussion in #32077), but // we need #14072 to make sense of the generics. - render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) } fn item_typedef(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Typedef) { @@ -3926,7 +3915,7 @@ fn item_typedef(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Typed // won't be visible anywhere in the docs. It would be nice to also show // associated items from the aliased type (see discussion in #32077), but // we need #14072 to make sense of the generics. - render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) } fn item_foreign_type(w: &mut Buffer, cx: &Context, it: &clean::Item) { @@ -3941,7 +3930,7 @@ fn item_foreign_type(w: &mut Buffer, cx: &Context, it: &clean::Item) { document(w, cx, it); - render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) } fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer) { @@ -4137,20 +4126,20 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { .filter(|i| i.inner_impl().trait_.is_some()) .find(|i| i.inner_impl().trait_.def_id() == c.deref_trait_did) { - if let Some((target, real_target)) = impl_ + if let Some(target) = impl_ .inner_impl() .items .iter() .filter_map(|item| match item.inner { clean::TypedefItem(ref t, true) => Some(match *t { - clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, type_), - _ => (&t.type_, &t.type_), + clean::Typedef { item_type: Some(ref type_), .. } => type_, + _ => &t.type_, }), _ => None, }) .next() { - let inner_impl = real_target + let inner_impl = target .def_id() .or(target .primitive_type() @@ -4613,7 +4602,7 @@ fn item_proc_macro(w: &mut Buffer, cx: &Context, it: &clean::Item, m: &clean::Pr fn item_primitive(w: &mut Buffer, cx: &Context, it: &clean::Item) { document(w, cx, it); - render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) } fn item_keyword(w: &mut Buffer, cx: &Context, it: &clean::Item) { From 8a9b951f578a1389507c7251b5c75258ac215bf9 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 15 Jan 2020 21:34:15 +0100 Subject: [PATCH 089/169] Fix rendering on sidebar and update tests --- src/librustdoc/html/render.rs | 8 ++++---- src/test/rustdoc/deref-typedef.rs | 28 +++++++++++++++++++++------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index aaacae045b903..9406803825350 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -4126,14 +4126,14 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { .filter(|i| i.inner_impl().trait_.is_some()) .find(|i| i.inner_impl().trait_.def_id() == c.deref_trait_did) { - if let Some(target) = impl_ + if let Some((target, real_target)) = impl_ .inner_impl() .items .iter() .filter_map(|item| match item.inner { clean::TypedefItem(ref t, true) => Some(match *t { - clean::Typedef { item_type: Some(ref type_), .. } => type_, - _ => &t.type_, + clean::Typedef { item_type: Some(ref type_), .. } => (type_, &t.type_), + _ => (&t.type_, &t.type_), }), _ => None, }) @@ -4153,7 +4153,7 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { "{:#}", impl_.inner_impl().trait_.as_ref().unwrap().print() )), - Escape(&format!("{:#}", target.print())) + Escape(&format!("{:#}", real_target.print())) )); out.push_str(""); let mut ret = impls diff --git a/src/test/rustdoc/deref-typedef.rs b/src/test/rustdoc/deref-typedef.rs index b2dc20a5030e7..770f8d7289c3b 100644 --- a/src/test/rustdoc/deref-typedef.rs +++ b/src/test/rustdoc/deref-typedef.rs @@ -1,19 +1,33 @@ #![crate_name = "foo"] // @has 'foo/struct.Bar.html' -// @has '-' '//*[@id="deref-methods"]' 'Methods from Deref' -// @has '-' '//*[@class="impl-items"]//*[@id="method.happy"]' 'pub fn happy(&self)' -// @has '-' '//*[@class="sidebar-title"]' 'Methods from Deref' -// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.happy"]' 'happy' +// @has '-' '//*[@id="deref-methods"]' 'Methods from Deref' +// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_a"]' 'pub fn foo_a(&self)' +// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_b"]' 'pub fn foo_b(&self)' +// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_c"]' 'pub fn foo_c(&self)' +// @has '-' '//*[@class="sidebar-title"]' 'Methods from Deref' +// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_a"]' 'foo_a' +// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_b"]' 'foo_b' +// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_c"]' 'foo_c' + pub struct FooA; pub type FooB = FooA; +pub type FooC = FooB; impl FooA { - pub fn happy(&self) {} + pub fn foo_a(&self) {} +} + +impl FooB { + pub fn foo_b(&self) {} +} + +impl FooC { + pub fn foo_c(&self) {} } pub struct Bar; impl std::ops::Deref for Bar { - type Target = FooB; - fn deref(&self) -> &FooB { unimplemented!() } + type Target = FooC; + fn deref(&self) -> &Self::Target { unimplemented!() } } From baf2921ebc5f5da879d00dd5fb529e5d274dce6b Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Wed, 15 Jan 2020 22:42:04 +0000 Subject: [PATCH 090/169] rustdoc: HTML escape codeblocks which fail syntax highlighting --- src/librustdoc/html/highlight.rs | 2 +- src/test/rustdoc/bad-codeblock-syntax.rs | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index fb6bdcdc9f48b..aa52b769c38ed 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -65,7 +65,7 @@ pub fn render_with_highlighting( Err(()) => { // If errors are encountered while trying to highlight, just emit // the unhighlighted source. - write!(out, "
{}
", src).unwrap(); + write!(out, "
{}
", Escape(src)).unwrap(); } } diff --git a/src/test/rustdoc/bad-codeblock-syntax.rs b/src/test/rustdoc/bad-codeblock-syntax.rs index 0ab2f68fcdebe..ae8fbe4a2a800 100644 --- a/src/test/rustdoc/bad-codeblock-syntax.rs +++ b/src/test/rustdoc/bad-codeblock-syntax.rs @@ -25,3 +25,11 @@ pub fn quux() {} /// \_ /// ``` pub fn ok() {} + +// @has bad_codeblock_syntax/fn.escape.html +// @has - '//*[@class="docblock"]/pre/code' '\_ ' +/// ``` +/// \_ +/// +/// ``` +pub fn escape() {} From ea64a3394312d65c95c7e74e7b8fa7e454685113 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Thu, 16 Jan 2020 00:00:00 +0000 Subject: [PATCH 091/169] Update sanitizer tests * Move tests from src/test/run-make-fulldeps to src/test/ui. * Fix memory sanitizer test to detect the intended issue rather than an unrelated one caused by the use of an uninstrumented std. --- .../sanitizer-address/Makefile | 30 ------------- .../sanitizer-address/overflow.rs | 4 -- .../sanitizer-invalid-target/Makefile | 5 --- .../sanitizer-invalid-target/hello.rs | 3 -- .../run-make-fulldeps/sanitizer-leak/Makefile | 7 --- .../sanitizer-memory/Makefile | 11 ----- .../sanitizer-memory/maybeuninit.rs | 8 ---- .../sanitizer-memory/uninit.rs | 7 --- src/test/ui/sanitizer-address.rs | 21 +++++++++ .../leak.rs => ui/sanitizer-leak.rs} | 8 ++++ src/test/ui/sanitizer-memory.rs | 44 +++++++++++++++++++ src/test/ui/sanitizer-unsupported-target.rs | 7 +++ .../ui/sanitizer-unsupported-target.stderr | 4 ++ 13 files changed, 84 insertions(+), 75 deletions(-) delete mode 100644 src/test/run-make-fulldeps/sanitizer-address/Makefile delete mode 100644 src/test/run-make-fulldeps/sanitizer-address/overflow.rs delete mode 100644 src/test/run-make-fulldeps/sanitizer-invalid-target/Makefile delete mode 100644 src/test/run-make-fulldeps/sanitizer-invalid-target/hello.rs delete mode 100644 src/test/run-make-fulldeps/sanitizer-leak/Makefile delete mode 100644 src/test/run-make-fulldeps/sanitizer-memory/Makefile delete mode 100644 src/test/run-make-fulldeps/sanitizer-memory/maybeuninit.rs delete mode 100644 src/test/run-make-fulldeps/sanitizer-memory/uninit.rs create mode 100644 src/test/ui/sanitizer-address.rs rename src/test/{run-make-fulldeps/sanitizer-leak/leak.rs => ui/sanitizer-leak.rs} (62%) create mode 100644 src/test/ui/sanitizer-memory.rs create mode 100644 src/test/ui/sanitizer-unsupported-target.rs create mode 100644 src/test/ui/sanitizer-unsupported-target.stderr diff --git a/src/test/run-make-fulldeps/sanitizer-address/Makefile b/src/test/run-make-fulldeps/sanitizer-address/Makefile deleted file mode 100644 index 7f5e9049b2f77..0000000000000 --- a/src/test/run-make-fulldeps/sanitizer-address/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# needs-sanitizer-support - --include ../tools.mk - -LOG := $(TMPDIR)/log.txt - -# NOTE the address sanitizer only supports x86_64 linux and macOS - -ifeq ($(TARGET),x86_64-apple-darwin) -EXTRA_RUSTFLAG=-C rpath -else -ifeq ($(TARGET),x86_64-unknown-linux-gnu) - -# Apparently there are very specific Linux kernels, notably the one that's -# currently on Travis CI, which contain a buggy commit that triggers failures in -# the ASan implementation, detailed at google/sanitizers#837. As noted in -# google/sanitizers#856 the "fix" is to avoid using PIE binaries, so we pass a -# different relocation model to avoid generating a PIE binary. Once Travis is no -# longer running kernel 4.4.0-93 we can remove this and pass an empty set of -# flags again. -EXTRA_RUSTFLAG=-C relocation-model=dynamic-no-pic -endif -endif - -all: - $(RUSTC) -g -Z sanitizer=address -Z print-link-args $(EXTRA_RUSTFLAG) overflow.rs | $(CGREP) rustc_rt.asan - # Verify that stack buffer overflow is detected: - $(TMPDIR)/overflow 2>&1 | $(CGREP) stack-buffer-overflow - # Verify that variable name is included in address sanitizer report: - $(TMPDIR)/overflow 2>&1 | $(CGREP) "'xs'" diff --git a/src/test/run-make-fulldeps/sanitizer-address/overflow.rs b/src/test/run-make-fulldeps/sanitizer-address/overflow.rs deleted file mode 100644 index b997a74cc3eb4..0000000000000 --- a/src/test/run-make-fulldeps/sanitizer-address/overflow.rs +++ /dev/null @@ -1,4 +0,0 @@ -fn main() { - let xs = [0, 1, 2, 3]; - let _y = unsafe { *xs.as_ptr().offset(4) }; -} diff --git a/src/test/run-make-fulldeps/sanitizer-invalid-target/Makefile b/src/test/run-make-fulldeps/sanitizer-invalid-target/Makefile deleted file mode 100644 index 2a23f0fe3d4ef..0000000000000 --- a/src/test/run-make-fulldeps/sanitizer-invalid-target/Makefile +++ /dev/null @@ -1,5 +0,0 @@ --include ../tools.mk - -all: - $(RUSTC) -Z sanitizer=leak --target i686-unknown-linux-gnu hello.rs 2>&1 | \ - $(CGREP) 'LeakSanitizer only works with the `x86_64-unknown-linux-gnu` or `x86_64-apple-darwin` target' diff --git a/src/test/run-make-fulldeps/sanitizer-invalid-target/hello.rs b/src/test/run-make-fulldeps/sanitizer-invalid-target/hello.rs deleted file mode 100644 index d3dd5ed03d954..0000000000000 --- a/src/test/run-make-fulldeps/sanitizer-invalid-target/hello.rs +++ /dev/null @@ -1,3 +0,0 @@ -#![feature(no_core)] -#![no_core] -#![no_main] diff --git a/src/test/run-make-fulldeps/sanitizer-leak/Makefile b/src/test/run-make-fulldeps/sanitizer-leak/Makefile deleted file mode 100644 index da370335ca918..0000000000000 --- a/src/test/run-make-fulldeps/sanitizer-leak/Makefile +++ /dev/null @@ -1,7 +0,0 @@ --include ../tools.mk - -# needs-sanitizer-support - -all: - $(RUSTC) -O -Z sanitizer=leak -Z print-link-args leak.rs | $(CGREP) rustc_rt.lsan - $(TMPDIR)/leak 2>&1 | $(CGREP) 'detected memory leaks' diff --git a/src/test/run-make-fulldeps/sanitizer-memory/Makefile b/src/test/run-make-fulldeps/sanitizer-memory/Makefile deleted file mode 100644 index 8bc9df1b4baeb..0000000000000 --- a/src/test/run-make-fulldeps/sanitizer-memory/Makefile +++ /dev/null @@ -1,11 +0,0 @@ --include ../tools.mk - -# needs-sanitizer-support -# only-linux -# only-x86_64 - -all: - $(RUSTC) -g -Z sanitizer=memory -Z print-link-args uninit.rs | $(CGREP) rustc_rt.msan - $(TMPDIR)/uninit 2>&1 | $(CGREP) use-of-uninitialized-value - $(RUSTC) -g -Z sanitizer=memory -Z print-link-args maybeuninit.rs | $(CGREP) rustc_rt.msan - $(TMPDIR)/maybeuninit 2>&1 | $(CGREP) use-of-uninitialized-value diff --git a/src/test/run-make-fulldeps/sanitizer-memory/maybeuninit.rs b/src/test/run-make-fulldeps/sanitizer-memory/maybeuninit.rs deleted file mode 100644 index a9ae85f57639e..0000000000000 --- a/src/test/run-make-fulldeps/sanitizer-memory/maybeuninit.rs +++ /dev/null @@ -1,8 +0,0 @@ -use std::mem::MaybeUninit; - -fn main() { - // This is technically not sound -- but we're literally trying to test - // that the sanitizer catches this, so I guess "intentionally unsound"? - let xs: [u8; 4] = unsafe { MaybeUninit::uninit().assume_init() }; - let y = xs[0] + xs[1]; -} diff --git a/src/test/run-make-fulldeps/sanitizer-memory/uninit.rs b/src/test/run-make-fulldeps/sanitizer-memory/uninit.rs deleted file mode 100644 index eae52508f6585..0000000000000 --- a/src/test/run-make-fulldeps/sanitizer-memory/uninit.rs +++ /dev/null @@ -1,7 +0,0 @@ -fn main() { - // This is technically not sound -- but we're literally trying to test - // that the sanitizer catches this, so I guess "intentionally unsound"? - #[allow(deprecated)] - let xs: [u8; 4] = unsafe { std::mem::uninitialized() }; - let y = xs[0] + xs[1]; -} diff --git a/src/test/ui/sanitizer-address.rs b/src/test/ui/sanitizer-address.rs new file mode 100644 index 0000000000000..d27a30a2dc55f --- /dev/null +++ b/src/test/ui/sanitizer-address.rs @@ -0,0 +1,21 @@ +// needs-sanitizer-support +// only-x86_64 +// +// compile-flags: -Z sanitizer=address -O +// +// run-fail +// error-pattern: AddressSanitizer: stack-buffer-overflow +// error-pattern: 'xs' <== Memory access at offset + +#![feature(test)] + +use std::hint::black_box; +use std::mem; + +fn main() { + let xs = [0, 1, 2, 3]; + // Avoid optimizing everything out. + let xs = black_box(xs.as_ptr()); + let code = unsafe { *xs.offset(4) }; + std::process::exit(code); +} diff --git a/src/test/run-make-fulldeps/sanitizer-leak/leak.rs b/src/test/ui/sanitizer-leak.rs similarity index 62% rename from src/test/run-make-fulldeps/sanitizer-leak/leak.rs rename to src/test/ui/sanitizer-leak.rs index fb0a917dd98b6..5c2f2cb4e868b 100644 --- a/src/test/run-make-fulldeps/sanitizer-leak/leak.rs +++ b/src/test/ui/sanitizer-leak.rs @@ -1,3 +1,11 @@ +// needs-sanitizer-support +// only-x86_64 +// +// compile-flags: -Z sanitizer=leak -O +// +// run-fail +// error-pattern: LeakSanitizer: detected memory leaks + #![feature(test)] use std::hint::black_box; diff --git a/src/test/ui/sanitizer-memory.rs b/src/test/ui/sanitizer-memory.rs new file mode 100644 index 0000000000000..3e1cf4509a31f --- /dev/null +++ b/src/test/ui/sanitizer-memory.rs @@ -0,0 +1,44 @@ +// needs-sanitizer-support +// only-linux +// only-x86_64 +// +// compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins -O +// +// run-fail +// error-pattern: MemorySanitizer: use-of-uninitialized-value +// error-pattern: Uninitialized value was created by an allocation +// error-pattern: in the stack frame of function 'random' +// +// This test case intentionally limits the usage of the std, +// since it will be linked with an uninstrumented version of it. + +#![feature(core_intrinsics)] +#![feature(start)] +#![feature(test)] + +use std::hint::black_box; +use std::mem::MaybeUninit; + +#[inline(never)] +#[no_mangle] +fn random() -> [isize; 32] { + let r = unsafe { MaybeUninit::uninit().assume_init() }; + // Avoid optimizing everything out. + black_box(r) +} + +#[inline(never)] +#[no_mangle] +fn xor(a: &[isize]) -> isize { + let mut s = 0; + for i in 0..a.len() { + s = s ^ a[i]; + } + s +} + +#[start] +fn main(_: isize, _: *const *const u8) -> isize { + let r = random(); + xor(&r) +} diff --git a/src/test/ui/sanitizer-unsupported-target.rs b/src/test/ui/sanitizer-unsupported-target.rs new file mode 100644 index 0000000000000..444333c3f01e2 --- /dev/null +++ b/src/test/ui/sanitizer-unsupported-target.rs @@ -0,0 +1,7 @@ +// ignore-tidy-linelength +// compile-flags: -Z sanitizer=leak --target i686-unknown-linux-gnu +// error-pattern: error: LeakSanitizer only works with the `x86_64-unknown-linux-gnu` or `x86_64-apple-darwin` target + +#![feature(no_core)] +#![no_core] +#![no_main] diff --git a/src/test/ui/sanitizer-unsupported-target.stderr b/src/test/ui/sanitizer-unsupported-target.stderr new file mode 100644 index 0000000000000..38be58dd4b365 --- /dev/null +++ b/src/test/ui/sanitizer-unsupported-target.stderr @@ -0,0 +1,4 @@ +error: LeakSanitizer only works with the `x86_64-unknown-linux-gnu` or `x86_64-apple-darwin` target + +error: aborting due to previous error + From bf0a7845d7860c681a6d273697dd1ca9d1cda81a Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Thu, 16 Jan 2020 10:55:29 +0900 Subject: [PATCH 092/169] Fix issue number of `member_constraints` --- .../unstable-book/src/language-features/member-constraints.md | 4 ++-- src/librustc_feature/active.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/unstable-book/src/language-features/member-constraints.md b/src/doc/unstable-book/src/language-features/member-constraints.md index 0d11c31aca6e9..3ba4a3e6b1f02 100644 --- a/src/doc/unstable-book/src/language-features/member-constraints.md +++ b/src/doc/unstable-book/src/language-features/member-constraints.md @@ -1,8 +1,8 @@ # `member_constraints` -The tracking issue for this feature is: [#61977] +The tracking issue for this feature is: [#61997] -[#61977]: https://github.com/rust-lang/rust/issues/61977 +[#61997]: https://github.com/rust-lang/rust/issues/61997 ------------------------ diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs index 319cd88f24586..0d1d1f8254439 100644 --- a/src/librustc_feature/active.rs +++ b/src/librustc_feature/active.rs @@ -481,7 +481,7 @@ declare_features! ( (active, arbitrary_enum_discriminant, "1.37.0", Some(60553), None), /// Allows `impl Trait` with multiple unrelated lifetimes. - (active, member_constraints, "1.37.0", Some(61977), None), + (active, member_constraints, "1.37.0", Some(61997), None), /// Allows `async || body` closures. (active, async_closure, "1.37.0", Some(62290), None), From 54b961658ba73f04d3603c8f839c1e36a7f989e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Str=C3=B8mberg?= Date: Thu, 16 Jan 2020 03:30:27 +0100 Subject: [PATCH 093/169] Update f32.rs --- src/libstd/f32.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs index 267d7013b1e42..375624e6797a7 100644 --- a/src/libstd/f32.rs +++ b/src/libstd/f32.rs @@ -355,7 +355,7 @@ impl f32 { return unsafe { intrinsics::powf32(self, n) }; } - /// Takes the square root of a number. + /// Returns the square root of a number. /// /// Returns NaN if `self` is a negative number. /// From 3f337b312d0cfec712fc56539a08b3ea9923bbf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Str=C3=B8mberg?= Date: Thu, 16 Jan 2020 03:34:23 +0100 Subject: [PATCH 094/169] Update f64.rs --- src/libstd/f64.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs index 61ce7b29e26fc..2dbd942f3324d 100644 --- a/src/libstd/f64.rs +++ b/src/libstd/f64.rs @@ -323,7 +323,7 @@ impl f64 { unsafe { intrinsics::powf64(self, n) } } - /// Takes the square root of a number. + /// Returns the square root of a number. /// /// Returns NaN if `self` is a negative number. /// @@ -506,7 +506,7 @@ impl f64 { unsafe { cmath::fdim(self, other) } } - /// Takes the cubic root of a number. + /// Returns the cubic root of a number. /// /// # Examples /// From d0db6d5791a75bb6e6f7ebe98067e78753fc1986 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Str=C3=B8mberg?= Date: Thu, 16 Jan 2020 03:35:31 +0100 Subject: [PATCH 095/169] Update f32.rs --- src/libstd/f32.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs index 375624e6797a7..171891b5dabc0 100644 --- a/src/libstd/f32.rs +++ b/src/libstd/f32.rs @@ -564,7 +564,7 @@ impl f32 { unsafe { cmath::fdimf(self, other) } } - /// Takes the cubic root of a number. + /// Returns the cubic root of a number. /// /// # Examples /// From 49d8aebbf36a254f1d527b90c72f07b4d23b2687 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Thu, 16 Jan 2020 11:58:28 +0900 Subject: [PATCH 096/169] Fix issue number of `repr128` --- src/doc/unstable-book/src/language-features/repr128.md | 4 ++-- src/librustc_feature/active.rs | 2 +- src/test/ui/error-codes/E0658.stderr | 2 +- src/test/ui/feature-gates/feature-gate-repr128.stderr | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/doc/unstable-book/src/language-features/repr128.md b/src/doc/unstable-book/src/language-features/repr128.md index 0858988952c10..146f50ee67b50 100644 --- a/src/doc/unstable-book/src/language-features/repr128.md +++ b/src/doc/unstable-book/src/language-features/repr128.md @@ -1,8 +1,8 @@ # `repr128` -The tracking issue for this feature is: [#35118] +The tracking issue for this feature is: [#56071] -[#35118]: https://github.com/rust-lang/rust/issues/35118 +[#56071]: https://github.com/rust-lang/rust/issues/56071 ------------------------ diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs index 0d1d1f8254439..4c8c47a567113 100644 --- a/src/librustc_feature/active.rs +++ b/src/librustc_feature/active.rs @@ -333,7 +333,7 @@ declare_features! ( (active, abi_ptx, "1.15.0", Some(38788), None), /// Allows the `#[repr(i128)]` attribute for enums. - (active, repr128, "1.16.0", Some(35118), None), + (active, repr128, "1.16.0", Some(56071), None), /// Allows `#[link(kind="static-nobundle"...)]`. (active, static_nobundle, "1.16.0", Some(37403), None), diff --git a/src/test/ui/error-codes/E0658.stderr b/src/test/ui/error-codes/E0658.stderr index 071dbccd80ba0..1cb81c8d778ec 100644 --- a/src/test/ui/error-codes/E0658.stderr +++ b/src/test/ui/error-codes/E0658.stderr @@ -6,7 +6,7 @@ LL | | Bar(u64), LL | | } | |_^ | - = note: for more information, see https://github.com/rust-lang/rust/issues/35118 + = note: for more information, see https://github.com/rust-lang/rust/issues/56071 = help: add `#![feature(repr128)]` to the crate attributes to enable error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-repr128.stderr b/src/test/ui/feature-gates/feature-gate-repr128.stderr index 2139a5da600df..e108d74e9c6cc 100644 --- a/src/test/ui/feature-gates/feature-gate-repr128.stderr +++ b/src/test/ui/feature-gates/feature-gate-repr128.stderr @@ -6,7 +6,7 @@ LL | | A(u64) LL | | } | |_^ | - = note: for more information, see https://github.com/rust-lang/rust/issues/35118 + = note: for more information, see https://github.com/rust-lang/rust/issues/56071 = help: add `#![feature(repr128)]` to the crate attributes to enable error: aborting due to previous error From 91c6a5aaeebacf444aba8d99cba0da945c0ce732 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Thu, 16 Jan 2020 11:59:04 +0900 Subject: [PATCH 097/169] Fix issue number of `infer_static_outlives_requirements` --- .../language-features/infer-static-outlives-requirements.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/unstable-book/src/language-features/infer-static-outlives-requirements.md b/src/doc/unstable-book/src/language-features/infer-static-outlives-requirements.md index 6187f395b0498..53e01091f754e 100644 --- a/src/doc/unstable-book/src/language-features/infer-static-outlives-requirements.md +++ b/src/doc/unstable-book/src/language-features/infer-static-outlives-requirements.md @@ -1,8 +1,8 @@ # `infer_static_outlives_requirements` -The tracking issue for this feature is: [#44493] +The tracking issue for this feature is: [#54185] -[#44493]: https://github.com/rust-lang/rust/issues/44493 +[#54185]: https://github.com/rust-lang/rust/issues/54185 ------------------------ The `infer_static_outlives_requirements` feature indicates that certain From c4d91aae5a72733479bab8df1aee78bb049b9735 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Thu, 16 Jan 2020 08:27:41 +0100 Subject: [PATCH 098/169] remove dead code The condition if obligation.recursion_depth >= 0 is always true since recursion_depth is usize. The else branch is dead code and can be removed. Found by Clippy. Fixes #68251 --- src/librustc/traits/select.rs | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index e96697cc7e09d..fb1c46834d3a0 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -3767,16 +3767,12 @@ impl<'tcx> TraitObligation<'tcx> { // NOTE(flaper87): As of now, it keeps track of the whole error // chain. Ideally, we should have a way to configure this either // by using -Z verbose or just a CLI argument. - if obligation.recursion_depth >= 0 { - let derived_cause = DerivedObligationCause { - parent_trait_ref: obligation.predicate.to_poly_trait_ref(), - parent_code: Rc::new(obligation.cause.code.clone()), - }; - let derived_code = variant(derived_cause); - ObligationCause::new(obligation.cause.span, obligation.cause.body_id, derived_code) - } else { - obligation.cause.clone() - } + let derived_cause = DerivedObligationCause { + parent_trait_ref: obligation.predicate.to_poly_trait_ref(), + parent_code: Rc::new(obligation.cause.code.clone()), + }; + let derived_code = variant(derived_cause); + ObligationCause::new(obligation.cause.span, obligation.cause.body_id, derived_code) } } From a1a0aea9e3830f4351f45f3a56c1adbca49be481 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 15 Jan 2020 13:36:54 +0100 Subject: [PATCH 099/169] clean up E0195 explanation --- src/librustc_error_codes/error_codes/E0195.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0195.md b/src/librustc_error_codes/error_codes/E0195.md index 3606521020a11..b8c313d412eba 100644 --- a/src/librustc_error_codes/error_codes/E0195.md +++ b/src/librustc_error_codes/error_codes/E0195.md @@ -1,4 +1,5 @@ -Your method's lifetime parameters do not match the trait declaration. +The lifetime parameters of the method do not match the trait declaration. + Erroneous code example: ```compile_fail,E0195 @@ -16,7 +17,7 @@ impl Trait for Foo { } ``` -The lifetime constraint `'b` for bar() implementation does not match the +The lifetime constraint `'b` for `bar()` implementation does not match the trait declaration. Ensure lifetime declarations match exactly in both trait declaration and implementation. Example: From 6f1bdb47f2a3bb24f60f8f27683991ddd2058b03 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 15 Jan 2020 13:37:01 +0100 Subject: [PATCH 100/169] clean up E0197 explanation --- src/librustc_error_codes/error_codes/E0197.md | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0197.md b/src/librustc_error_codes/error_codes/E0197.md index 0d91157e572cc..c142b8f3664c5 100644 --- a/src/librustc_error_codes/error_codes/E0197.md +++ b/src/librustc_error_codes/error_codes/E0197.md @@ -1,13 +1,20 @@ +An inherent implementation was marked unsafe. + +Erroneous code example: + +```compile_fail,E0197 +struct Foo; + +unsafe impl Foo { } // error! +``` + Inherent implementations (one that do not implement a trait but provide methods associated with a type) are always safe because they are not implementing an unsafe trait. Removing the `unsafe` keyword from the inherent implementation will resolve this error. -```compile_fail,E0197 +``` struct Foo; -// this will cause this error -unsafe impl Foo { } -// converting it to this will fix it -impl Foo { } +impl Foo { } // ok! ``` From 0e6a941820dcb39f5abab156e423cf3e28970c9f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 16 Jan 2020 14:19:37 +0100 Subject: [PATCH 101/169] Don't keep link title either, text is generated outside of the link tag --- src/librustdoc/html/markdown.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index b2f5c8e81ff7e..c87964af0200c 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -381,8 +381,7 @@ impl<'a, 'b, 'ids, I: Iterator>> Iterator for HeadingLinks<'a, _ => {} } match event { - Event::Start(Tag::Link(_, _, text)) => self.buf.push_back(Event::Text(text)), - Event::End(Tag::Link(..)) => {} + Event::Start(Tag::Link(_, _, _)) | Event::End(Tag::Link(..)) => {} event => self.buf.push_back(event), } } From 5022dd3b854792dd72d396e1586aa5b5c09975b2 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 16 Jan 2020 14:26:43 +0100 Subject: [PATCH 102/169] Extend url in titles test --- src/test/rustdoc/remove-url-from-headings.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/test/rustdoc/remove-url-from-headings.rs b/src/test/rustdoc/remove-url-from-headings.rs index 7fbcdbafa7486..50e45a7f53a1e 100644 --- a/src/test/rustdoc/remove-url-from-headings.rs +++ b/src/test/rustdoc/remove-url-from-headings.rs @@ -3,10 +3,15 @@ // @has foo/fn.foo.html // !@has - '//a[@href="http://a.a"]' // @has - '//a[@href="#implementing-stuff-somewhere"]' 'Implementing stuff somewhere' +// @has - '//a[@href="#another-one-urg"]' 'Another one urg' /// fooo /// /// # Implementing [stuff](http://a.a) somewhere /// /// hello +/// +/// # Another [one][two] urg +/// +/// [two]: http://a.a pub fn foo() {} From 25f1bf9a66c60eaced6eca70507f36cbc4ac6b44 Mon Sep 17 00:00:00 2001 From: flip1995 Date: Thu, 16 Jan 2020 16:07:54 +0100 Subject: [PATCH 103/169] Update Clippy --- src/tools/clippy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/clippy b/src/tools/clippy index 920cdb59e1edf..a8d90f6a57925 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit 920cdb59e1edf2c4cb2f266fa521f12c1b97a499 +Subproject commit a8d90f6a57925d204efb21b3f6d9726d6674f9bd From eed0d33a65bd3f315bdf2d26511676f61e95120e Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Thu, 16 Jan 2020 16:18:08 +0100 Subject: [PATCH 104/169] Array repeat expression lengths must be monomorphic at MIR building time --- src/librustc_mir_build/hair/cx/expr.rs | 27 ++++++++++--------- .../ui/consts/associated_const_generic.rs | 25 +++++++++++++++++ 2 files changed, 40 insertions(+), 12 deletions(-) create mode 100644 src/test/ui/consts/associated_const_generic.rs diff --git a/src/librustc_mir_build/hair/cx/expr.rs b/src/librustc_mir_build/hair/cx/expr.rs index 97e718118292d..d6786ea247973 100644 --- a/src/librustc_mir_build/hair/cx/expr.rs +++ b/src/librustc_mir_build/hair/cx/expr.rs @@ -411,18 +411,21 @@ fn make_mirror_unadjusted<'a, 'tcx>( let def_id = cx.tcx.hir().local_def_id(count.hir_id); let substs = InternalSubsts::identity_for_item(cx.tcx, def_id); let span = cx.tcx.def_span(def_id); - let count = - match cx.tcx.const_eval_resolve(cx.param_env, def_id, substs, None, Some(span)) { - Ok(cv) => cv.eval_usize(cx.tcx, cx.param_env), - Err(ErrorHandled::Reported) => 0, - Err(ErrorHandled::TooGeneric) => { - let span = cx.tcx.def_span(def_id); - cx.tcx - .sess - .span_err(span, "array lengths can't depend on generic parameters"); - 0 - } - }; + let count = match cx.tcx.const_eval_resolve( + ty::ParamEnv::reveal_all(), + def_id, + substs, + None, + Some(span), + ) { + Ok(cv) => cv.eval_usize(cx.tcx, ty::ParamEnv::reveal_all()), + Err(ErrorHandled::Reported) => 0, + Err(ErrorHandled::TooGeneric) => { + let span = cx.tcx.def_span(def_id); + cx.tcx.sess.span_err(span, "array lengths can't depend on generic parameters"); + 0 + } + }; ExprKind::Repeat { value: v.to_ref(), count } } diff --git a/src/test/ui/consts/associated_const_generic.rs b/src/test/ui/consts/associated_const_generic.rs new file mode 100644 index 0000000000000..dee376cc17b40 --- /dev/null +++ b/src/test/ui/consts/associated_const_generic.rs @@ -0,0 +1,25 @@ +// check-pass + +trait TraitA { + const VALUE: usize; +} + +struct A; +impl TraitA for A { + const VALUE: usize = 1; +} + +trait TraitB { + type MyA: TraitA; + const VALUE: usize = Self::MyA::VALUE; +} + +struct B; +impl TraitB for B { + type MyA = A; +} + +fn main() { + let _ = [0; A::VALUE]; + let _ = [0; B::VALUE]; // Indirectly refers to `A::VALUE` +} From 6fd564112f1ec00f6f8a56e8a3577dd255639131 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 13 Jan 2020 13:13:12 -0800 Subject: [PATCH 105/169] Specific error for unsized `dyn Trait` return type Suggest `impl Trait` when possible, and `Box` otherwise. --- src/librustc/traits/error_reporting.rs | 201 +++++++++++++++++- src/librustc/traits/mod.rs | 11 + src/librustc_error_codes/error_codes.rs | 1 + src/test/ui/error-codes/E0746.rs | 17 ++ src/test/ui/error-codes/E0746.stderr | 62 ++++++ .../dyn-trait-return-should-be-impl-trait.rs | 36 ++++ ...n-trait-return-should-be-impl-trait.stderr | 186 ++++++++++++++++ 7 files changed, 512 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/error-codes/E0746.rs create mode 100644 src/test/ui/error-codes/E0746.stderr create mode 100644 src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs create mode 100644 src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 7f151af7abe50..8f771658e4098 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1,3 +1,4 @@ +// ignore-tidy-filelength use super::{ ConstEvalFailure, EvaluationResult, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes, ObjectSafetyViolation, Obligation, ObligationCause, @@ -22,9 +23,12 @@ use crate::ty::TypeckTables; use crate::ty::{self, AdtKind, DefIdTree, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder, Style}; +use rustc_errors::{ + error_code, pluralize, struct_span_err, Applicability, DiagnosticBuilder, Style, +}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; +use rustc_hir::intravisit::Visitor; use rustc_hir::Node; use rustc_span::source_map::SourceMap; use rustc_span::symbol::{kw, sym}; @@ -758,7 +762,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { )), Some( "the question mark operation (`?`) implicitly performs a \ - conversion on the error value using the `From` trait" + conversion on the error value using the `From` trait" .to_owned(), ), ) @@ -835,6 +839,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { self.suggest_remove_reference(&obligation, &mut err, &trait_ref); self.suggest_semicolon_removal(&obligation, &mut err, span, &trait_ref); self.note_version_mismatch(&mut err, &trait_ref); + if self.suggest_impl_trait(&mut err, span, &obligation, &trait_ref) { + err.emit(); + return; + } // Try to report a help message if !trait_ref.has_infer_types() @@ -1696,6 +1704,195 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } + fn suggest_impl_trait( + &self, + err: &mut DiagnosticBuilder<'tcx>, + span: Span, + obligation: &PredicateObligation<'tcx>, + trait_ref: &ty::Binder>, + ) -> bool { + if let ObligationCauseCode::SizedReturnType = obligation.cause.code.peel_derives() { + } else { + return false; + } + + let hir = self.tcx.hir(); + let parent_node = hir.get_parent_node(obligation.cause.body_id); + let node = hir.find(parent_node); + if let Some(hir::Node::Item(hir::Item { + kind: hir::ItemKind::Fn(sig, _, body_id), .. + })) = node + { + let body = hir.body(*body_id); + let trait_ref = self.resolve_vars_if_possible(trait_ref); + let ty = trait_ref.skip_binder().self_ty(); + if let ty::Dynamic(..) = ty.kind { + } else { + // We only want to suggest `impl Trait` to `dyn Trait`s. + // For example, `fn foo() -> str` needs to be filtered out. + return false; + } + // Use `TypeVisitor` instead of the output type directly to find the span of `ty` for + // cases like `fn foo() -> (dyn Trait, i32) {}`. + // Recursively look for `TraitObject` types and if there's only one, use that span to + // suggest `impl Trait`. + + struct ReturnsVisitor<'v>(Vec<&'v hir::Expr<'v>>); + + impl<'v> Visitor<'v> for ReturnsVisitor<'v> { + type Map = rustc::hir::map::Map<'v>; + + fn nested_visit_map(&mut self) -> hir::intravisit::NestedVisitorMap<'_, Self::Map> { + hir::intravisit::NestedVisitorMap::None + } + + fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { + match ex.kind { + hir::ExprKind::Ret(Some(ex)) => self.0.push(ex), + _ => {} + } + hir::intravisit::walk_expr(self, ex); + } + + fn visit_body(&mut self, body: &'v hir::Body<'v>) { + if body.generator_kind().is_none() { + if let hir::ExprKind::Block(block, None) = body.value.kind { + if let Some(expr) = block.expr { + self.0.push(expr); + } + } + } + hir::intravisit::walk_body(self, body); + } + } + + // Visit to make sure there's a single `return` type to suggest `impl Trait`, + // otherwise suggest using `Box` or an enum. + let mut visitor = ReturnsVisitor(vec![]); + visitor.visit_body(&body); + + let tables = self.in_progress_tables.map(|t| t.borrow()).unwrap(); + + if let hir::FunctionRetTy::Return(ret_ty) = sig.decl.output { + let mut all_returns_conform_to_trait = true; + let mut all_returns_have_same_type = true; + let mut last_ty = None; + if let Some(ty_ret_ty) = tables.node_type_opt(ret_ty.hir_id) { + let cause = ObligationCause::misc(ret_ty.span, ret_ty.hir_id); + if let ty::Dynamic(predicates, _) = &ty_ret_ty.kind { + for predicate in predicates.iter() { + for expr in &visitor.0 { + if let Some(returned_ty) = tables.node_type_opt(expr.hir_id) { + if let Some(ty) = last_ty { + all_returns_have_same_type &= ty == returned_ty; + } + last_ty = Some(returned_ty); + + let param_env = ty::ParamEnv::empty(); + let pred = predicate.with_self_ty(self.tcx, returned_ty); + let obligation = + Obligation::new(cause.clone(), param_env, pred); + all_returns_conform_to_trait &= + self.predicate_may_hold(&obligation); + } + } + } + } + } else { + // We still want to verify whether all the return types conform to each other. + for expr in &visitor.0 { + if let Some(returned_ty) = tables.node_type_opt(expr.hir_id) { + if let Some(ty) = last_ty { + all_returns_have_same_type &= ty == returned_ty; + } + last_ty = Some(returned_ty); + } + } + } + + if let (true, hir::TyKind::TraitObject(..), Ok(snippet), true, Some(last_ty)) = ( + ret_ty.span.overlaps(span), + &ret_ty.kind, + self.tcx.sess.source_map().span_to_snippet(ret_ty.span), + all_returns_conform_to_trait, + last_ty, + ) { + err.code = Some(error_code!(E0746)); + err.set_primary_message( + "return type cannot have a bare trait because it must be `Sized`", + ); + err.children.clear(); + let impl_trait_msg = "for information on `impl Trait`, see \ + "; + let trait_obj_msg = "for information on trait objects, see \ + "; + let has_dyn = snippet.split_whitespace().next().map_or(false, |s| s == "dyn"); + let trait_obj = if has_dyn { &snippet[4..] } else { &snippet[..] }; + if all_returns_have_same_type { + err.span_suggestion( + ret_ty.span, + &format!( + "you can use the `impl Trait` feature \ + in the return type because all the return paths are of type \ + `{}`, which implements `dyn {}`", + last_ty, trait_obj, + ), + format!("impl {}", trait_obj), + Applicability::MaybeIncorrect, + ); + err.note(impl_trait_msg); + } else { + let mut suggestions = visitor + .0 + .iter() + .map(|expr| { + ( + expr.span, + format!( + "Box::new({})", + self.tcx + .sess + .source_map() + .span_to_snippet(expr.span) + .unwrap() + ), + ) + }) + .collect::>(); + suggestions.push(( + ret_ty.span, + format!("Box<{}{}>", if has_dyn { "" } else { "dyn " }, snippet), + )); + err.multipart_suggestion( + "if the performance implications are acceptable, you can return a \ + trait object", + suggestions, + Applicability::MaybeIncorrect, + ); + err.span_help( + visitor.0.iter().map(|expr| expr.span).collect::>(), + &format!( + "if all the returned values were of the same type you could use \ + `impl {}` as the return type", + trait_obj, + ), + ); + err.help( + "alternatively, you can always create a new `enum` with a variant \ + for each returned type", + ); + err.note(impl_trait_msg); + err.note(trait_obj_msg); + } + return true; + } + } + } + false + } + /// Given some node representing a fn-like thing in the HIR map, /// returns a span and `ArgKind` information that describes the /// arguments it expects. This can be supplied to diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 31de5409fc8be..f68711c06205b 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -1171,6 +1171,17 @@ impl<'tcx> ObligationCause<'tcx> { } } +impl<'tcx> ObligationCauseCode<'tcx> { + pub fn peel_derives(&self) -> &Self { + match self { + BuiltinDerivedObligation(cause) | ImplDerivedObligation(cause) => { + cause.parent_code.peel_derives() + } + _ => self, + } + } +} + impl<'tcx, N> Vtable<'tcx, N> { pub fn nested_obligations(self) -> Vec { match self { diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs index 272147e28a419..c17cb7dd9f161 100644 --- a/src/librustc_error_codes/error_codes.rs +++ b/src/librustc_error_codes/error_codes.rs @@ -608,4 +608,5 @@ E0745: include_str!("./error_codes/E0745.md"), E0726, // non-explicit (not `'_`) elided lifetime in unsupported position E0727, // `async` generators are not yet supported E0739, // invalid track_caller application/syntax + E0746, // `dyn Trait` return type } diff --git a/src/test/ui/error-codes/E0746.rs b/src/test/ui/error-codes/E0746.rs new file mode 100644 index 0000000000000..ad257b01e1b40 --- /dev/null +++ b/src/test/ui/error-codes/E0746.rs @@ -0,0 +1,17 @@ +struct Struct; +trait Trait {} +impl Trait for Struct {} +impl Trait for u32 {} + +fn foo() -> dyn Trait { Struct } +//~^ ERROR E0746 +//~| ERROR E0308 + +fn bar() -> dyn Trait { //~ ERROR E0746 + if true { + return 0; //~ ERROR E0308 + } + 42 //~ ERROR E0308 +} + +fn main() {} diff --git a/src/test/ui/error-codes/E0746.stderr b/src/test/ui/error-codes/E0746.stderr new file mode 100644 index 0000000000000..baafcd27c29d4 --- /dev/null +++ b/src/test/ui/error-codes/E0746.stderr @@ -0,0 +1,62 @@ +error[E0308]: mismatched types + --> $DIR/E0746.rs:6:25 + | +LL | fn foo() -> dyn Trait { Struct } + | --------- ^^^^^^ expected trait `Trait`, found struct `Struct` + | | + | expected `(dyn Trait + 'static)` because of return type + | + = note: expected trait object `(dyn Trait + 'static)` + found struct `Struct` + +error[E0746]: return type cannot have a bare trait because it must be `Sized` + --> $DIR/E0746.rs:6:13 + | +LL | fn foo() -> dyn Trait { Struct } + | ^^^^^^^^^ doesn't have a size known at compile-time + | + = note: for information on `impl Trait`, see +help: you can use the `impl Trait` feature in the return type because all the return paths are of type `Struct`, which implements `dyn Trait` + | +LL | fn foo() -> impl Trait { Struct } + | ^^^^^^^^^^ + +error[E0746]: return type cannot have a bare trait because it must be `Sized` + --> $DIR/E0746.rs:10:13 + | +LL | fn bar() -> dyn Trait { + | ^^^^^^^^^ doesn't have a size known at compile-time + | + = note: for information on `impl Trait`, see +help: you can use the `impl Trait` feature in the return type because all the return paths are of type `{integer}`, which implements `dyn Trait` + | +LL | fn bar() -> impl Trait { + | ^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/E0746.rs:12:16 + | +LL | fn bar() -> dyn Trait { + | --------- expected `(dyn Trait + 'static)` because of return type +LL | if true { +LL | return 0; + | ^ expected trait `Trait`, found integer + | + = note: expected trait object `(dyn Trait + 'static)` + found type `{integer}` + +error[E0308]: mismatched types + --> $DIR/E0746.rs:14:5 + | +LL | fn bar() -> dyn Trait { + | --------- expected `(dyn Trait + 'static)` because of return type +... +LL | 42 + | ^^ expected trait `Trait`, found integer + | + = note: expected trait object `(dyn Trait + 'static)` + found type `{integer}` + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs new file mode 100644 index 0000000000000..80168ca825774 --- /dev/null +++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs @@ -0,0 +1,36 @@ +#![allow(bare_trait_objects)] +struct Struct; +trait Trait {} +impl Trait for Struct {} +impl Trait for u32 {} + +fn fuz() -> (usize, Trait) { (42, Struct) } +//~^ ERROR E0277 +//~| ERROR E0308 +fn bar() -> (usize, dyn Trait) { (42, Struct) } +//~^ ERROR E0277 +//~| ERROR E0308 +fn bap() -> Trait { Struct } +//~^ ERROR E0746 +//~| ERROR E0308 +fn ban() -> dyn Trait { Struct } +//~^ ERROR E0746 +//~| ERROR E0308 +fn bak() -> dyn Trait { unimplemented!() } //~ ERROR E0277 +// Suggest using `Box` +fn bal() -> dyn Trait { //~ ERROR E0746 + if true { + return Struct; //~ ERROR E0308 + } + 42 //~ ERROR E0308 +} + +// Suggest using `impl Trait` +fn bat() -> dyn Trait { //~ ERROR E0746 + if true { + return 0; //~ ERROR E0308 + } + 42 //~ ERROR E0308 +} + +fn main() {} diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr new file mode 100644 index 0000000000000..ce4c141a0af9d --- /dev/null +++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr @@ -0,0 +1,186 @@ +error[E0308]: mismatched types + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:7:35 + | +LL | fn fuz() -> (usize, Trait) { (42, Struct) } + | ^^^^^^ expected trait `Trait`, found struct `Struct` + | + = note: expected trait object `(dyn Trait + 'static)` + found struct `Struct` + +error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:7:13 + | +LL | fn fuz() -> (usize, Trait) { (42, Struct) } + | ^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: within `(usize, (dyn Trait + 'static))`, the trait `std::marker::Sized` is not implemented for `(dyn Trait + 'static)` + = note: to learn more, visit + = note: required because it appears within the type `(usize, (dyn Trait + 'static))` + = note: the return type of a function must have a statically known size + +error[E0308]: mismatched types + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:10:39 + | +LL | fn bar() -> (usize, dyn Trait) { (42, Struct) } + | ^^^^^^ expected trait `Trait`, found struct `Struct` + | + = note: expected trait object `(dyn Trait + 'static)` + found struct `Struct` + +error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:10:13 + | +LL | fn bar() -> (usize, dyn Trait) { (42, Struct) } + | ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: within `(usize, (dyn Trait + 'static))`, the trait `std::marker::Sized` is not implemented for `(dyn Trait + 'static)` + = note: to learn more, visit + = note: required because it appears within the type `(usize, (dyn Trait + 'static))` + = note: the return type of a function must have a statically known size + +error[E0308]: mismatched types + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:13:21 + | +LL | fn bap() -> Trait { Struct } + | ----- ^^^^^^ expected trait `Trait`, found struct `Struct` + | | + | expected `(dyn Trait + 'static)` because of return type + | + = note: expected trait object `(dyn Trait + 'static)` + found struct `Struct` + +error[E0746]: return type cannot have a bare trait because it must be `Sized` + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:13:13 + | +LL | fn bap() -> Trait { Struct } + | ^^^^^ doesn't have a size known at compile-time + | + = note: for information on `impl Trait`, see +help: you can use the `impl Trait` feature in the return type because all the return paths are of type `Struct`, which implements `dyn Trait` + | +LL | fn bap() -> impl Trait { Struct } + | ^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:16:25 + | +LL | fn ban() -> dyn Trait { Struct } + | --------- ^^^^^^ expected trait `Trait`, found struct `Struct` + | | + | expected `(dyn Trait + 'static)` because of return type + | + = note: expected trait object `(dyn Trait + 'static)` + found struct `Struct` + +error[E0746]: return type cannot have a bare trait because it must be `Sized` + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:16:13 + | +LL | fn ban() -> dyn Trait { Struct } + | ^^^^^^^^^ doesn't have a size known at compile-time + | + = note: for information on `impl Trait`, see +help: you can use the `impl Trait` feature in the return type because all the return paths are of type `Struct`, which implements `dyn Trait` + | +LL | fn ban() -> impl Trait { Struct } + | ^^^^^^^^^^ + +error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:19:13 + | +LL | fn bak() -> dyn Trait { unimplemented!() } + | ^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `std::marker::Sized` is not implemented for `(dyn Trait + 'static)` + = note: to learn more, visit + = note: the return type of a function must have a statically known size + +error[E0308]: mismatched types + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:23:16 + | +LL | fn bal() -> dyn Trait { + | --------- expected `(dyn Trait + 'static)` because of return type +LL | if true { +LL | return Struct; + | ^^^^^^ expected trait `Trait`, found struct `Struct` + | + = note: expected trait object `(dyn Trait + 'static)` + found struct `Struct` + +error[E0746]: return type cannot have a bare trait because it must be `Sized` + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:21:13 + | +LL | fn bal() -> dyn Trait { + | ^^^^^^^^^ doesn't have a size known at compile-time + | +help: if all the returned values were of the same type you could use `impl Trait` as the return type + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:25:5 + | +LL | return Struct; + | ^^^^^^ +LL | } +LL | 42 + | ^^ + = help: alternatively, you can always create a new `enum` with a variant for each returned type + = note: for information on `impl Trait`, see + = note: for information on trait objects, see +help: if the performance implications are acceptable, you can return a trait object + | +LL | fn bal() -> Box { +LL | if true { +LL | return Box::new(Struct); +LL | } +LL | Box::new(42) + | + +error[E0308]: mismatched types + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:25:5 + | +LL | fn bal() -> dyn Trait { + | --------- expected `(dyn Trait + 'static)` because of return type +... +LL | 42 + | ^^ expected trait `Trait`, found integer + | + = note: expected trait object `(dyn Trait + 'static)` + found type `{integer}` + +error[E0746]: return type cannot have a bare trait because it must be `Sized` + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:29:13 + | +LL | fn bat() -> dyn Trait { + | ^^^^^^^^^ doesn't have a size known at compile-time + | + = note: for information on `impl Trait`, see +help: you can use the `impl Trait` feature in the return type because all the return paths are of type `{integer}`, which implements `dyn Trait` + | +LL | fn bat() -> impl Trait { + | ^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:31:16 + | +LL | fn bat() -> dyn Trait { + | --------- expected `(dyn Trait + 'static)` because of return type +LL | if true { +LL | return 0; + | ^ expected trait `Trait`, found integer + | + = note: expected trait object `(dyn Trait + 'static)` + found type `{integer}` + +error[E0308]: mismatched types + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:33:5 + | +LL | fn bat() -> dyn Trait { + | --------- expected `(dyn Trait + 'static)` because of return type +... +LL | 42 + | ^^ expected trait `Trait`, found integer + | + = note: expected trait object `(dyn Trait + 'static)` + found type `{integer}` + +error: aborting due to 15 previous errors + +Some errors have detailed explanations: E0277, E0308. +For more information about an error, try `rustc --explain E0277`. From 75eabb17aec390fd91b5bf11539012e4fc7307b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 13 Jan 2020 13:14:11 -0800 Subject: [PATCH 106/169] Account for diverging types in return `impl Trait` --- src/librustc_typeck/check/coercion.rs | 28 +++++++++++++++++ src/test/ui/impl-trait/equality.stderr | 5 ++++ ...type-err-cause-on-impl-trait-return.stderr | 30 +++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 1afb703ca1506..698fdfa3897b1 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -1348,6 +1348,34 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { "...is found to be `{}` here", fcx.resolve_vars_with_obligations(expected), )); + err.note( + "`impl Trait` as a return type requires that all the returned values must have \ + the same type", + ); + let snippet = fcx + .tcx + .sess + .source_map() + .span_to_snippet(return_sp) + .unwrap_or_else(|_| "dyn Trait".to_string()); + let mut snippet_iter = snippet.split_whitespace(); + let has_impl = snippet_iter.next().map_or(false, |s| s == "impl"); + if has_impl { + err.help(&format!( + "you can instead return a trait object using `Box`", + &snippet[5..] + )); + } + let impl_trait_msg = "for information on `impl Trait`, see \ + "; + let trait_obj_msg = "for information on trait objects, see \ + "; + err.note(impl_trait_msg); + if has_impl { + err.note(trait_obj_msg); + } } err } diff --git a/src/test/ui/impl-trait/equality.stderr b/src/test/ui/impl-trait/equality.stderr index e53524e58d663..215b6d52918ab 100644 --- a/src/test/ui/impl-trait/equality.stderr +++ b/src/test/ui/impl-trait/equality.stderr @@ -9,6 +9,11 @@ LL | return 1_i32; LL | } LL | 0_u32 | ^^^^^ expected `i32`, found `u32` + | + = note: `impl Trait` as a return type requires that all the returned values must have the same type + = help: you can instead return a trait object using `Box` + = note: for information on `impl Trait`, see + = note: for information on trait objects, see error[E0277]: cannot add `impl Foo` to `u32` --> $DIR/equality.rs:24:11 diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr index 27b86007451d8..9db5250e4d876 100644 --- a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr +++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr @@ -9,6 +9,11 @@ LL | return 0i32; LL | } LL | 1u32 | ^^^^ expected `i32`, found `u32` + | + = note: `impl Trait` as a return type requires that all the returned values must have the same type + = help: you can instead return a trait object using `Box` + = note: for information on `impl Trait`, see + = note: for information on trait objects, see error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:13:16 @@ -21,6 +26,11 @@ LL | return 0i32; LL | } else { LL | return 1u32; | ^^^^ expected `i32`, found `u32` + | + = note: `impl Trait` as a return type requires that all the returned values must have the same type + = help: you can instead return a trait object using `Box` + = note: for information on `impl Trait`, see + = note: for information on trait objects, see error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:22:9 @@ -33,6 +43,11 @@ LL | return 0i32; LL | } else { LL | 1u32 | ^^^^ expected `i32`, found `u32` + | + = note: `impl Trait` as a return type requires that all the returned values must have the same type + = help: you can instead return a trait object using `Box` + = note: for information on `impl Trait`, see + = note: for information on trait objects, see error[E0308]: `if` and `else` have incompatible types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:31:9 @@ -57,6 +72,11 @@ LL | 0 => return 0i32, | ---- ...is found to be `i32` here LL | _ => 1u32, | ^^^^ expected `i32`, found `u32` + | + = note: `impl Trait` as a return type requires that all the returned values must have the same type + = help: you can instead return a trait object using `Box` + = note: for information on `impl Trait`, see + = note: for information on trait objects, see error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:45:5 @@ -71,6 +91,11 @@ LL | | 1 => 1u32, LL | | _ => 2u32, LL | | } | |_____^ expected `i32`, found `u32` + | + = note: `impl Trait` as a return type requires that all the returned values must have the same type + = help: you can instead return a trait object using `Box` + = note: for information on `impl Trait`, see + = note: for information on trait objects, see error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:59:13 @@ -83,6 +108,11 @@ LL | return 0i32; ... LL | 1u32 | ^^^^ expected `i32`, found `u32` + | + = note: `impl Trait` as a return type requires that all the returned values must have the same type + = help: you can instead return a trait object using `Box` + = note: for information on `impl Trait`, see + = note: for information on trait objects, see error: aborting due to 7 previous errors From ea7e885204e1ed6b18406e84708abef748925ec5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 13 Jan 2020 16:12:44 -0800 Subject: [PATCH 107/169] Elide E0308 errors in favor of E0746 When a type error involves a `dyn Trait` as the return type, do not emit the type error, as the "return type is not `Sized`" error will provide enough information to the user. --- src/librustc_typeck/check/coercion.rs | 19 ++++- src/librustc_typeck/check/mod.rs | 12 +++ src/test/ui/error-codes/E0746.rs | 5 +- src/test/ui/error-codes/E0746.stderr | 40 +-------- .../dyn-trait-return-should-be-impl-trait.rs | 10 +-- ...n-trait-return-should-be-impl-trait.stderr | 82 ++----------------- 6 files changed, 44 insertions(+), 124 deletions(-) diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 698fdfa3897b1..77f16fb79141d 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -1222,6 +1222,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { }; let mut err; + let mut unsized_return = false; match cause.code { ObligationCauseCode::ReturnNoExpression => { err = struct_span_err!( @@ -1243,6 +1244,9 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { parent_id, expression.map(|expr| (expr, blk_id)), ); + if !fcx.tcx.features().unsized_locals { + unsized_return = fcx.is_unsized_return(blk_id); + } } ObligationCauseCode::ReturnValue(id) => { err = self.report_return_mismatched_types( @@ -1254,6 +1258,10 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { id, None, ); + if !fcx.tcx.features().unsized_locals { + let id = fcx.tcx.hir().get_parent_node(id); + unsized_return = fcx.is_unsized_return(id); + } } _ => { err = fcx.report_mismatched_types(cause, expected, found, coercion_error); @@ -1282,7 +1290,16 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { .filter(|e| fcx.is_assign_to_bool(e, self.expected_ty())) .is_some(); - err.emit_unless(assign_to_bool); + if unsized_return { + fcx.tcx.sess.delay_span_bug( + cause.span, + &format!( + "elided E0308 in favor of more detailed E0277 or E0746: {:?}", + cause.code + ), + ); + } + err.emit_unless(assign_to_bool || unsized_return); self.final_ty = Some(fcx.tcx.types.err); } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index baf9ae1ac2911..8f531ea6199e1 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4964,6 +4964,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } + fn is_unsized_return(&self, blk_id: hir::HirId) -> bool { + if let Some((fn_decl, _)) = self.get_fn_decl(blk_id) { + if let hir::FunctionRetTy::Return(ty) = fn_decl.output { + let ty = AstConv::ast_ty_to_ty(self, ty); + if let ty::Dynamic(..) = ty.kind { + return true; + } + } + } + false + } + /// A possible error is to forget to add a return type that is needed: /// /// ``` diff --git a/src/test/ui/error-codes/E0746.rs b/src/test/ui/error-codes/E0746.rs index ad257b01e1b40..c9ab455a4c5b4 100644 --- a/src/test/ui/error-codes/E0746.rs +++ b/src/test/ui/error-codes/E0746.rs @@ -5,13 +5,12 @@ impl Trait for u32 {} fn foo() -> dyn Trait { Struct } //~^ ERROR E0746 -//~| ERROR E0308 fn bar() -> dyn Trait { //~ ERROR E0746 if true { - return 0; //~ ERROR E0308 + return 0; } - 42 //~ ERROR E0308 + 42 } fn main() {} diff --git a/src/test/ui/error-codes/E0746.stderr b/src/test/ui/error-codes/E0746.stderr index baafcd27c29d4..44bd0d7ed7d37 100644 --- a/src/test/ui/error-codes/E0746.stderr +++ b/src/test/ui/error-codes/E0746.stderr @@ -1,14 +1,3 @@ -error[E0308]: mismatched types - --> $DIR/E0746.rs:6:25 - | -LL | fn foo() -> dyn Trait { Struct } - | --------- ^^^^^^ expected trait `Trait`, found struct `Struct` - | | - | expected `(dyn Trait + 'static)` because of return type - | - = note: expected trait object `(dyn Trait + 'static)` - found struct `Struct` - error[E0746]: return type cannot have a bare trait because it must be `Sized` --> $DIR/E0746.rs:6:13 | @@ -22,7 +11,7 @@ LL | fn foo() -> impl Trait { Struct } | ^^^^^^^^^^ error[E0746]: return type cannot have a bare trait because it must be `Sized` - --> $DIR/E0746.rs:10:13 + --> $DIR/E0746.rs:9:13 | LL | fn bar() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time @@ -33,30 +22,5 @@ help: you can use the `impl Trait` feature in the return type because all the re LL | fn bar() -> impl Trait { | ^^^^^^^^^^ -error[E0308]: mismatched types - --> $DIR/E0746.rs:12:16 - | -LL | fn bar() -> dyn Trait { - | --------- expected `(dyn Trait + 'static)` because of return type -LL | if true { -LL | return 0; - | ^ expected trait `Trait`, found integer - | - = note: expected trait object `(dyn Trait + 'static)` - found type `{integer}` - -error[E0308]: mismatched types - --> $DIR/E0746.rs:14:5 - | -LL | fn bar() -> dyn Trait { - | --------- expected `(dyn Trait + 'static)` because of return type -... -LL | 42 - | ^^ expected trait `Trait`, found integer - | - = note: expected trait object `(dyn Trait + 'static)` - found type `{integer}` - -error: aborting due to 5 previous errors +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs index 80168ca825774..b70a51dc82511 100644 --- a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs +++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.rs @@ -12,25 +12,23 @@ fn bar() -> (usize, dyn Trait) { (42, Struct) } //~| ERROR E0308 fn bap() -> Trait { Struct } //~^ ERROR E0746 -//~| ERROR E0308 fn ban() -> dyn Trait { Struct } //~^ ERROR E0746 -//~| ERROR E0308 fn bak() -> dyn Trait { unimplemented!() } //~ ERROR E0277 // Suggest using `Box` fn bal() -> dyn Trait { //~ ERROR E0746 if true { - return Struct; //~ ERROR E0308 + return Struct; } - 42 //~ ERROR E0308 + 42 } // Suggest using `impl Trait` fn bat() -> dyn Trait { //~ ERROR E0746 if true { - return 0; //~ ERROR E0308 + return 0; } - 42 //~ ERROR E0308 + 42 } fn main() {} diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr index ce4c141a0af9d..a09ce2bb29863 100644 --- a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr +++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr @@ -38,17 +38,6 @@ LL | fn bar() -> (usize, dyn Trait) { (42, Struct) } = note: required because it appears within the type `(usize, (dyn Trait + 'static))` = note: the return type of a function must have a statically known size -error[E0308]: mismatched types - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:13:21 - | -LL | fn bap() -> Trait { Struct } - | ----- ^^^^^^ expected trait `Trait`, found struct `Struct` - | | - | expected `(dyn Trait + 'static)` because of return type - | - = note: expected trait object `(dyn Trait + 'static)` - found struct `Struct` - error[E0746]: return type cannot have a bare trait because it must be `Sized` --> $DIR/dyn-trait-return-should-be-impl-trait.rs:13:13 | @@ -61,19 +50,8 @@ help: you can use the `impl Trait` feature in the return type because all the re LL | fn bap() -> impl Trait { Struct } | ^^^^^^^^^^ -error[E0308]: mismatched types - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:16:25 - | -LL | fn ban() -> dyn Trait { Struct } - | --------- ^^^^^^ expected trait `Trait`, found struct `Struct` - | | - | expected `(dyn Trait + 'static)` because of return type - | - = note: expected trait object `(dyn Trait + 'static)` - found struct `Struct` - error[E0746]: return type cannot have a bare trait because it must be `Sized` - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:16:13 + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:15:13 | LL | fn ban() -> dyn Trait { Struct } | ^^^^^^^^^ doesn't have a size known at compile-time @@ -85,7 +63,7 @@ LL | fn ban() -> impl Trait { Struct } | ^^^^^^^^^^ error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:19:13 + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:17:13 | LL | fn bak() -> dyn Trait { unimplemented!() } | ^^^^^^^^^ doesn't have a size known at compile-time @@ -94,26 +72,14 @@ LL | fn bak() -> dyn Trait { unimplemented!() } = note: to learn more, visit = note: the return type of a function must have a statically known size -error[E0308]: mismatched types - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:23:16 - | -LL | fn bal() -> dyn Trait { - | --------- expected `(dyn Trait + 'static)` because of return type -LL | if true { -LL | return Struct; - | ^^^^^^ expected trait `Trait`, found struct `Struct` - | - = note: expected trait object `(dyn Trait + 'static)` - found struct `Struct` - error[E0746]: return type cannot have a bare trait because it must be `Sized` - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:21:13 + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:19:13 | LL | fn bal() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time | help: if all the returned values were of the same type you could use `impl Trait` as the return type - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:25:5 + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:23:5 | LL | return Struct; | ^^^^^^ @@ -132,20 +98,8 @@ LL | } LL | Box::new(42) | -error[E0308]: mismatched types - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:25:5 - | -LL | fn bal() -> dyn Trait { - | --------- expected `(dyn Trait + 'static)` because of return type -... -LL | 42 - | ^^ expected trait `Trait`, found integer - | - = note: expected trait object `(dyn Trait + 'static)` - found type `{integer}` - error[E0746]: return type cannot have a bare trait because it must be `Sized` - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:29:13 + --> $DIR/dyn-trait-return-should-be-impl-trait.rs:27:13 | LL | fn bat() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time @@ -156,31 +110,7 @@ help: you can use the `impl Trait` feature in the return type because all the re LL | fn bat() -> impl Trait { | ^^^^^^^^^^ -error[E0308]: mismatched types - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:31:16 - | -LL | fn bat() -> dyn Trait { - | --------- expected `(dyn Trait + 'static)` because of return type -LL | if true { -LL | return 0; - | ^ expected trait `Trait`, found integer - | - = note: expected trait object `(dyn Trait + 'static)` - found type `{integer}` - -error[E0308]: mismatched types - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:33:5 - | -LL | fn bat() -> dyn Trait { - | --------- expected `(dyn Trait + 'static)` because of return type -... -LL | 42 - | ^^ expected trait `Trait`, found integer - | - = note: expected trait object `(dyn Trait + 'static)` - found type `{integer}` - -error: aborting due to 15 previous errors +error: aborting due to 9 previous errors Some errors have detailed explanations: E0277, E0308. For more information about an error, try `rustc --explain E0277`. From b4bbe784a9dc1f97f07e2543c6f726cb1eb4cc86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 13 Jan 2020 16:13:51 -0800 Subject: [PATCH 108/169] Make `impl Trait` suggestion in E0746 `MachineApplicable` --- src/librustc/traits/error_reporting.rs | 2 +- src/test/ui/error-codes/E0746.fixed | 18 ++++++++++++++++++ src/test/ui/error-codes/E0746.rs | 2 ++ src/test/ui/error-codes/E0746.stderr | 4 ++-- 4 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/error-codes/E0746.fixed diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 8f771658e4098..8d0923f571851 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1840,7 +1840,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { last_ty, trait_obj, ), format!("impl {}", trait_obj), - Applicability::MaybeIncorrect, + Applicability::MachineApplicable, ); err.note(impl_trait_msg); } else { diff --git a/src/test/ui/error-codes/E0746.fixed b/src/test/ui/error-codes/E0746.fixed new file mode 100644 index 0000000000000..ca8319aa020dc --- /dev/null +++ b/src/test/ui/error-codes/E0746.fixed @@ -0,0 +1,18 @@ +// run-rustfix +#![allow(dead_code)] +struct Struct; +trait Trait {} +impl Trait for Struct {} +impl Trait for u32 {} + +fn foo() -> impl Trait { Struct } +//~^ ERROR E0746 + +fn bar() -> impl Trait { //~ ERROR E0746 + if true { + return 0; + } + 42 +} + +fn main() {} diff --git a/src/test/ui/error-codes/E0746.rs b/src/test/ui/error-codes/E0746.rs index c9ab455a4c5b4..bf5ba8fff562a 100644 --- a/src/test/ui/error-codes/E0746.rs +++ b/src/test/ui/error-codes/E0746.rs @@ -1,3 +1,5 @@ +// run-rustfix +#![allow(dead_code)] struct Struct; trait Trait {} impl Trait for Struct {} diff --git a/src/test/ui/error-codes/E0746.stderr b/src/test/ui/error-codes/E0746.stderr index 44bd0d7ed7d37..0cffd108226d8 100644 --- a/src/test/ui/error-codes/E0746.stderr +++ b/src/test/ui/error-codes/E0746.stderr @@ -1,5 +1,5 @@ error[E0746]: return type cannot have a bare trait because it must be `Sized` - --> $DIR/E0746.rs:6:13 + --> $DIR/E0746.rs:8:13 | LL | fn foo() -> dyn Trait { Struct } | ^^^^^^^^^ doesn't have a size known at compile-time @@ -11,7 +11,7 @@ LL | fn foo() -> impl Trait { Struct } | ^^^^^^^^^^ error[E0746]: return type cannot have a bare trait because it must be `Sized` - --> $DIR/E0746.rs:9:13 + --> $DIR/E0746.rs:11:13 | LL | fn bar() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time From e1dd8a909531cd66080ca89227fb8828a01d7e22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 13 Jan 2020 17:19:52 -0800 Subject: [PATCH 109/169] When trait bounds are missing for return values, point at them --- src/librustc/traits/error_reporting.rs | 122 +++++++++++------- .../issue-64130-4-async-move.stderr | 13 +- .../alloc-traits-no-impls-length-33.stderr | 15 +++ .../into-iter-no-impls-length-33.stderr | 21 +++ .../impl_bounds.stderr | 2 +- ...n-trait-return-should-be-impl-trait.stderr | 8 +- src/test/ui/issues/issue-58344.stderr | 6 + src/test/ui/issues/issue-5883.stderr | 3 + .../lifetime-elision-return-type-trait.stderr | 3 + .../feature-gate-never_type_fallback.stderr | 4 + .../generic_underconstrained2.stderr | 4 + 11 files changed, 147 insertions(+), 54 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 8d0923f571851..d5af1a9a42dd7 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -1130,6 +1130,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { }; self.note_obligation_cause(&mut err, obligation); + self.point_at_returns_when_relevant(&mut err, &obligation); err.emit(); } @@ -1737,35 +1738,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { // Recursively look for `TraitObject` types and if there's only one, use that span to // suggest `impl Trait`. - struct ReturnsVisitor<'v>(Vec<&'v hir::Expr<'v>>); - - impl<'v> Visitor<'v> for ReturnsVisitor<'v> { - type Map = rustc::hir::map::Map<'v>; - - fn nested_visit_map(&mut self) -> hir::intravisit::NestedVisitorMap<'_, Self::Map> { - hir::intravisit::NestedVisitorMap::None - } - - fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { - match ex.kind { - hir::ExprKind::Ret(Some(ex)) => self.0.push(ex), - _ => {} - } - hir::intravisit::walk_expr(self, ex); - } - - fn visit_body(&mut self, body: &'v hir::Body<'v>) { - if body.generator_kind().is_none() { - if let hir::ExprKind::Block(block, None) = body.value.kind { - if let Some(expr) = block.expr { - self.0.push(expr); - } - } - } - hir::intravisit::walk_body(self, body); - } - } - // Visit to make sure there's a single `return` type to suggest `impl Trait`, // otherwise suggest using `Box` or an enum. let mut visitor = ReturnsVisitor(vec![]); @@ -1893,6 +1865,38 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { false } + fn point_at_returns_when_relevant( + &self, + err: &mut DiagnosticBuilder<'tcx>, + obligation: &PredicateObligation<'tcx>, + ) { + if let ObligationCauseCode::SizedReturnType = obligation.cause.code.peel_derives() { + } else { + return; + } + + let hir = self.tcx.hir(); + let parent_node = hir.get_parent_node(obligation.cause.body_id); + let node = hir.find(parent_node); + if let Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })) = + node + { + let body = hir.body(*body_id); + // Point at all the `return`s in the function as they have failed trait bounds. + let mut visitor = ReturnsVisitor(vec![]); + visitor.visit_body(&body); + let tables = self.in_progress_tables.map(|t| t.borrow()).unwrap(); + for expr in &visitor.0 { + if let Some(returned_ty) = tables.node_type_opt(expr.hir_id) { + err.span_label( + expr.span, + &format!("this returned value is of type `{}`", returned_ty), + ); + } + } + } + } + /// Given some node representing a fn-like thing in the HIR map, /// returns a span and `ArgKind` information that describes the /// arguments it expects. This can be supplied to @@ -2911,19 +2915,18 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } ObligationCauseCode::RepeatVec(suggest_const_in_array_repeat_expressions) => { err.note( - "the `Copy` trait is required because the \ - repeated element will be copied", + "the `Copy` trait is required because the repeated element will be copied", ); if suggest_const_in_array_repeat_expressions { err.note( "this array initializer can be evaluated at compile-time, for more \ - information, see issue \ - https://github.com/rust-lang/rust/issues/49147", + information, see issue \ + https://github.com/rust-lang/rust/issues/49147", ); if tcx.sess.opts.unstable_features.is_nightly_build() { err.help( "add `#![feature(const_in_array_repeat_expressions)]` to the \ - crate attributes to enable", + crate attributes to enable", ); } } @@ -2941,16 +2944,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } ObligationCauseCode::SizedReturnType => { - err.note( - "the return type of a function must have a \ - statically known size", - ); + err.note("the return type of a function must have a statically known size"); } ObligationCauseCode::SizedYieldType => { - err.note( - "the yield type of a generator must have a \ - statically known size", - ); + err.note("the yield type of a generator must have a statically known size"); } ObligationCauseCode::AssignmentLhsSized => { err.note("the left-hand-side of an assignment must have a statically known size"); @@ -2966,12 +2963,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { if last { err.note( "the last field of a packed struct may only have a \ - dynamically sized type if it does not need drop to be run", + dynamically sized type if it does not need drop to be run", ); } else { err.note( - "only the last field of a struct may have a dynamically \ - sized type", + "only the last field of a struct may have a dynamically sized type", ); } } @@ -3025,13 +3021,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ObligationCauseCode::CompareImplMethodObligation { .. } => { err.note(&format!( "the requirement `{}` appears on the impl method \ - but not on the corresponding trait method", + but not on the corresponding trait method", predicate )); } ObligationCauseCode::CompareImplTypeObligation { .. } => { err.note(&format!( - "the requirement `{}` appears on the associated impl type\ + "the requirement `{}` appears on the associated impl type \ but not on the corresponding associated trait type", predicate )); @@ -3043,8 +3039,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { err.help("see issue #48214"); if tcx.sess.opts.unstable_features.is_nightly_build() { err.help( - "add `#![feature(trivial_bounds)]` to the \ - crate attributes to enable", + "add `#![feature(trivial_bounds)]` to the crate attributes to enable", ); } } @@ -3186,3 +3181,32 @@ pub fn suggest_constraining_type_param( } false } + +struct ReturnsVisitor<'v>(Vec<&'v hir::Expr<'v>>); + +impl<'v> Visitor<'v> for ReturnsVisitor<'v> { + type Map = rustc::hir::map::Map<'v>; + + fn nested_visit_map(&mut self) -> hir::intravisit::NestedVisitorMap<'_, Self::Map> { + hir::intravisit::NestedVisitorMap::None + } + + fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { + match ex.kind { + hir::ExprKind::Ret(Some(ex)) => self.0.push(ex), + _ => {} + } + hir::intravisit::walk_expr(self, ex); + } + + fn visit_body(&mut self, body: &'v hir::Body<'v>) { + if body.generator_kind().is_none() { + if let hir::ExprKind::Block(block, None) = body.value.kind { + if let Some(expr) = block.expr { + self.0.push(expr); + } + } + } + hir::intravisit::walk_body(self, body); + } +} diff --git a/src/test/ui/async-await/issue-64130-4-async-move.stderr b/src/test/ui/async-await/issue-64130-4-async-move.stderr index 77d0885c38d58..f59dbc2638400 100644 --- a/src/test/ui/async-await/issue-64130-4-async-move.stderr +++ b/src/test/ui/async-await/issue-64130-4-async-move.stderr @@ -1,8 +1,17 @@ error: future cannot be sent between threads safely --> $DIR/issue-64130-4-async-move.rs:15:17 | -LL | pub fn foo() -> impl Future + Send { - | ^^^^^^^^^^^^^^^^^^ future returned by `foo` is not `Send` +LL | pub fn foo() -> impl Future + Send { + | ^^^^^^^^^^^^^^^^^^ future returned by `foo` is not `Send` +... +LL | / async move { +LL | | match client.status() { +LL | | 200 => { +LL | | let _x = get().await; +... | +LL | | } +LL | | } + | |_____- this returned value is of type `impl std::future::Future` | = help: the trait `std::marker::Sync` is not implemented for `(dyn std::any::Any + std::marker::Send + 'static)` note: future is not `Send` as this value is used across an await diff --git a/src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.stderr b/src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.stderr index 5c37468130c64..6e5afcdb8bb68 100644 --- a/src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.stderr +++ b/src/test/ui/const-generics/array-impls/alloc-traits-no-impls-length-33.stderr @@ -3,6 +3,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32 | LL | pub fn no_vec_partial_eq_array() -> impl PartialEq<[B; 33]> | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[B; 33]` +... +LL | Vec::::new() + | --------------- this returned value is of type `std::vec::Vec` | = note: required because of the requirements on the impl of `std::cmp::PartialEq<[B; 33]>` for `std::vec::Vec` = note: the return type of a function must have a statically known size @@ -12,6 +15,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32 | LL | pub fn no_vec_partial_eq_ref_array<'a, A, B>() -> impl PartialEq<&'a [B; 33]> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[B; 33]` +... +LL | Vec::::new() + | --------------- this returned value is of type `std::vec::Vec` | = note: required because of the requirements on the impl of `std::cmp::PartialEq<&'a [B; 33]>` for `std::vec::Vec` = note: the return type of a function must have a statically known size @@ -21,6 +27,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32 | LL | pub fn no_vecdeque_partial_eq_array() -> impl PartialEq<[B; 33]> | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[B; 33]` +... +LL | VecDeque::::new() + | -------------------- this returned value is of type `std::collections::VecDeque` | = note: required because of the requirements on the impl of `std::cmp::PartialEq<[B; 33]>` for `std::collections::VecDeque` = note: the return type of a function must have a statically known size @@ -30,6 +39,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32 | LL | pub fn no_vecdeque_partial_eq_ref_array<'a, A, B>() -> impl PartialEq<&'a [B; 33]> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[B; 33]` +... +LL | VecDeque::::new() + | -------------------- this returned value is of type `std::collections::VecDeque` | = note: required because of the requirements on the impl of `std::cmp::PartialEq<&'a [B; 33]>` for `std::collections::VecDeque` = note: the return type of a function must have a statically known size @@ -39,6 +51,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32 | LL | pub fn no_vecdeque_partial_eq_ref_mut_array<'a, A, B>() -> impl PartialEq<&'a mut [B; 33]> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[B; 33]` +... +LL | VecDeque::::new() + | -------------------- this returned value is of type `std::collections::VecDeque` | = note: required because of the requirements on the impl of `std::cmp::PartialEq<&'a mut [B; 33]>` for `std::collections::VecDeque` = note: the return type of a function must have a statically known size diff --git a/src/test/ui/const-generics/array-impls/into-iter-no-impls-length-33.stderr b/src/test/ui/const-generics/array-impls/into-iter-no-impls-length-33.stderr index bfdff8e3bbe61..e615e10bd5f5f 100644 --- a/src/test/ui/const-generics/array-impls/into-iter-no-impls-length-33.stderr +++ b/src/test/ui/const-generics/array-impls/into-iter-no-impls-length-33.stderr @@ -11,6 +11,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32 | LL | pub fn no_iterator() -> impl Iterator { | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]` +LL | +LL | IntoIter::new([0i32; 33]) + | ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>` | = note: required because of the requirements on the impl of `std::iter::Iterator` for `std::array::IntoIter` = note: the return type of a function must have a statically known size @@ -28,6 +31,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32 | LL | pub fn no_double_ended_iterator() -> impl DoubleEndedIterator { | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]` +LL | +LL | IntoIter::new([0i32; 33]) + | ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>` | = note: required because of the requirements on the impl of `std::iter::DoubleEndedIterator` for `std::array::IntoIter` = note: the return type of a function must have a statically known size @@ -45,6 +51,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32 | LL | pub fn no_exact_size_iterator() -> impl ExactSizeIterator { | ^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]` +LL | +LL | IntoIter::new([0i32; 33]) + | ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>` | = note: required because of the requirements on the impl of `std::iter::ExactSizeIterator` for `std::array::IntoIter` = note: the return type of a function must have a statically known size @@ -62,6 +71,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32 | LL | pub fn no_fused_iterator() -> impl FusedIterator { | ^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]` +LL | +LL | IntoIter::new([0i32; 33]) + | ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>` | = note: required because of the requirements on the impl of `std::iter::FusedIterator` for `std::array::IntoIter` = note: the return type of a function must have a statically known size @@ -79,6 +91,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32 | LL | pub fn no_trusted_len() -> impl TrustedLen { | ^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]` +LL | +LL | IntoIter::new([0i32; 33]) + | ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>` | = note: required because of the requirements on the impl of `std::iter::TrustedLen` for `std::array::IntoIter` = note: the return type of a function must have a statically known size @@ -96,6 +111,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32 | LL | pub fn no_clone() -> impl Clone { | ^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]` +LL | +LL | IntoIter::new([0i32; 33]) + | ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>` | = note: required because of the requirements on the impl of `std::clone::Clone` for `std::array::IntoIter` = note: the return type of a function must have a statically known size @@ -113,6 +131,9 @@ error[E0277]: arrays only have std trait implementations for lengths 0..=32 | LL | pub fn no_debug() -> impl Debug { | ^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]` +LL | +LL | IntoIter::new([0i32; 33]) + | ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>` | = note: required because of the requirements on the impl of `std::fmt::Debug` for `std::array::IntoIter` = note: the return type of a function must have a statically known size diff --git a/src/test/ui/generic-associated-types/impl_bounds.stderr b/src/test/ui/generic-associated-types/impl_bounds.stderr index 017990076931b..ca2350ff7577f 100644 --- a/src/test/ui/generic-associated-types/impl_bounds.stderr +++ b/src/test/ui/generic-associated-types/impl_bounds.stderr @@ -38,7 +38,7 @@ LL | type C where Self: Copy = String; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `T` | = note: required because of the requirements on the impl of `std::marker::Copy` for `Fooy` - = note: the requirement `Fooy: std::marker::Copy` appears on the associated impl typebut not on the corresponding associated trait type + = note: the requirement `Fooy: std::marker::Copy` appears on the associated impl type but not on the corresponding associated trait type error: aborting due to 3 previous errors diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr index a09ce2bb29863..d51cd6aeae6ec 100644 --- a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr +++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr @@ -11,7 +11,9 @@ error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be know --> $DIR/dyn-trait-return-should-be-impl-trait.rs:7:13 | LL | fn fuz() -> (usize, Trait) { (42, Struct) } - | ^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | ^^^^^^^^^^^^^^ ------------ this returned value is of type `(usize, (dyn Trait + 'static))` + | | + | doesn't have a size known at compile-time | = help: within `(usize, (dyn Trait + 'static))`, the trait `std::marker::Sized` is not implemented for `(dyn Trait + 'static)` = note: to learn more, visit @@ -31,7 +33,9 @@ error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be know --> $DIR/dyn-trait-return-should-be-impl-trait.rs:10:13 | LL | fn bar() -> (usize, dyn Trait) { (42, Struct) } - | ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | ^^^^^^^^^^^^^^^^^^ ------------ this returned value is of type `(usize, (dyn Trait + 'static))` + | | + | doesn't have a size known at compile-time | = help: within `(usize, (dyn Trait + 'static))`, the trait `std::marker::Sized` is not implemented for `(dyn Trait + 'static)` = note: to learn more, visit diff --git a/src/test/ui/issues/issue-58344.stderr b/src/test/ui/issues/issue-58344.stderr index 427d03b679d5f..9b07dbd7ab69c 100644 --- a/src/test/ui/issues/issue-58344.stderr +++ b/src/test/ui/issues/issue-58344.stderr @@ -3,6 +3,9 @@ error[E0277]: the trait bound `impl Trait<::Output>: Trait | LL | ) -> Either>::Output>, impl Trait<>::Output>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `impl Trait<::Output>` +... +LL | add_generic(value, 1u32) + | ------------------------ this returned value is of type `Either>::Output>, impl Trait<<_ as std::ops::Add<_>>::Output>>` | = note: the return type of a function must have a statically known size @@ -11,6 +14,9 @@ error[E0277]: the trait bound `impl Trait<::Output>: Trait | LL | ) -> Either>::Output>, impl Trait<>::Output>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `impl Trait<::Output>` +... +LL | add_generic(value, 1u32) + | ------------------------ this returned value is of type `Either>::Output>, impl Trait<<_ as std::ops::Add<_>>::Output>>` | = note: the return type of a function must have a statically known size diff --git a/src/test/ui/issues/issue-5883.stderr b/src/test/ui/issues/issue-5883.stderr index c2de1d095505a..d886ecc11d17b 100644 --- a/src/test/ui/issues/issue-5883.stderr +++ b/src/test/ui/issues/issue-5883.stderr @@ -14,6 +14,9 @@ error[E0277]: the size for values of type `(dyn A + 'static)` cannot be known at | LL | -> Struct { | ^^^^^^ doesn't have a size known at compile-time +LL | +LL | Struct { r: r } + | --------------- this returned value is of type `Struct` | = help: within `Struct`, the trait `std::marker::Sized` is not implemented for `(dyn A + 'static)` = note: to learn more, visit diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr index 228582d0001da..49fa11c35aef8 100644 --- a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr +++ b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr @@ -3,6 +3,9 @@ error[E0277]: the trait bound `std::result::Result<(), _>: Future` is not satisf | LL | fn foo() -> impl Future> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Future` is not implemented for `std::result::Result<(), _>` +LL | +LL | Ok(()) + | ------ this returned value is of type `std::result::Result<_, _>` | = note: the return type of a function must have a statically known size diff --git a/src/test/ui/never_type/feature-gate-never_type_fallback.stderr b/src/test/ui/never_type/feature-gate-never_type_fallback.stderr index 837e90d6ceb9b..88bfed2b54742 100644 --- a/src/test/ui/never_type/feature-gate-never_type_fallback.stderr +++ b/src/test/ui/never_type/feature-gate-never_type_fallback.stderr @@ -3,8 +3,12 @@ error[E0277]: the trait bound `(): T` is not satisfied | LL | fn should_ret_unit() -> impl T { | ^^^^^^ the trait `T` is not implemented for `()` +LL | +LL | panic!() + | -------- this returned value is of type `_` | = note: the return type of a function must have a statically known size + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr b/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr index d4c7c7c74529e..9e8414f9c15fe 100644 --- a/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr @@ -18,6 +18,8 @@ LL | type Underconstrained = impl 'static; ... LL | fn underconstrained(_: U) -> Underconstrained { | - help: consider restricting this bound: `U: std::fmt::Debug` +LL | 5u32 + | ---- this returned value is of type `u32` | = help: the trait `std::fmt::Debug` is not implemented for `U` = note: the return type of a function must have a statically known size @@ -30,6 +32,8 @@ LL | type Underconstrained2 = impl 'static; ... LL | fn underconstrained2(_: U, _: V) -> Underconstrained2 { | - help: consider restricting this bound: `V: std::fmt::Debug` +LL | 5u32 + | ---- this returned value is of type `u32` | = help: the trait `std::fmt::Debug` is not implemented for `V` = note: the return type of a function must have a statically known size From 93293c56e85a2afdde8664bc08303d5f5853ba29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 13 Jan 2020 17:20:28 -0800 Subject: [PATCH 110/169] fmt --- src/librustc/traits/error_reporting.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index d5af1a9a42dd7..77a73aba45484 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -3038,9 +3038,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ObligationCauseCode::TrivialBound => { err.help("see issue #48214"); if tcx.sess.opts.unstable_features.is_nightly_build() { - err.help( - "add `#![feature(trivial_bounds)]` to the crate attributes to enable", - ); + err.help("add `#![feature(trivial_bounds)]` to the crate attributes to enable"); } } ObligationCauseCode::AssocTypeBound(ref data) => { From 4c13d2555c4535516eb00dd0221c9d158b91e31c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 13 Jan 2020 17:21:31 -0800 Subject: [PATCH 111/169] Add E0746 explanation to the index --- src/librustc_error_codes/error_codes.rs | 2 +- src/librustc_error_codes/error_codes/E0746.md | 137 ++++++++++++++++++ src/test/ui/error-codes/E0746.stderr | 1 + ...n-trait-return-should-be-impl-trait.stderr | 2 +- 4 files changed, 140 insertions(+), 2 deletions(-) create mode 100644 src/librustc_error_codes/error_codes/E0746.md diff --git a/src/librustc_error_codes/error_codes.rs b/src/librustc_error_codes/error_codes.rs index c17cb7dd9f161..180ccb15977dd 100644 --- a/src/librustc_error_codes/error_codes.rs +++ b/src/librustc_error_codes/error_codes.rs @@ -414,6 +414,7 @@ E0742: include_str!("./error_codes/E0742.md"), E0743: include_str!("./error_codes/E0743.md"), E0744: include_str!("./error_codes/E0744.md"), E0745: include_str!("./error_codes/E0745.md"), +E0746: include_str!("./error_codes/E0746.md"), ; // E0006, // merged with E0005 // E0008, // cannot bind by-move into a pattern guard @@ -608,5 +609,4 @@ E0745: include_str!("./error_codes/E0745.md"), E0726, // non-explicit (not `'_`) elided lifetime in unsupported position E0727, // `async` generators are not yet supported E0739, // invalid track_caller application/syntax - E0746, // `dyn Trait` return type } diff --git a/src/librustc_error_codes/error_codes/E0746.md b/src/librustc_error_codes/error_codes/E0746.md new file mode 100644 index 0000000000000..538c9d720d71b --- /dev/null +++ b/src/librustc_error_codes/error_codes/E0746.md @@ -0,0 +1,137 @@ +Return types cannot be `dyn Trait`s as they must be `Sized`. + +Erroneous code example: + +```compile_fail,E0746 +trait T { + fn bar(&self); +} +struct S(usize); +impl T for S { + fn bar(&self) {} +} + +// Having the trait `T` as return type is invalid because bare traits do not +have a statically known size: +fn foo() -> dyn T { + S(42) +} +``` + +To avoid the error there are a couple of options. + +If there is a single type involved, you can use [`impl Trait`]: + +``` +# trait T { +# fn bar(&self); +# } +# struct S(usize); +# impl T for S { +# fn bar(&self) {} +# } +// The compiler will select `S(usize)` as the materialized return type of this +// function, but callers will only be able to access associated items from `T`. +fn foo() -> impl T { + S(42) +} +``` + +If there are multiple types involved, the only way you care to interact with +them is through the trait's interface and having to rely on dynamic dispatch is +acceptable, then you can use [trait objects] with `Box`, or other container +types like `Rc` or `Arc`: + +``` +# trait T { +# fn bar(&self); +# } +# struct S(usize); +# impl T for S { +# fn bar(&self) {} +# } +struct O(&'static str); +impl T for O { + fn bar(&self) {} +} + +// This now returns a "trait object" and callers are only be able to access +// associated items from `T`. +fn foo(x: bool) -> Box { + if x { + Box::new(S(42)) + } else { + Box::new(O("val")) + } +} +``` + +Finally, if you wish to still be able to access the original type, you can +create a new `enum` with a variant for each type: + +``` +# trait T { +# fn bar(&self); +# } +# struct S(usize); +# impl T for S { +# fn bar(&self) {} +# } +# struct O(&'static str); +# impl T for O { +# fn bar(&self) {} +# } +enum E { + S(S), + O(O), +} + +// The caller can access the original types directly, but it needs to match on +// the returned `enum E`. +fn foo(x: bool) -> E { + if x { + E::S(S(42)) + } else { + E::O(O("val")) + } +} +``` + +You can even implement the `trait` on the returned `enum` so the callers +*don't* have to match on the returned value to invoke the associated items: + +``` +# trait T { +# fn bar(&self); +# } +# struct S(usize); +# impl T for S { +# fn bar(&self) {} +# } +# struct O(&'static str); +# impl T for O { +# fn bar(&self) {} +# } +# enum E { +# S(S), +# O(O), +# } +impl T for E { + fn bar(&self) { + match self { + E::S(s) => s.bar(), + E::O(o) => o.bar(), + } + } +} +``` + +If you decide to use trait objects, be aware that these rely on +[dynamic dispatch], which has performance implications, as the compiler needs +to emit code that will figure out which method to call *at runtime* instead of +during compilation. Using trait objects we are trading flexibility for +performance. + +[`impl Trait`]: https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits +[trait objects]: https://doc.rust-lang.org/book/ch17-02-trait-objects.html#using-trait-objects-that-allow-for-values-of-different-types +[dynamic dispatch]: https://doc.rust-lang.org/book/ch17-02-trait-objects.html#trait-objects-perform-dynamic-dispatch diff --git a/src/test/ui/error-codes/E0746.stderr b/src/test/ui/error-codes/E0746.stderr index 0cffd108226d8..1c88ce64749ae 100644 --- a/src/test/ui/error-codes/E0746.stderr +++ b/src/test/ui/error-codes/E0746.stderr @@ -24,3 +24,4 @@ LL | fn bar() -> impl Trait { error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0746`. diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr index d51cd6aeae6ec..ff7438e9affc1 100644 --- a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr +++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr @@ -116,5 +116,5 @@ LL | fn bat() -> impl Trait { error: aborting due to 9 previous errors -Some errors have detailed explanations: E0277, E0308. +Some errors have detailed explanations: E0277, E0308, E0746. For more information about an error, try `rustc --explain E0277`. From 9dee5d582f538e1d12f278e23ee47cb7c201c9b7 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 3 Jan 2020 13:31:56 +0100 Subject: [PATCH 112/169] fix rustfmt fallout --- src/librustc/mir/interpret/error.rs | 5 +++-- src/librustc/mir/interpret/mod.rs | 4 ++-- src/librustc_mir/interpret/cast.rs | 20 +++++++++++--------- src/librustc_mir/interpret/eval_context.rs | 12 +++++++++--- src/librustc_mir/interpret/memory.rs | 4 ++-- src/librustc_mir/interpret/operand.rs | 22 +++++++++++----------- src/librustc_mir/interpret/place.rs | 11 +++++------ src/librustc_mir/interpret/validity.rs | 10 +++++----- 8 files changed, 48 insertions(+), 40 deletions(-) diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index 8643bd63d8cba..29b3b045ca5fe 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -33,7 +33,7 @@ impl ErrorHandled { ErrorHandled::Reported => {} ErrorHandled::TooGeneric => bug!( "MIR interpretation failed without reporting an error \ - even though it was fully monomorphized" + even though it was fully monomorphized" ), } } @@ -137,7 +137,8 @@ impl<'tcx> ConstEvalErr<'tcx> { ) -> Result, ErrorHandled> { let must_error = match self.error { InterpError::MachineStop(_) => bug!("CTFE does not stop"), - err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => { + err_inval!(Layout(LayoutError::Unknown(_))) + | err_inval!(TooGeneric) => { return Err(ErrorHandled::TooGeneric); } err_inval!(TypeckError) => return Err(ErrorHandled::Reported), diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs index 47f067590b9d5..e554b280ef78c 100644 --- a/src/librustc/mir/interpret/mod.rs +++ b/src/librustc/mir/interpret/mod.rs @@ -403,8 +403,8 @@ impl<'tcx> AllocMap<'tcx> { let next = self.next_id; self.next_id.0 = self.next_id.0.checked_add(1).expect( "You overflowed a u64 by incrementing by 1... \ - You've just earned yourself a free drink if we ever meet. \ - Seriously, how did you do that?!", + You've just earned yourself a free drink if we ever meet. \ + Seriously, how did you do that?!", ); next } diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index 9461a06690212..6d0b6bf70ad8c 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -118,15 +118,17 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } // The rest is integer/pointer-"like", including fn ptr casts and casts from enums that // are represented as integers. - _ => assert!( - src.layout.ty.is_bool() - || src.layout.ty.is_char() - || src.layout.ty.is_enum() - || src.layout.ty.is_integral() - || src.layout.ty.is_any_ptr(), - "Unexpected cast from type {:?}", - src.layout.ty - ), + _ => { + assert!( + src.layout.ty.is_bool() + || src.layout.ty.is_char() + || src.layout.ty.is_enum() + || src.layout.ty.is_integral() + || src.layout.ty.is_any_ptr(), + "Unexpected cast from type {:?}", + src.layout.ty + ) + } } // Handle cast from a univariant (ZST) enum. diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 206d3d156735e..3d590fb820359 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -152,10 +152,16 @@ impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> { &mut self, ) -> InterpResult<'tcx, Result<&mut LocalValue, MemPlace>> { match self.value { - LocalValue::Dead => throw_unsup!(DeadLocal), - LocalValue::Live(Operand::Indirect(mplace)) => Ok(Err(mplace)), + LocalValue::Dead => { + throw_unsup!(DeadLocal) + } + LocalValue::Live(Operand::Indirect(mplace)) => { + Ok(Err(mplace)) + } ref mut local @ LocalValue::Live(Operand::Immediate(_)) - | ref mut local @ LocalValue::Uninitialized => Ok(Ok(local)), + | ref mut local @ LocalValue::Uninitialized => { + Ok(Ok(local)) + } } } } diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index cb676821fd438..3386254c93b75 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -581,9 +581,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { Ok((layout.size, layout.align.abi)) } Some(GlobalAlloc::Memory(alloc)) => - // Need to duplicate the logic here, because the global allocations have - // different associated types than the interpreter-local ones. { + // Need to duplicate the logic here, because the global allocations have + // different associated types than the interpreter-local ones. Ok((alloc.size, alloc.align)) } Some(GlobalAlloc::Function(_)) => bug!("We already checked function pointers above"), diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index b37eff3f40626..34a32daaab65f 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -543,7 +543,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { | ty::ConstKind::Placeholder(..) => { bug!("eval_const_to_op: Unexpected ConstKind {:?}", val) } - ty::ConstKind::Value(val_val) => val_val, + ty::ConstKind::Value(val_val) => { + val_val + } }; // Other cases need layout. let layout = from_known_layout(layout, || self.layout_of(val.ty))?; @@ -684,16 +686,14 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let variant_index = variants_start .checked_add(variant_index_relative) .expect("oveflow computing absolute variant idx"); - assert!( - (variant_index as usize) - < rval - .layout - .ty - .ty_adt_def() - .expect("tagged layout for non adt") - .variants - .len() - ); + let variants_len = rval + .layout + .ty + .ty_adt_def() + .expect("tagged layout for non adt") + .variants + .len(); + assert!((variant_index as usize) < variants_len); (u128::from(variant_index), VariantIdx::from_u32(variant_index)) } else { (u128::from(dataful_variant.as_u32()), dataful_variant) diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 8888e3fd4632a..4f96cb698915d 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -432,12 +432,11 @@ where // happens at run-time so that's okay. let align = match self.size_and_align_of(base.meta, field_layout)? { Some((_, align)) => align, - None if offset == Size::ZERO => - // An extern type at offset 0, we fall back to its static alignment. - // FIXME: Once we have made decisions for how to handle size and alignment - // of `extern type`, this should be adapted. It is just a temporary hack - // to get some code to work that probably ought to work. - { + None if offset == Size::ZERO => { + // An extern type at offset 0, we fall back to its static alignment. + // FIXME: Once we have made decisions for how to handle size and alignment + // of `extern type`, this should be adapted. It is just a temporary hack + // to get some code to work that probably ought to work. field_layout.align.abi } None => bug!("Cannot compute offset for extern type field at non-0 offset"), diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index 2f0fb81fffd13..d0fef08bb60c7 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -115,11 +115,11 @@ fn write_path(out: &mut String, path: &Vec) { TupleElem(idx) => write!(out, ".{}", idx), ArrayElem(idx) => write!(out, "[{}]", idx), Deref => - // This does not match Rust syntax, but it is more readable for long paths -- and - // some of the other items here also are not Rust syntax. Actually we can't - // even use the usual syntax because we are just showing the projections, - // not the root. { + // This does not match Rust syntax, but it is more readable for long paths -- and + // some of the other items here also are not Rust syntax. Actually we can't + // even use the usual syntax because we are just showing the projections, + // not the root. write!(out, ".") } Tag => write!(out, "."), @@ -207,8 +207,8 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M // we might be projecting *to* a variant, or to a field *in*a variant. match layout.variants { layout::Variants::Single { index } => - // Inside a variant { + // Inside a variant PathElem::Field(def.variants[index].fields[field].ident.name) } _ => bug!(), From 00c82726122d550c586e11bf85501a93ce0fbf75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 13 Jan 2020 18:27:42 -0800 Subject: [PATCH 113/169] Split `librustc/traits/error_reporting.rs` --- src/librustc/traits/error_reporting/mod.rs | 1442 +++++++++++++++ .../error_reporting/on_unimplemented.rs | 199 +++ .../suggestions.rs} | 1557 +---------------- 3 files changed, 1667 insertions(+), 1531 deletions(-) create mode 100644 src/librustc/traits/error_reporting/mod.rs create mode 100644 src/librustc/traits/error_reporting/on_unimplemented.rs rename src/librustc/traits/{error_reporting.rs => error_reporting/suggestions.rs} (52%) diff --git a/src/librustc/traits/error_reporting/mod.rs b/src/librustc/traits/error_reporting/mod.rs new file mode 100644 index 0000000000000..f8329124851b0 --- /dev/null +++ b/src/librustc/traits/error_reporting/mod.rs @@ -0,0 +1,1442 @@ +pub mod on_unimplemented; +pub mod suggestions; + +use super::{ + ConstEvalFailure, EvaluationResult, FulfillmentError, FulfillmentErrorCode, + MismatchedProjectionTypes, ObjectSafetyViolation, Obligation, ObligationCause, + ObligationCauseCode, OnUnimplementedDirective, OnUnimplementedNote, + OutputTypeParameterMismatch, Overflow, PredicateObligation, SelectionContext, SelectionError, + TraitNotObjectSafe, +}; + +use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode}; +use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use crate::infer::{self, InferCtxt}; +use crate::mir::interpret::ErrorHandled; +use crate::session::DiagnosticMessageId; +use crate::traits::object_safety_violations; +use crate::ty::error::ExpectedFound; +use crate::ty::fast_reject; +use crate::ty::fold::TypeFolder; +use crate::ty::SubtypePredicate; +use crate::ty::{self, AdtKind, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable}; + +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; +use rustc_hir as hir; +use rustc_hir::def_id::{DefId, LOCAL_CRATE}; +use rustc_hir::intravisit::Visitor; +use rustc_span::source_map::SourceMap; +use rustc_span::{ExpnKind, Span, DUMMY_SP}; +use std::fmt; +use syntax::ast; + +use rustc_error_codes::*; + +impl<'a, 'tcx> InferCtxt<'a, 'tcx> { + pub fn report_fulfillment_errors( + &self, + errors: &[FulfillmentError<'tcx>], + body_id: Option, + fallback_has_occurred: bool, + ) { + #[derive(Debug)] + struct ErrorDescriptor<'tcx> { + predicate: ty::Predicate<'tcx>, + index: Option, // None if this is an old error + } + + let mut error_map: FxHashMap<_, Vec<_>> = self + .reported_trait_errors + .borrow() + .iter() + .map(|(&span, predicates)| { + ( + span, + predicates + .iter() + .map(|predicate| ErrorDescriptor { + predicate: predicate.clone(), + index: None, + }) + .collect(), + ) + }) + .collect(); + + for (index, error) in errors.iter().enumerate() { + // We want to ignore desugarings here: spans are equivalent even + // if one is the result of a desugaring and the other is not. + let mut span = error.obligation.cause.span; + let expn_data = span.ctxt().outer_expn_data(); + if let ExpnKind::Desugaring(_) = expn_data.kind { + span = expn_data.call_site; + } + + error_map.entry(span).or_default().push(ErrorDescriptor { + predicate: error.obligation.predicate.clone(), + index: Some(index), + }); + + self.reported_trait_errors + .borrow_mut() + .entry(span) + .or_default() + .push(error.obligation.predicate.clone()); + } + + // We do this in 2 passes because we want to display errors in order, though + // maybe it *is* better to sort errors by span or something. + let mut is_suppressed = vec![false; errors.len()]; + for (_, error_set) in error_map.iter() { + // We want to suppress "duplicate" errors with the same span. + for error in error_set { + if let Some(index) = error.index { + // Suppress errors that are either: + // 1) strictly implied by another error. + // 2) implied by an error with a smaller index. + for error2 in error_set { + if error2.index.map_or(false, |index2| is_suppressed[index2]) { + // Avoid errors being suppressed by already-suppressed + // errors, to prevent all errors from being suppressed + // at once. + continue; + } + + if self.error_implies(&error2.predicate, &error.predicate) + && !(error2.index >= error.index + && self.error_implies(&error.predicate, &error2.predicate)) + { + info!("skipping {:?} (implied by {:?})", error, error2); + is_suppressed[index] = true; + break; + } + } + } + } + } + + for (error, suppressed) in errors.iter().zip(is_suppressed) { + if !suppressed { + self.report_fulfillment_error(error, body_id, fallback_has_occurred); + } + } + } + + // returns if `cond` not occurring implies that `error` does not occur - i.e., that + // `error` occurring implies that `cond` occurs. + fn error_implies(&self, cond: &ty::Predicate<'tcx>, error: &ty::Predicate<'tcx>) -> bool { + if cond == error { + return true; + } + + let (cond, error) = match (cond, error) { + (&ty::Predicate::Trait(..), &ty::Predicate::Trait(ref error)) => (cond, error), + _ => { + // FIXME: make this work in other cases too. + return false; + } + }; + + for implication in super::elaborate_predicates(self.tcx, vec![cond.clone()]) { + if let ty::Predicate::Trait(implication) = implication { + let error = error.to_poly_trait_ref(); + let implication = implication.to_poly_trait_ref(); + // FIXME: I'm just not taking associated types at all here. + // Eventually I'll need to implement param-env-aware + // `Γ₁ ⊦ φ₁ => Γ₂ ⊦ φ₂` logic. + let param_env = ty::ParamEnv::empty(); + if self.can_sub(param_env, error, implication).is_ok() { + debug!("error_implies: {:?} -> {:?} -> {:?}", cond, error, implication); + return true; + } + } + } + + false + } + + fn report_fulfillment_error( + &self, + error: &FulfillmentError<'tcx>, + body_id: Option, + fallback_has_occurred: bool, + ) { + debug!("report_fulfillment_error({:?})", error); + match error.code { + FulfillmentErrorCode::CodeSelectionError(ref selection_error) => { + self.report_selection_error( + &error.obligation, + selection_error, + fallback_has_occurred, + error.points_at_arg_span, + ); + } + FulfillmentErrorCode::CodeProjectionError(ref e) => { + self.report_projection_error(&error.obligation, e); + } + FulfillmentErrorCode::CodeAmbiguity => { + self.maybe_report_ambiguity(&error.obligation, body_id); + } + FulfillmentErrorCode::CodeSubtypeError(ref expected_found, ref err) => { + self.report_mismatched_types( + &error.obligation.cause, + expected_found.expected, + expected_found.found, + err.clone(), + ) + .emit(); + } + } + } + + fn report_projection_error( + &self, + obligation: &PredicateObligation<'tcx>, + error: &MismatchedProjectionTypes<'tcx>, + ) { + let predicate = self.resolve_vars_if_possible(&obligation.predicate); + + if predicate.references_error() { + return; + } + + self.probe(|_| { + let err_buf; + let mut err = &error.err; + let mut values = None; + + // try to find the mismatched types to report the error with. + // + // this can fail if the problem was higher-ranked, in which + // cause I have no idea for a good error message. + if let ty::Predicate::Projection(ref data) = predicate { + let mut selcx = SelectionContext::new(self); + let (data, _) = self.replace_bound_vars_with_fresh_vars( + obligation.cause.span, + infer::LateBoundRegionConversionTime::HigherRankedType, + data, + ); + let mut obligations = vec![]; + let normalized_ty = super::normalize_projection_type( + &mut selcx, + obligation.param_env, + data.projection_ty, + obligation.cause.clone(), + 0, + &mut obligations, + ); + + debug!( + "report_projection_error obligation.cause={:?} obligation.param_env={:?}", + obligation.cause, obligation.param_env + ); + + debug!( + "report_projection_error normalized_ty={:?} data.ty={:?}", + normalized_ty, data.ty + ); + + let is_normalized_ty_expected = match &obligation.cause.code { + ObligationCauseCode::ItemObligation(_) + | ObligationCauseCode::BindingObligation(_, _) + | ObligationCauseCode::ObjectCastObligation(_) => false, + _ => true, + }; + + if let Err(error) = self.at(&obligation.cause, obligation.param_env).eq_exp( + is_normalized_ty_expected, + normalized_ty, + data.ty, + ) { + values = Some(infer::ValuePairs::Types(ExpectedFound::new( + is_normalized_ty_expected, + normalized_ty, + data.ty, + ))); + + err_buf = error; + err = &err_buf; + } + } + + let msg = format!("type mismatch resolving `{}`", predicate); + let error_id = (DiagnosticMessageId::ErrorId(271), Some(obligation.cause.span), msg); + let fresh = self.tcx.sess.one_time_diagnostics.borrow_mut().insert(error_id); + if fresh { + let mut diag = struct_span_err!( + self.tcx.sess, + obligation.cause.span, + E0271, + "type mismatch resolving `{}`", + predicate + ); + self.note_type_err(&mut diag, &obligation.cause, None, values, err); + self.note_obligation_cause(&mut diag, obligation); + diag.emit(); + } + }); + } + + fn fuzzy_match_tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> bool { + /// returns the fuzzy category of a given type, or None + /// if the type can be equated to any type. + fn type_category(t: Ty<'_>) -> Option { + match t.kind { + ty::Bool => Some(0), + ty::Char => Some(1), + ty::Str => Some(2), + ty::Int(..) | ty::Uint(..) | ty::Infer(ty::IntVar(..)) => Some(3), + ty::Float(..) | ty::Infer(ty::FloatVar(..)) => Some(4), + ty::Ref(..) | ty::RawPtr(..) => Some(5), + ty::Array(..) | ty::Slice(..) => Some(6), + ty::FnDef(..) | ty::FnPtr(..) => Some(7), + ty::Dynamic(..) => Some(8), + ty::Closure(..) => Some(9), + ty::Tuple(..) => Some(10), + ty::Projection(..) => Some(11), + ty::Param(..) => Some(12), + ty::Opaque(..) => Some(13), + ty::Never => Some(14), + ty::Adt(adt, ..) => match adt.adt_kind() { + AdtKind::Struct => Some(15), + AdtKind::Union => Some(16), + AdtKind::Enum => Some(17), + }, + ty::Generator(..) => Some(18), + ty::Foreign(..) => Some(19), + ty::GeneratorWitness(..) => Some(20), + ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) | ty::Error => None, + ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"), + } + } + + match (type_category(a), type_category(b)) { + (Some(cat_a), Some(cat_b)) => match (&a.kind, &b.kind) { + (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => def_a == def_b, + _ => cat_a == cat_b, + }, + // infer and error can be equated to all types + _ => true, + } + } + + fn describe_generator(&self, body_id: hir::BodyId) -> Option<&'static str> { + self.tcx.hir().body(body_id).generator_kind.map(|gen_kind| match gen_kind { + hir::GeneratorKind::Gen => "a generator", + hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Block) => "an async block", + hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Fn) => "an async function", + hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Closure) => "an async closure", + }) + } + + fn find_similar_impl_candidates( + &self, + trait_ref: ty::PolyTraitRef<'tcx>, + ) -> Vec> { + let simp = fast_reject::simplify_type(self.tcx, trait_ref.skip_binder().self_ty(), true); + let all_impls = self.tcx.all_impls(trait_ref.def_id()); + + match simp { + Some(simp) => all_impls + .iter() + .filter_map(|&def_id| { + let imp = self.tcx.impl_trait_ref(def_id).unwrap(); + let imp_simp = fast_reject::simplify_type(self.tcx, imp.self_ty(), true); + if let Some(imp_simp) = imp_simp { + if simp != imp_simp { + return None; + } + } + + Some(imp) + }) + .collect(), + None => { + all_impls.iter().map(|&def_id| self.tcx.impl_trait_ref(def_id).unwrap()).collect() + } + } + } + + fn report_similar_impl_candidates( + &self, + impl_candidates: Vec>, + err: &mut DiagnosticBuilder<'_>, + ) { + if impl_candidates.is_empty() { + return; + } + + let len = impl_candidates.len(); + let end = if impl_candidates.len() <= 5 { impl_candidates.len() } else { 4 }; + + let normalize = |candidate| { + self.tcx.infer_ctxt().enter(|ref infcx| { + let normalized = infcx + .at(&ObligationCause::dummy(), ty::ParamEnv::empty()) + .normalize(candidate) + .ok(); + match normalized { + Some(normalized) => format!("\n {:?}", normalized.value), + None => format!("\n {:?}", candidate), + } + }) + }; + + // Sort impl candidates so that ordering is consistent for UI tests. + let mut normalized_impl_candidates = + impl_candidates.iter().map(normalize).collect::>(); + + // Sort before taking the `..end` range, + // because the ordering of `impl_candidates` may not be deterministic: + // https://github.com/rust-lang/rust/pull/57475#issuecomment-455519507 + normalized_impl_candidates.sort(); + + err.help(&format!( + "the following implementations were found:{}{}", + normalized_impl_candidates[..end].join(""), + if len > 5 { format!("\nand {} others", len - 4) } else { String::new() } + )); + } + + /// Reports that an overflow has occurred and halts compilation. We + /// halt compilation unconditionally because it is important that + /// overflows never be masked -- they basically represent computations + /// whose result could not be truly determined and thus we can't say + /// if the program type checks or not -- and they are unusual + /// occurrences in any case. + pub fn report_overflow_error( + &self, + obligation: &Obligation<'tcx, T>, + suggest_increasing_limit: bool, + ) -> ! + where + T: fmt::Display + TypeFoldable<'tcx>, + { + let predicate = self.resolve_vars_if_possible(&obligation.predicate); + let mut err = struct_span_err!( + self.tcx.sess, + obligation.cause.span, + E0275, + "overflow evaluating the requirement `{}`", + predicate + ); + + if suggest_increasing_limit { + self.suggest_new_overflow_limit(&mut err); + } + + self.note_obligation_cause_code( + &mut err, + &obligation.predicate, + &obligation.cause.code, + &mut vec![], + ); + + err.emit(); + self.tcx.sess.abort_if_errors(); + bug!(); + } + + /// Reports that a cycle was detected which led to overflow and halts + /// compilation. This is equivalent to `report_overflow_error` except + /// that we can give a more helpful error message (and, in particular, + /// we do not suggest increasing the overflow limit, which is not + /// going to help). + pub fn report_overflow_error_cycle(&self, cycle: &[PredicateObligation<'tcx>]) -> ! { + let cycle = self.resolve_vars_if_possible(&cycle.to_owned()); + assert!(cycle.len() > 0); + + debug!("report_overflow_error_cycle: cycle={:?}", cycle); + + self.report_overflow_error(&cycle[0], false); + } + + pub fn report_extra_impl_obligation( + &self, + error_span: Span, + item_name: ast::Name, + _impl_item_def_id: DefId, + trait_item_def_id: DefId, + requirement: &dyn fmt::Display, + ) -> DiagnosticBuilder<'tcx> { + let msg = "impl has stricter requirements than trait"; + let sp = self.tcx.sess.source_map().def_span(error_span); + + let mut err = struct_span_err!(self.tcx.sess, sp, E0276, "{}", msg); + + if let Some(trait_item_span) = self.tcx.hir().span_if_local(trait_item_def_id) { + let span = self.tcx.sess.source_map().def_span(trait_item_span); + err.span_label(span, format!("definition of `{}` from trait", item_name)); + } + + err.span_label(sp, format!("impl has extra requirement {}", requirement)); + + err + } + + /// Gets the parent trait chain start + fn get_parent_trait_ref( + &self, + code: &ObligationCauseCode<'tcx>, + ) -> Option<(String, Option)> { + match code { + &ObligationCauseCode::BuiltinDerivedObligation(ref data) => { + let parent_trait_ref = self.resolve_vars_if_possible(&data.parent_trait_ref); + match self.get_parent_trait_ref(&data.parent_code) { + Some(t) => Some(t), + None => { + let ty = parent_trait_ref.skip_binder().self_ty(); + let span = + TyCategory::from_ty(ty).map(|(_, def_id)| self.tcx.def_span(def_id)); + Some((ty.to_string(), span)) + } + } + } + _ => None, + } + } + + pub fn report_selection_error( + &self, + obligation: &PredicateObligation<'tcx>, + error: &SelectionError<'tcx>, + fallback_has_occurred: bool, + points_at_arg: bool, + ) { + let tcx = self.tcx; + let span = obligation.cause.span; + + let mut err = match *error { + SelectionError::Unimplemented => { + if let ObligationCauseCode::CompareImplMethodObligation { + item_name, + impl_item_def_id, + trait_item_def_id, + } + | ObligationCauseCode::CompareImplTypeObligation { + item_name, + impl_item_def_id, + trait_item_def_id, + } = obligation.cause.code + { + self.report_extra_impl_obligation( + span, + item_name, + impl_item_def_id, + trait_item_def_id, + &format!("`{}`", obligation.predicate), + ) + .emit(); + return; + } + match obligation.predicate { + ty::Predicate::Trait(ref trait_predicate) => { + let trait_predicate = self.resolve_vars_if_possible(trait_predicate); + + if self.tcx.sess.has_errors() && trait_predicate.references_error() { + return; + } + let trait_ref = trait_predicate.to_poly_trait_ref(); + let (post_message, pre_message, type_def) = self + .get_parent_trait_ref(&obligation.cause.code) + .map(|(t, s)| { + ( + format!(" in `{}`", t), + format!("within `{}`, ", t), + s.map(|s| (format!("within this `{}`", t), s)), + ) + }) + .unwrap_or_default(); + + let OnUnimplementedNote { message, label, note, enclosing_scope } = + self.on_unimplemented_note(trait_ref, obligation); + let have_alt_message = message.is_some() || label.is_some(); + let is_try = self + .tcx + .sess + .source_map() + .span_to_snippet(span) + .map(|s| &s == "?") + .unwrap_or(false); + let is_from = format!("{}", trait_ref.print_only_trait_path()) + .starts_with("std::convert::From<"); + let (message, note) = if is_try && is_from { + ( + Some(format!( + "`?` couldn't convert the error to `{}`", + trait_ref.self_ty(), + )), + Some( + "the question mark operation (`?`) implicitly performs a \ + conversion on the error value using the `From` trait" + .to_owned(), + ), + ) + } else { + (message, note) + }; + + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0277, + "{}", + message.unwrap_or_else(|| format!( + "the trait bound `{}` is not satisfied{}", + trait_ref.to_predicate(), + post_message, + )) + ); + + let explanation = + if obligation.cause.code == ObligationCauseCode::MainFunctionType { + "consider using `()`, or a `Result`".to_owned() + } else { + format!( + "{}the trait `{}` is not implemented for `{}`", + pre_message, + trait_ref.print_only_trait_path(), + trait_ref.self_ty(), + ) + }; + + if self.suggest_add_reference_to_arg( + &obligation, + &mut err, + &trait_ref, + points_at_arg, + have_alt_message, + ) { + self.note_obligation_cause(&mut err, obligation); + err.emit(); + return; + } + if let Some(ref s) = label { + // If it has a custom `#[rustc_on_unimplemented]` + // error message, let's display it as the label! + err.span_label(span, s.as_str()); + err.help(&explanation); + } else { + err.span_label(span, explanation); + } + if let Some((msg, span)) = type_def { + err.span_label(span, &msg); + } + if let Some(ref s) = note { + // If it has a custom `#[rustc_on_unimplemented]` note, let's display it + err.note(s.as_str()); + } + if let Some(ref s) = enclosing_scope { + let enclosing_scope_span = tcx.def_span( + tcx.hir() + .opt_local_def_id(obligation.cause.body_id) + .unwrap_or_else(|| { + tcx.hir().body_owner_def_id(hir::BodyId { + hir_id: obligation.cause.body_id, + }) + }), + ); + + err.span_label(enclosing_scope_span, s.as_str()); + } + + self.suggest_borrow_on_unsized_slice(&obligation.cause.code, &mut err); + self.suggest_fn_call(&obligation, &mut err, &trait_ref, points_at_arg); + self.suggest_remove_reference(&obligation, &mut err, &trait_ref); + self.suggest_semicolon_removal(&obligation, &mut err, span, &trait_ref); + self.note_version_mismatch(&mut err, &trait_ref); + if self.suggest_impl_trait(&mut err, span, &obligation, &trait_ref) { + err.emit(); + return; + } + + // Try to report a help message + if !trait_ref.has_infer_types() + && self.predicate_can_apply(obligation.param_env, trait_ref) + { + // If a where-clause may be useful, remind the + // user that they can add it. + // + // don't display an on-unimplemented note, as + // these notes will often be of the form + // "the type `T` can't be frobnicated" + // which is somewhat confusing. + self.suggest_restricting_param_bound( + &mut err, + &trait_ref, + obligation.cause.body_id, + ); + } else { + if !have_alt_message { + // Can't show anything else useful, try to find similar impls. + let impl_candidates = self.find_similar_impl_candidates(trait_ref); + self.report_similar_impl_candidates(impl_candidates, &mut err); + } + self.suggest_change_mut( + &obligation, + &mut err, + &trait_ref, + points_at_arg, + ); + } + + // If this error is due to `!: Trait` not implemented but `(): Trait` is + // implemented, and fallback has occurred, then it could be due to a + // variable that used to fallback to `()` now falling back to `!`. Issue a + // note informing about the change in behaviour. + if trait_predicate.skip_binder().self_ty().is_never() + && fallback_has_occurred + { + let predicate = trait_predicate.map_bound(|mut trait_pred| { + trait_pred.trait_ref.substs = self.tcx.mk_substs_trait( + self.tcx.mk_unit(), + &trait_pred.trait_ref.substs[1..], + ); + trait_pred + }); + let unit_obligation = Obligation { + predicate: ty::Predicate::Trait(predicate), + ..obligation.clone() + }; + if self.predicate_may_hold(&unit_obligation) { + err.note( + "the trait is implemented for `()`. \ + Possibly this error has been caused by changes to \ + Rust's type-inference algorithm \ + (see: https://github.com/rust-lang/rust/issues/48950 \ + for more info). Consider whether you meant to use the \ + type `()` here instead.", + ); + } + } + + err + } + + ty::Predicate::Subtype(ref predicate) => { + // Errors for Subtype predicates show up as + // `FulfillmentErrorCode::CodeSubtypeError`, + // not selection error. + span_bug!(span, "subtype requirement gave wrong error: `{:?}`", predicate) + } + + ty::Predicate::RegionOutlives(ref predicate) => { + let predicate = self.resolve_vars_if_possible(predicate); + let err = self + .region_outlives_predicate(&obligation.cause, &predicate) + .err() + .unwrap(); + struct_span_err!( + self.tcx.sess, + span, + E0279, + "the requirement `{}` is not satisfied (`{}`)", + predicate, + err, + ) + } + + ty::Predicate::Projection(..) | ty::Predicate::TypeOutlives(..) => { + let predicate = self.resolve_vars_if_possible(&obligation.predicate); + struct_span_err!( + self.tcx.sess, + span, + E0280, + "the requirement `{}` is not satisfied", + predicate + ) + } + + ty::Predicate::ObjectSafe(trait_def_id) => { + let violations = object_safety_violations(self.tcx, trait_def_id); + report_object_safety_error(self.tcx, span, trait_def_id, violations) + } + + ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => { + let found_kind = self.closure_kind(closure_def_id, closure_substs).unwrap(); + let closure_span = self + .tcx + .sess + .source_map() + .def_span(self.tcx.hir().span_if_local(closure_def_id).unwrap()); + let hir_id = self.tcx.hir().as_local_hir_id(closure_def_id).unwrap(); + let mut err = struct_span_err!( + self.tcx.sess, + closure_span, + E0525, + "expected a closure that implements the `{}` trait, \ + but this closure only implements `{}`", + kind, + found_kind + ); + + err.span_label( + closure_span, + format!("this closure implements `{}`, not `{}`", found_kind, kind), + ); + err.span_label( + obligation.cause.span, + format!("the requirement to implement `{}` derives from here", kind), + ); + + // Additional context information explaining why the closure only implements + // a particular trait. + if let Some(tables) = self.in_progress_tables { + let tables = tables.borrow(); + match (found_kind, tables.closure_kind_origins().get(hir_id)) { + (ty::ClosureKind::FnOnce, Some((span, name))) => { + err.span_label( + *span, + format!( + "closure is `FnOnce` because it moves the \ + variable `{}` out of its environment", + name + ), + ); + } + (ty::ClosureKind::FnMut, Some((span, name))) => { + err.span_label( + *span, + format!( + "closure is `FnMut` because it mutates the \ + variable `{}` here", + name + ), + ); + } + _ => {} + } + } + + err.emit(); + return; + } + + ty::Predicate::WellFormed(ty) => { + if !self.tcx.sess.opts.debugging_opts.chalk { + // WF predicates cannot themselves make + // errors. They can only block due to + // ambiguity; otherwise, they always + // degenerate into other obligations + // (which may fail). + span_bug!(span, "WF predicate not satisfied for {:?}", ty); + } else { + // FIXME: we'll need a better message which takes into account + // which bounds actually failed to hold. + self.tcx.sess.struct_span_err( + span, + &format!("the type `{}` is not well-formed (chalk)", ty), + ) + } + } + + ty::Predicate::ConstEvaluatable(..) => { + // Errors for `ConstEvaluatable` predicates show up as + // `SelectionError::ConstEvalFailure`, + // not `Unimplemented`. + span_bug!( + span, + "const-evaluatable requirement gave wrong error: `{:?}`", + obligation + ) + } + } + } + + OutputTypeParameterMismatch(ref found_trait_ref, ref expected_trait_ref, _) => { + let found_trait_ref = self.resolve_vars_if_possible(&*found_trait_ref); + let expected_trait_ref = self.resolve_vars_if_possible(&*expected_trait_ref); + + if expected_trait_ref.self_ty().references_error() { + return; + } + + let found_trait_ty = found_trait_ref.self_ty(); + + let found_did = match found_trait_ty.kind { + ty::Closure(did, _) | ty::Foreign(did) | ty::FnDef(did, _) => Some(did), + ty::Adt(def, _) => Some(def.did), + _ => None, + }; + + let found_span = found_did + .and_then(|did| self.tcx.hir().span_if_local(did)) + .map(|sp| self.tcx.sess.source_map().def_span(sp)); // the sp could be an fn def + + if self.reported_closure_mismatch.borrow().contains(&(span, found_span)) { + // We check closures twice, with obligations flowing in different directions, + // but we want to complain about them only once. + return; + } + + self.reported_closure_mismatch.borrow_mut().insert((span, found_span)); + + let found = match found_trait_ref.skip_binder().substs.type_at(1).kind { + ty::Tuple(ref tys) => vec![ArgKind::empty(); tys.len()], + _ => vec![ArgKind::empty()], + }; + + let expected_ty = expected_trait_ref.skip_binder().substs.type_at(1); + let expected = match expected_ty.kind { + ty::Tuple(ref tys) => tys + .iter() + .map(|t| ArgKind::from_expected_ty(t.expect_ty(), Some(span))) + .collect(), + _ => vec![ArgKind::Arg("_".to_owned(), expected_ty.to_string())], + }; + + if found.len() == expected.len() { + self.report_closure_arg_mismatch( + span, + found_span, + found_trait_ref, + expected_trait_ref, + ) + } else { + let (closure_span, found) = found_did + .and_then(|did| self.tcx.hir().get_if_local(did)) + .map(|node| { + let (found_span, found) = self.get_fn_like_arguments(node); + (Some(found_span), found) + }) + .unwrap_or((found_span, found)); + + self.report_arg_count_mismatch( + span, + closure_span, + expected, + found, + found_trait_ty.is_closure(), + ) + } + } + + TraitNotObjectSafe(did) => { + let violations = object_safety_violations(self.tcx, did); + report_object_safety_error(self.tcx, span, did, violations) + } + + // already reported in the query + ConstEvalFailure(err) => { + if let ErrorHandled::TooGeneric = err { + // Silence this error, as it can be produced during intermediate steps + // when a constant is not yet able to be evaluated (but will be later). + return; + } + self.tcx.sess.delay_span_bug( + span, + &format!("constant in type had an ignored error: {:?}", err), + ); + return; + } + + Overflow => { + bug!("overflow should be handled before the `report_selection_error` path"); + } + }; + + self.note_obligation_cause(&mut err, obligation); + self.point_at_returns_when_relevant(&mut err, &obligation); + + err.emit(); + } + + /// If the `Self` type of the unsatisfied trait `trait_ref` implements a trait + /// with the same path as `trait_ref`, a help message about + /// a probable version mismatch is added to `err` + fn note_version_mismatch( + &self, + err: &mut DiagnosticBuilder<'_>, + trait_ref: &ty::PolyTraitRef<'tcx>, + ) { + let get_trait_impl = |trait_def_id| { + let mut trait_impl = None; + self.tcx.for_each_relevant_impl(trait_def_id, trait_ref.self_ty(), |impl_def_id| { + if trait_impl.is_none() { + trait_impl = Some(impl_def_id); + } + }); + trait_impl + }; + let required_trait_path = self.tcx.def_path_str(trait_ref.def_id()); + let all_traits = self.tcx.all_traits(LOCAL_CRATE); + let traits_with_same_path: std::collections::BTreeSet<_> = all_traits + .iter() + .filter(|trait_def_id| **trait_def_id != trait_ref.def_id()) + .filter(|trait_def_id| self.tcx.def_path_str(**trait_def_id) == required_trait_path) + .collect(); + for trait_with_same_path in traits_with_same_path { + if let Some(impl_def_id) = get_trait_impl(*trait_with_same_path) { + let impl_span = self.tcx.def_span(impl_def_id); + err.span_help(impl_span, "trait impl with same name found"); + let trait_crate = self.tcx.crate_name(trait_with_same_path.krate); + let crate_msg = format!( + "perhaps two different versions of crate `{}` are being used?", + trait_crate + ); + err.note(&crate_msg); + } + } + } + + fn mk_obligation_for_def_id( + &self, + def_id: DefId, + output_ty: Ty<'tcx>, + cause: ObligationCause<'tcx>, + param_env: ty::ParamEnv<'tcx>, + ) -> PredicateObligation<'tcx> { + let new_trait_ref = + ty::TraitRef { def_id, substs: self.tcx.mk_substs_trait(output_ty, &[]) }; + Obligation::new(cause, param_env, new_trait_ref.to_predicate()) + } +} + +pub fn recursive_type_with_infinite_size_error( + tcx: TyCtxt<'tcx>, + type_def_id: DefId, +) -> DiagnosticBuilder<'tcx> { + assert!(type_def_id.is_local()); + let span = tcx.hir().span_if_local(type_def_id).unwrap(); + let span = tcx.sess.source_map().def_span(span); + let mut err = struct_span_err!( + tcx.sess, + span, + E0072, + "recursive type `{}` has infinite size", + tcx.def_path_str(type_def_id) + ); + err.span_label(span, "recursive type has infinite size"); + err.help(&format!( + "insert indirection (e.g., a `Box`, `Rc`, or `&`) \ + at some point to make `{}` representable", + tcx.def_path_str(type_def_id) + )); + err +} + +pub fn report_object_safety_error( + tcx: TyCtxt<'tcx>, + span: Span, + trait_def_id: DefId, + violations: Vec, +) -> DiagnosticBuilder<'tcx> { + let trait_str = tcx.def_path_str(trait_def_id); + let span = tcx.sess.source_map().def_span(span); + let mut err = struct_span_err!( + tcx.sess, + span, + E0038, + "the trait `{}` cannot be made into an object", + trait_str + ); + err.span_label(span, format!("the trait `{}` cannot be made into an object", trait_str)); + + let mut reported_violations = FxHashSet::default(); + for violation in violations { + if reported_violations.insert(violation.clone()) { + match violation.span() { + Some(span) => err.span_label(span, violation.error_msg()), + None => err.note(&violation.error_msg()), + }; + } + } + + if tcx.sess.trait_methods_not_found.borrow().contains(&span) { + // Avoid emitting error caused by non-existing method (#58734) + err.cancel(); + } + + err +} + +impl<'a, 'tcx> InferCtxt<'a, 'tcx> { + fn maybe_report_ambiguity( + &self, + obligation: &PredicateObligation<'tcx>, + body_id: Option, + ) { + // Unable to successfully determine, probably means + // insufficient type information, but could mean + // ambiguous impls. The latter *ought* to be a + // coherence violation, so we don't report it here. + + let predicate = self.resolve_vars_if_possible(&obligation.predicate); + let span = obligation.cause.span; + + debug!( + "maybe_report_ambiguity(predicate={:?}, obligation={:?} body_id={:?}, code={:?})", + predicate, obligation, body_id, obligation.cause.code, + ); + + // Ambiguity errors are often caused as fallout from earlier + // errors. So just ignore them if this infcx is tainted. + if self.is_tainted_by_errors() { + return; + } + + let mut err = match predicate { + ty::Predicate::Trait(ref data) => { + let trait_ref = data.to_poly_trait_ref(); + let self_ty = trait_ref.self_ty(); + debug!("self_ty {:?} {:?} trait_ref {:?}", self_ty, self_ty.kind, trait_ref); + + if predicate.references_error() { + return; + } + // Typically, this ambiguity should only happen if + // there are unresolved type inference variables + // (otherwise it would suggest a coherence + // failure). But given #21974 that is not necessarily + // the case -- we can have multiple where clauses that + // are only distinguished by a region, which results + // in an ambiguity even when all types are fully + // known, since we don't dispatch based on region + // relationships. + + // This is kind of a hack: it frequently happens that some earlier + // error prevents types from being fully inferred, and then we get + // a bunch of uninteresting errors saying something like " doesn't implement Sized". It may even be true that we + // could just skip over all checks where the self-ty is an + // inference variable, but I was afraid that there might be an + // inference variable created, registered as an obligation, and + // then never forced by writeback, and hence by skipping here we'd + // be ignoring the fact that we don't KNOW the type works + // out. Though even that would probably be harmless, given that + // we're only talking about builtin traits, which are known to be + // inhabited. We used to check for `self.tcx.sess.has_errors()` to + // avoid inundating the user with unnecessary errors, but we now + // check upstream for type errors and dont add the obligations to + // begin with in those cases. + if self + .tcx + .lang_items() + .sized_trait() + .map_or(false, |sized_id| sized_id == trait_ref.def_id()) + { + self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0282).emit(); + return; + } + let mut err = self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0283); + err.note(&format!("cannot resolve `{}`", predicate)); + if let ObligationCauseCode::ItemObligation(def_id) = obligation.cause.code { + self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id()); + } else if let ( + Ok(ref snippet), + ObligationCauseCode::BindingObligation(ref def_id, _), + ) = + (self.tcx.sess.source_map().span_to_snippet(span), &obligation.cause.code) + { + let generics = self.tcx.generics_of(*def_id); + if !generics.params.is_empty() && !snippet.ends_with('>') { + // FIXME: To avoid spurious suggestions in functions where type arguments + // where already supplied, we check the snippet to make sure it doesn't + // end with a turbofish. Ideally we would have access to a `PathSegment` + // instead. Otherwise we would produce the following output: + // + // error[E0283]: type annotations needed + // --> $DIR/issue-54954.rs:3:24 + // | + // LL | const ARR_LEN: usize = Tt::const_val::<[i8; 123]>(); + // | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + // | | + // | cannot infer type + // | help: consider specifying the type argument + // | in the function call: + // | `Tt::const_val::<[i8; 123]>::` + // ... + // LL | const fn const_val() -> usize { + // | --------- - required by this bound in `Tt::const_val` + // | + // = note: cannot resolve `_: Tt` + + err.span_suggestion( + span, + &format!( + "consider specifying the type argument{} in the function call", + if generics.params.len() > 1 { "s" } else { "" }, + ), + format!( + "{}::<{}>", + snippet, + generics + .params + .iter() + .map(|p| p.name.to_string()) + .collect::>() + .join(", ") + ), + Applicability::HasPlaceholders, + ); + } + } + err + } + + ty::Predicate::WellFormed(ty) => { + // Same hacky approach as above to avoid deluging user + // with error messages. + if ty.references_error() || self.tcx.sess.has_errors() { + return; + } + self.need_type_info_err(body_id, span, ty, ErrorCode::E0282) + } + + ty::Predicate::Subtype(ref data) => { + if data.references_error() || self.tcx.sess.has_errors() { + // no need to overload user in such cases + return; + } + let &SubtypePredicate { a_is_expected: _, a, b } = data.skip_binder(); + // both must be type variables, or the other would've been instantiated + assert!(a.is_ty_var() && b.is_ty_var()); + self.need_type_info_err(body_id, span, a, ErrorCode::E0282) + } + ty::Predicate::Projection(ref data) => { + let trait_ref = data.to_poly_trait_ref(self.tcx); + let self_ty = trait_ref.self_ty(); + if predicate.references_error() { + return; + } + let mut err = self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0284); + err.note(&format!("cannot resolve `{}`", predicate)); + err + } + + _ => { + if self.tcx.sess.has_errors() { + return; + } + let mut err = struct_span_err!( + self.tcx.sess, + span, + E0284, + "type annotations needed: cannot resolve `{}`", + predicate, + ); + err.span_label(span, &format!("cannot resolve `{}`", predicate)); + err + } + }; + self.note_obligation_cause(&mut err, obligation); + err.emit(); + } + + /// Returns `true` if the trait predicate may apply for *some* assignment + /// to the type parameters. + fn predicate_can_apply( + &self, + param_env: ty::ParamEnv<'tcx>, + pred: ty::PolyTraitRef<'tcx>, + ) -> bool { + struct ParamToVarFolder<'a, 'tcx> { + infcx: &'a InferCtxt<'a, 'tcx>, + var_map: FxHashMap, Ty<'tcx>>, + } + + impl<'a, 'tcx> TypeFolder<'tcx> for ParamToVarFolder<'a, 'tcx> { + fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { + self.infcx.tcx + } + + fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { + if let ty::Param(ty::ParamTy { name, .. }) = ty.kind { + let infcx = self.infcx; + self.var_map.entry(ty).or_insert_with(|| { + infcx.next_ty_var(TypeVariableOrigin { + kind: TypeVariableOriginKind::TypeParameterDefinition(name, None), + span: DUMMY_SP, + }) + }) + } else { + ty.super_fold_with(self) + } + } + } + + self.probe(|_| { + let mut selcx = SelectionContext::new(self); + + let cleaned_pred = + pred.fold_with(&mut ParamToVarFolder { infcx: self, var_map: Default::default() }); + + let cleaned_pred = super::project::normalize( + &mut selcx, + param_env, + ObligationCause::dummy(), + &cleaned_pred, + ) + .value; + + let obligation = + Obligation::new(ObligationCause::dummy(), param_env, cleaned_pred.to_predicate()); + + self.predicate_may_hold(&obligation) + }) + } + + fn note_obligation_cause( + &self, + err: &mut DiagnosticBuilder<'_>, + obligation: &PredicateObligation<'tcx>, + ) { + // First, attempt to add note to this error with an async-await-specific + // message, and fall back to regular note otherwise. + if !self.maybe_note_obligation_cause_for_async_await(err, obligation) { + self.note_obligation_cause_code( + err, + &obligation.predicate, + &obligation.cause.code, + &mut vec![], + ); + } + } + + fn is_recursive_obligation( + &self, + obligated_types: &mut Vec<&ty::TyS<'tcx>>, + cause_code: &ObligationCauseCode<'tcx>, + ) -> bool { + if let ObligationCauseCode::BuiltinDerivedObligation(ref data) = cause_code { + let parent_trait_ref = self.resolve_vars_if_possible(&data.parent_trait_ref); + + if obligated_types.iter().any(|ot| ot == &parent_trait_ref.skip_binder().self_ty()) { + return true; + } + } + false + } +} + +/// Summarizes information +#[derive(Clone)] +pub enum ArgKind { + /// An argument of non-tuple type. Parameters are (name, ty) + Arg(String, String), + + /// An argument of tuple type. For a "found" argument, the span is + /// the locationo in the source of the pattern. For a "expected" + /// argument, it will be None. The vector is a list of (name, ty) + /// strings for the components of the tuple. + Tuple(Option, Vec<(String, String)>), +} + +impl ArgKind { + fn empty() -> ArgKind { + ArgKind::Arg("_".to_owned(), "_".to_owned()) + } + + /// Creates an `ArgKind` from the expected type of an + /// argument. It has no name (`_`) and an optional source span. + pub fn from_expected_ty(t: Ty<'_>, span: Option) -> ArgKind { + match t.kind { + ty::Tuple(ref tys) => ArgKind::Tuple( + span, + tys.iter().map(|ty| ("_".to_owned(), ty.to_string())).collect::>(), + ), + _ => ArgKind::Arg("_".to_owned(), t.to_string()), + } + } +} + +/// Suggest restricting a type param with a new bound. +pub fn suggest_constraining_type_param( + generics: &hir::Generics<'_>, + err: &mut DiagnosticBuilder<'_>, + param_name: &str, + constraint: &str, + source_map: &SourceMap, + span: Span, +) -> bool { + let restrict_msg = "consider further restricting this bound"; + if let Some(param) = + generics.params.iter().filter(|p| p.name.ident().as_str() == param_name).next() + { + if param_name.starts_with("impl ") { + // `impl Trait` in argument: + // `fn foo(x: impl Trait) {}` → `fn foo(t: impl Trait + Trait2) {}` + err.span_suggestion( + param.span, + restrict_msg, + // `impl CurrentTrait + MissingTrait` + format!("{} + {}", param_name, constraint), + Applicability::MachineApplicable, + ); + } else if generics.where_clause.predicates.is_empty() && param.bounds.is_empty() { + // If there are no bounds whatsoever, suggest adding a constraint + // to the type parameter: + // `fn foo(t: T) {}` → `fn foo(t: T) {}` + err.span_suggestion( + param.span, + "consider restricting this bound", + format!("{}: {}", param_name, constraint), + Applicability::MachineApplicable, + ); + } else if !generics.where_clause.predicates.is_empty() { + // There is a `where` clause, so suggest expanding it: + // `fn foo(t: T) where T: Debug {}` → + // `fn foo(t: T) where T: Debug, T: Trait {}` + err.span_suggestion( + generics.where_clause.span().unwrap().shrink_to_hi(), + &format!("consider further restricting type parameter `{}`", param_name), + format!(", {}: {}", param_name, constraint), + Applicability::MachineApplicable, + ); + } else { + // If there is no `where` clause lean towards constraining to the + // type parameter: + // `fn foo(t: T, x: X) {}` → `fn foo(t: T) {}` + // `fn foo(t: T) {}` → `fn foo(t: T) {}` + let sp = param.span.with_hi(span.hi()); + let span = source_map.span_through_char(sp, ':'); + if sp != param.span && sp != span { + // Only suggest if we have high certainty that the span + // covers the colon in `foo`. + err.span_suggestion( + span, + restrict_msg, + format!("{}: {} + ", param_name, constraint), + Applicability::MachineApplicable, + ); + } else { + err.span_label( + param.span, + &format!("consider adding a `where {}: {}` bound", param_name, constraint), + ); + } + } + return true; + } + false +} + +struct ReturnsVisitor<'v>(Vec<&'v hir::Expr<'v>>); + +impl<'v> Visitor<'v> for ReturnsVisitor<'v> { + type Map = rustc::hir::map::Map<'v>; + + fn nested_visit_map(&mut self) -> hir::intravisit::NestedVisitorMap<'_, Self::Map> { + hir::intravisit::NestedVisitorMap::None + } + + fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { + match ex.kind { + hir::ExprKind::Ret(Some(ex)) => self.0.push(ex), + _ => {} + } + hir::intravisit::walk_expr(self, ex); + } + + fn visit_body(&mut self, body: &'v hir::Body<'v>) { + if body.generator_kind().is_none() { + if let hir::ExprKind::Block(block, None) = body.value.kind { + if let Some(expr) = block.expr { + self.0.push(expr); + } + } + } + hir::intravisit::walk_body(self, body); + } +} diff --git a/src/librustc/traits/error_reporting/on_unimplemented.rs b/src/librustc/traits/error_reporting/on_unimplemented.rs new file mode 100644 index 0000000000000..9f3fc91548b21 --- /dev/null +++ b/src/librustc/traits/error_reporting/on_unimplemented.rs @@ -0,0 +1,199 @@ +use super::{ + ObligationCauseCode, OnUnimplementedDirective, OnUnimplementedNote, PredicateObligation, +}; +use crate::infer::InferCtxt; +use crate::ty::subst::Subst; +use crate::ty::{self, GenericParamDefKind}; +use rustc_hir as hir; +use rustc_hir::def_id::DefId; +use rustc_span::symbol::sym; + +impl<'a, 'tcx> InferCtxt<'a, 'tcx> { + fn impl_similar_to( + &self, + trait_ref: ty::PolyTraitRef<'tcx>, + obligation: &PredicateObligation<'tcx>, + ) -> Option { + let tcx = self.tcx; + let param_env = obligation.param_env; + let trait_ref = tcx.erase_late_bound_regions(&trait_ref); + let trait_self_ty = trait_ref.self_ty(); + + let mut self_match_impls = vec![]; + let mut fuzzy_match_impls = vec![]; + + self.tcx.for_each_relevant_impl(trait_ref.def_id, trait_self_ty, |def_id| { + let impl_substs = self.fresh_substs_for_item(obligation.cause.span, def_id); + let impl_trait_ref = tcx.impl_trait_ref(def_id).unwrap().subst(tcx, impl_substs); + + let impl_self_ty = impl_trait_ref.self_ty(); + + if let Ok(..) = self.can_eq(param_env, trait_self_ty, impl_self_ty) { + self_match_impls.push(def_id); + + if trait_ref + .substs + .types() + .skip(1) + .zip(impl_trait_ref.substs.types().skip(1)) + .all(|(u, v)| self.fuzzy_match_tys(u, v)) + { + fuzzy_match_impls.push(def_id); + } + } + }); + + let impl_def_id = if self_match_impls.len() == 1 { + self_match_impls[0] + } else if fuzzy_match_impls.len() == 1 { + fuzzy_match_impls[0] + } else { + return None; + }; + + tcx.has_attr(impl_def_id, sym::rustc_on_unimplemented).then_some(impl_def_id) + } + + /// Used to set on_unimplemented's `ItemContext` + /// to be the enclosing (async) block/function/closure + fn describe_enclosure(&self, hir_id: hir::HirId) -> Option<&'static str> { + let hir = &self.tcx.hir(); + let node = hir.find(hir_id)?; + if let hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, _, body_id), .. }) = &node { + self.describe_generator(*body_id).or_else(|| { + Some(if let hir::FnHeader { asyncness: hir::IsAsync::Async, .. } = sig.header { + "an async function" + } else { + "a function" + }) + }) + } else if let hir::Node::Expr(hir::Expr { + kind: hir::ExprKind::Closure(_is_move, _, body_id, _, gen_movability), + .. + }) = &node + { + self.describe_generator(*body_id).or_else(|| { + Some(if gen_movability.is_some() { "an async closure" } else { "a closure" }) + }) + } else if let hir::Node::Expr(hir::Expr { .. }) = &node { + let parent_hid = hir.get_parent_node(hir_id); + if parent_hid != hir_id { + return self.describe_enclosure(parent_hid); + } else { + None + } + } else { + None + } + } + + crate fn on_unimplemented_note( + &self, + trait_ref: ty::PolyTraitRef<'tcx>, + obligation: &PredicateObligation<'tcx>, + ) -> OnUnimplementedNote { + let def_id = + self.impl_similar_to(trait_ref, obligation).unwrap_or_else(|| trait_ref.def_id()); + let trait_ref = *trait_ref.skip_binder(); + + let mut flags = vec![]; + flags.push(( + sym::item_context, + self.describe_enclosure(obligation.cause.body_id).map(|s| s.to_owned()), + )); + + match obligation.cause.code { + ObligationCauseCode::BuiltinDerivedObligation(..) + | ObligationCauseCode::ImplDerivedObligation(..) => {} + _ => { + // this is a "direct", user-specified, rather than derived, + // obligation. + flags.push((sym::direct, None)); + } + } + + if let ObligationCauseCode::ItemObligation(item) = obligation.cause.code { + // FIXME: maybe also have some way of handling methods + // from other traits? That would require name resolution, + // which we might want to be some sort of hygienic. + // + // Currently I'm leaving it for what I need for `try`. + if self.tcx.trait_of_item(item) == Some(trait_ref.def_id) { + let method = self.tcx.item_name(item); + flags.push((sym::from_method, None)); + flags.push((sym::from_method, Some(method.to_string()))); + } + } + if let Some((t, _)) = self.get_parent_trait_ref(&obligation.cause.code) { + flags.push((sym::parent_trait, Some(t))); + } + + if let Some(k) = obligation.cause.span.desugaring_kind() { + flags.push((sym::from_desugaring, None)); + flags.push((sym::from_desugaring, Some(format!("{:?}", k)))); + } + let generics = self.tcx.generics_of(def_id); + let self_ty = trait_ref.self_ty(); + // This is also included through the generics list as `Self`, + // but the parser won't allow you to use it + flags.push((sym::_Self, Some(self_ty.to_string()))); + if let Some(def) = self_ty.ty_adt_def() { + // We also want to be able to select self's original + // signature with no type arguments resolved + flags.push((sym::_Self, Some(self.tcx.type_of(def.did).to_string()))); + } + + for param in generics.params.iter() { + let value = match param.kind { + GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => { + trait_ref.substs[param.index as usize].to_string() + } + GenericParamDefKind::Lifetime => continue, + }; + let name = param.name; + flags.push((name, Some(value))); + } + + if let Some(true) = self_ty.ty_adt_def().map(|def| def.did.is_local()) { + flags.push((sym::crate_local, None)); + } + + // Allow targeting all integers using `{integral}`, even if the exact type was resolved + if self_ty.is_integral() { + flags.push((sym::_Self, Some("{integral}".to_owned()))); + } + + if let ty::Array(aty, len) = self_ty.kind { + flags.push((sym::_Self, Some("[]".to_owned()))); + flags.push((sym::_Self, Some(format!("[{}]", aty)))); + if let Some(def) = aty.ty_adt_def() { + // We also want to be able to select the array's type's original + // signature with no type arguments resolved + flags.push(( + sym::_Self, + Some(format!("[{}]", self.tcx.type_of(def.did).to_string())), + )); + let tcx = self.tcx; + if let Some(len) = len.try_eval_usize(tcx, ty::ParamEnv::empty()) { + flags.push(( + sym::_Self, + Some(format!("[{}; {}]", self.tcx.type_of(def.did).to_string(), len)), + )); + } else { + flags.push(( + sym::_Self, + Some(format!("[{}; _]", self.tcx.type_of(def.did).to_string())), + )); + } + } + } + + if let Ok(Some(command)) = + OnUnimplementedDirective::of_item(self.tcx, trait_ref.def_id, def_id) + { + command.evaluate(self.tcx, trait_ref, &flags[..]) + } else { + OnUnimplementedNote::default() + } + } +} diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting/suggestions.rs similarity index 52% rename from src/librustc/traits/error_reporting.rs rename to src/librustc/traits/error_reporting/suggestions.rs index 77a73aba45484..389edfa071794 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting/suggestions.rs @@ -1,1178 +1,28 @@ -// ignore-tidy-filelength use super::{ - ConstEvalFailure, EvaluationResult, FulfillmentError, FulfillmentErrorCode, - MismatchedProjectionTypes, ObjectSafetyViolation, Obligation, ObligationCause, - ObligationCauseCode, OnUnimplementedDirective, OnUnimplementedNote, - OutputTypeParameterMismatch, Overflow, PredicateObligation, SelectionContext, SelectionError, - TraitNotObjectSafe, + ArgKind, EvaluationResult, Obligation, ObligationCause, ObligationCauseCode, + PredicateObligation, }; -use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode}; -use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; -use crate::infer::{self, InferCtxt}; -use crate::mir::interpret::ErrorHandled; -use crate::session::DiagnosticMessageId; -use crate::traits::object_safety_violations; -use crate::ty::error::ExpectedFound; -use crate::ty::fast_reject; -use crate::ty::fold::TypeFolder; -use crate::ty::subst::Subst; -use crate::ty::GenericParamDefKind; -use crate::ty::SubtypePredicate; +use crate::infer::InferCtxt; use crate::ty::TypeckTables; -use crate::ty::{self, AdtKind, DefIdTree, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable}; +use crate::ty::{self, AdtKind, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable}; -use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{ error_code, pluralize, struct_span_err, Applicability, DiagnosticBuilder, Style, }; use rustc_hir as hir; -use rustc_hir::def_id::{DefId, LOCAL_CRATE}; +use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; use rustc_hir::Node; use rustc_span::source_map::SourceMap; use rustc_span::symbol::{kw, sym}; -use rustc_span::{ExpnKind, MultiSpan, Span, DUMMY_SP}; +use rustc_span::{MultiSpan, Span, DUMMY_SP}; use std::fmt; -use syntax::ast; use rustc_error_codes::*; impl<'a, 'tcx> InferCtxt<'a, 'tcx> { - pub fn report_fulfillment_errors( - &self, - errors: &[FulfillmentError<'tcx>], - body_id: Option, - fallback_has_occurred: bool, - ) { - #[derive(Debug)] - struct ErrorDescriptor<'tcx> { - predicate: ty::Predicate<'tcx>, - index: Option, // None if this is an old error - } - - let mut error_map: FxHashMap<_, Vec<_>> = self - .reported_trait_errors - .borrow() - .iter() - .map(|(&span, predicates)| { - ( - span, - predicates - .iter() - .map(|predicate| ErrorDescriptor { - predicate: predicate.clone(), - index: None, - }) - .collect(), - ) - }) - .collect(); - - for (index, error) in errors.iter().enumerate() { - // We want to ignore desugarings here: spans are equivalent even - // if one is the result of a desugaring and the other is not. - let mut span = error.obligation.cause.span; - let expn_data = span.ctxt().outer_expn_data(); - if let ExpnKind::Desugaring(_) = expn_data.kind { - span = expn_data.call_site; - } - - error_map.entry(span).or_default().push(ErrorDescriptor { - predicate: error.obligation.predicate.clone(), - index: Some(index), - }); - - self.reported_trait_errors - .borrow_mut() - .entry(span) - .or_default() - .push(error.obligation.predicate.clone()); - } - - // We do this in 2 passes because we want to display errors in order, though - // maybe it *is* better to sort errors by span or something. - let mut is_suppressed = vec![false; errors.len()]; - for (_, error_set) in error_map.iter() { - // We want to suppress "duplicate" errors with the same span. - for error in error_set { - if let Some(index) = error.index { - // Suppress errors that are either: - // 1) strictly implied by another error. - // 2) implied by an error with a smaller index. - for error2 in error_set { - if error2.index.map_or(false, |index2| is_suppressed[index2]) { - // Avoid errors being suppressed by already-suppressed - // errors, to prevent all errors from being suppressed - // at once. - continue; - } - - if self.error_implies(&error2.predicate, &error.predicate) - && !(error2.index >= error.index - && self.error_implies(&error.predicate, &error2.predicate)) - { - info!("skipping {:?} (implied by {:?})", error, error2); - is_suppressed[index] = true; - break; - } - } - } - } - } - - for (error, suppressed) in errors.iter().zip(is_suppressed) { - if !suppressed { - self.report_fulfillment_error(error, body_id, fallback_has_occurred); - } - } - } - - // returns if `cond` not occurring implies that `error` does not occur - i.e., that - // `error` occurring implies that `cond` occurs. - fn error_implies(&self, cond: &ty::Predicate<'tcx>, error: &ty::Predicate<'tcx>) -> bool { - if cond == error { - return true; - } - - let (cond, error) = match (cond, error) { - (&ty::Predicate::Trait(..), &ty::Predicate::Trait(ref error)) => (cond, error), - _ => { - // FIXME: make this work in other cases too. - return false; - } - }; - - for implication in super::elaborate_predicates(self.tcx, vec![cond.clone()]) { - if let ty::Predicate::Trait(implication) = implication { - let error = error.to_poly_trait_ref(); - let implication = implication.to_poly_trait_ref(); - // FIXME: I'm just not taking associated types at all here. - // Eventually I'll need to implement param-env-aware - // `Γ₁ ⊦ φ₁ => Γ₂ ⊦ φ₂` logic. - let param_env = ty::ParamEnv::empty(); - if self.can_sub(param_env, error, implication).is_ok() { - debug!("error_implies: {:?} -> {:?} -> {:?}", cond, error, implication); - return true; - } - } - } - - false - } - - fn report_fulfillment_error( - &self, - error: &FulfillmentError<'tcx>, - body_id: Option, - fallback_has_occurred: bool, - ) { - debug!("report_fulfillment_error({:?})", error); - match error.code { - FulfillmentErrorCode::CodeSelectionError(ref selection_error) => { - self.report_selection_error( - &error.obligation, - selection_error, - fallback_has_occurred, - error.points_at_arg_span, - ); - } - FulfillmentErrorCode::CodeProjectionError(ref e) => { - self.report_projection_error(&error.obligation, e); - } - FulfillmentErrorCode::CodeAmbiguity => { - self.maybe_report_ambiguity(&error.obligation, body_id); - } - FulfillmentErrorCode::CodeSubtypeError(ref expected_found, ref err) => { - self.report_mismatched_types( - &error.obligation.cause, - expected_found.expected, - expected_found.found, - err.clone(), - ) - .emit(); - } - } - } - - fn report_projection_error( - &self, - obligation: &PredicateObligation<'tcx>, - error: &MismatchedProjectionTypes<'tcx>, - ) { - let predicate = self.resolve_vars_if_possible(&obligation.predicate); - - if predicate.references_error() { - return; - } - - self.probe(|_| { - let err_buf; - let mut err = &error.err; - let mut values = None; - - // try to find the mismatched types to report the error with. - // - // this can fail if the problem was higher-ranked, in which - // cause I have no idea for a good error message. - if let ty::Predicate::Projection(ref data) = predicate { - let mut selcx = SelectionContext::new(self); - let (data, _) = self.replace_bound_vars_with_fresh_vars( - obligation.cause.span, - infer::LateBoundRegionConversionTime::HigherRankedType, - data, - ); - let mut obligations = vec![]; - let normalized_ty = super::normalize_projection_type( - &mut selcx, - obligation.param_env, - data.projection_ty, - obligation.cause.clone(), - 0, - &mut obligations, - ); - - debug!( - "report_projection_error obligation.cause={:?} obligation.param_env={:?}", - obligation.cause, obligation.param_env - ); - - debug!( - "report_projection_error normalized_ty={:?} data.ty={:?}", - normalized_ty, data.ty - ); - - let is_normalized_ty_expected = match &obligation.cause.code { - ObligationCauseCode::ItemObligation(_) - | ObligationCauseCode::BindingObligation(_, _) - | ObligationCauseCode::ObjectCastObligation(_) => false, - _ => true, - }; - - if let Err(error) = self.at(&obligation.cause, obligation.param_env).eq_exp( - is_normalized_ty_expected, - normalized_ty, - data.ty, - ) { - values = Some(infer::ValuePairs::Types(ExpectedFound::new( - is_normalized_ty_expected, - normalized_ty, - data.ty, - ))); - - err_buf = error; - err = &err_buf; - } - } - - let msg = format!("type mismatch resolving `{}`", predicate); - let error_id = (DiagnosticMessageId::ErrorId(271), Some(obligation.cause.span), msg); - let fresh = self.tcx.sess.one_time_diagnostics.borrow_mut().insert(error_id); - if fresh { - let mut diag = struct_span_err!( - self.tcx.sess, - obligation.cause.span, - E0271, - "type mismatch resolving `{}`", - predicate - ); - self.note_type_err(&mut diag, &obligation.cause, None, values, err); - self.note_obligation_cause(&mut diag, obligation); - diag.emit(); - } - }); - } - - fn fuzzy_match_tys(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> bool { - /// returns the fuzzy category of a given type, or None - /// if the type can be equated to any type. - fn type_category(t: Ty<'_>) -> Option { - match t.kind { - ty::Bool => Some(0), - ty::Char => Some(1), - ty::Str => Some(2), - ty::Int(..) | ty::Uint(..) | ty::Infer(ty::IntVar(..)) => Some(3), - ty::Float(..) | ty::Infer(ty::FloatVar(..)) => Some(4), - ty::Ref(..) | ty::RawPtr(..) => Some(5), - ty::Array(..) | ty::Slice(..) => Some(6), - ty::FnDef(..) | ty::FnPtr(..) => Some(7), - ty::Dynamic(..) => Some(8), - ty::Closure(..) => Some(9), - ty::Tuple(..) => Some(10), - ty::Projection(..) => Some(11), - ty::Param(..) => Some(12), - ty::Opaque(..) => Some(13), - ty::Never => Some(14), - ty::Adt(adt, ..) => match adt.adt_kind() { - AdtKind::Struct => Some(15), - AdtKind::Union => Some(16), - AdtKind::Enum => Some(17), - }, - ty::Generator(..) => Some(18), - ty::Foreign(..) => Some(19), - ty::GeneratorWitness(..) => Some(20), - ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) | ty::Error => None, - ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"), - } - } - - match (type_category(a), type_category(b)) { - (Some(cat_a), Some(cat_b)) => match (&a.kind, &b.kind) { - (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => def_a == def_b, - _ => cat_a == cat_b, - }, - // infer and error can be equated to all types - _ => true, - } - } - - fn impl_similar_to( - &self, - trait_ref: ty::PolyTraitRef<'tcx>, - obligation: &PredicateObligation<'tcx>, - ) -> Option { - let tcx = self.tcx; - let param_env = obligation.param_env; - let trait_ref = tcx.erase_late_bound_regions(&trait_ref); - let trait_self_ty = trait_ref.self_ty(); - - let mut self_match_impls = vec![]; - let mut fuzzy_match_impls = vec![]; - - self.tcx.for_each_relevant_impl(trait_ref.def_id, trait_self_ty, |def_id| { - let impl_substs = self.fresh_substs_for_item(obligation.cause.span, def_id); - let impl_trait_ref = tcx.impl_trait_ref(def_id).unwrap().subst(tcx, impl_substs); - - let impl_self_ty = impl_trait_ref.self_ty(); - - if let Ok(..) = self.can_eq(param_env, trait_self_ty, impl_self_ty) { - self_match_impls.push(def_id); - - if trait_ref - .substs - .types() - .skip(1) - .zip(impl_trait_ref.substs.types().skip(1)) - .all(|(u, v)| self.fuzzy_match_tys(u, v)) - { - fuzzy_match_impls.push(def_id); - } - } - }); - - let impl_def_id = if self_match_impls.len() == 1 { - self_match_impls[0] - } else if fuzzy_match_impls.len() == 1 { - fuzzy_match_impls[0] - } else { - return None; - }; - - tcx.has_attr(impl_def_id, sym::rustc_on_unimplemented).then_some(impl_def_id) - } - - fn describe_generator(&self, body_id: hir::BodyId) -> Option<&'static str> { - self.tcx.hir().body(body_id).generator_kind.map(|gen_kind| match gen_kind { - hir::GeneratorKind::Gen => "a generator", - hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Block) => "an async block", - hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Fn) => "an async function", - hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Closure) => "an async closure", - }) - } - - /// Used to set on_unimplemented's `ItemContext` - /// to be the enclosing (async) block/function/closure - fn describe_enclosure(&self, hir_id: hir::HirId) -> Option<&'static str> { - let hir = &self.tcx.hir(); - let node = hir.find(hir_id)?; - if let hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, _, body_id), .. }) = &node { - self.describe_generator(*body_id).or_else(|| { - Some(if let hir::FnHeader { asyncness: hir::IsAsync::Async, .. } = sig.header { - "an async function" - } else { - "a function" - }) - }) - } else if let hir::Node::Expr(hir::Expr { - kind: hir::ExprKind::Closure(_is_move, _, body_id, _, gen_movability), - .. - }) = &node - { - self.describe_generator(*body_id).or_else(|| { - Some(if gen_movability.is_some() { "an async closure" } else { "a closure" }) - }) - } else if let hir::Node::Expr(hir::Expr { .. }) = &node { - let parent_hid = hir.get_parent_node(hir_id); - if parent_hid != hir_id { - return self.describe_enclosure(parent_hid); - } else { - None - } - } else { - None - } - } - - fn on_unimplemented_note( - &self, - trait_ref: ty::PolyTraitRef<'tcx>, - obligation: &PredicateObligation<'tcx>, - ) -> OnUnimplementedNote { - let def_id = - self.impl_similar_to(trait_ref, obligation).unwrap_or_else(|| trait_ref.def_id()); - let trait_ref = *trait_ref.skip_binder(); - - let mut flags = vec![]; - flags.push(( - sym::item_context, - self.describe_enclosure(obligation.cause.body_id).map(|s| s.to_owned()), - )); - - match obligation.cause.code { - ObligationCauseCode::BuiltinDerivedObligation(..) - | ObligationCauseCode::ImplDerivedObligation(..) => {} - _ => { - // this is a "direct", user-specified, rather than derived, - // obligation. - flags.push((sym::direct, None)); - } - } - - if let ObligationCauseCode::ItemObligation(item) = obligation.cause.code { - // FIXME: maybe also have some way of handling methods - // from other traits? That would require name resolution, - // which we might want to be some sort of hygienic. - // - // Currently I'm leaving it for what I need for `try`. - if self.tcx.trait_of_item(item) == Some(trait_ref.def_id) { - let method = self.tcx.item_name(item); - flags.push((sym::from_method, None)); - flags.push((sym::from_method, Some(method.to_string()))); - } - } - if let Some((t, _)) = self.get_parent_trait_ref(&obligation.cause.code) { - flags.push((sym::parent_trait, Some(t))); - } - - if let Some(k) = obligation.cause.span.desugaring_kind() { - flags.push((sym::from_desugaring, None)); - flags.push((sym::from_desugaring, Some(format!("{:?}", k)))); - } - let generics = self.tcx.generics_of(def_id); - let self_ty = trait_ref.self_ty(); - // This is also included through the generics list as `Self`, - // but the parser won't allow you to use it - flags.push((sym::_Self, Some(self_ty.to_string()))); - if let Some(def) = self_ty.ty_adt_def() { - // We also want to be able to select self's original - // signature with no type arguments resolved - flags.push((sym::_Self, Some(self.tcx.type_of(def.did).to_string()))); - } - - for param in generics.params.iter() { - let value = match param.kind { - GenericParamDefKind::Type { .. } | GenericParamDefKind::Const => { - trait_ref.substs[param.index as usize].to_string() - } - GenericParamDefKind::Lifetime => continue, - }; - let name = param.name; - flags.push((name, Some(value))); - } - - if let Some(true) = self_ty.ty_adt_def().map(|def| def.did.is_local()) { - flags.push((sym::crate_local, None)); - } - - // Allow targeting all integers using `{integral}`, even if the exact type was resolved - if self_ty.is_integral() { - flags.push((sym::_Self, Some("{integral}".to_owned()))); - } - - if let ty::Array(aty, len) = self_ty.kind { - flags.push((sym::_Self, Some("[]".to_owned()))); - flags.push((sym::_Self, Some(format!("[{}]", aty)))); - if let Some(def) = aty.ty_adt_def() { - // We also want to be able to select the array's type's original - // signature with no type arguments resolved - flags.push(( - sym::_Self, - Some(format!("[{}]", self.tcx.type_of(def.did).to_string())), - )); - let tcx = self.tcx; - if let Some(len) = len.try_eval_usize(tcx, ty::ParamEnv::empty()) { - flags.push(( - sym::_Self, - Some(format!("[{}; {}]", self.tcx.type_of(def.did).to_string(), len)), - )); - } else { - flags.push(( - sym::_Self, - Some(format!("[{}; _]", self.tcx.type_of(def.did).to_string())), - )); - } - } - } - - if let Ok(Some(command)) = - OnUnimplementedDirective::of_item(self.tcx, trait_ref.def_id, def_id) - { - command.evaluate(self.tcx, trait_ref, &flags[..]) - } else { - OnUnimplementedNote::default() - } - } - - fn find_similar_impl_candidates( - &self, - trait_ref: ty::PolyTraitRef<'tcx>, - ) -> Vec> { - let simp = fast_reject::simplify_type(self.tcx, trait_ref.skip_binder().self_ty(), true); - let all_impls = self.tcx.all_impls(trait_ref.def_id()); - - match simp { - Some(simp) => all_impls - .iter() - .filter_map(|&def_id| { - let imp = self.tcx.impl_trait_ref(def_id).unwrap(); - let imp_simp = fast_reject::simplify_type(self.tcx, imp.self_ty(), true); - if let Some(imp_simp) = imp_simp { - if simp != imp_simp { - return None; - } - } - - Some(imp) - }) - .collect(), - None => { - all_impls.iter().map(|&def_id| self.tcx.impl_trait_ref(def_id).unwrap()).collect() - } - } - } - - fn report_similar_impl_candidates( - &self, - impl_candidates: Vec>, - err: &mut DiagnosticBuilder<'_>, - ) { - if impl_candidates.is_empty() { - return; - } - - let len = impl_candidates.len(); - let end = if impl_candidates.len() <= 5 { impl_candidates.len() } else { 4 }; - - let normalize = |candidate| { - self.tcx.infer_ctxt().enter(|ref infcx| { - let normalized = infcx - .at(&ObligationCause::dummy(), ty::ParamEnv::empty()) - .normalize(candidate) - .ok(); - match normalized { - Some(normalized) => format!("\n {:?}", normalized.value), - None => format!("\n {:?}", candidate), - } - }) - }; - - // Sort impl candidates so that ordering is consistent for UI tests. - let mut normalized_impl_candidates = - impl_candidates.iter().map(normalize).collect::>(); - - // Sort before taking the `..end` range, - // because the ordering of `impl_candidates` may not be deterministic: - // https://github.com/rust-lang/rust/pull/57475#issuecomment-455519507 - normalized_impl_candidates.sort(); - - err.help(&format!( - "the following implementations were found:{}{}", - normalized_impl_candidates[..end].join(""), - if len > 5 { format!("\nand {} others", len - 4) } else { String::new() } - )); - } - - /// Reports that an overflow has occurred and halts compilation. We - /// halt compilation unconditionally because it is important that - /// overflows never be masked -- they basically represent computations - /// whose result could not be truly determined and thus we can't say - /// if the program type checks or not -- and they are unusual - /// occurrences in any case. - pub fn report_overflow_error( - &self, - obligation: &Obligation<'tcx, T>, - suggest_increasing_limit: bool, - ) -> ! - where - T: fmt::Display + TypeFoldable<'tcx>, - { - let predicate = self.resolve_vars_if_possible(&obligation.predicate); - let mut err = struct_span_err!( - self.tcx.sess, - obligation.cause.span, - E0275, - "overflow evaluating the requirement `{}`", - predicate - ); - - if suggest_increasing_limit { - self.suggest_new_overflow_limit(&mut err); - } - - self.note_obligation_cause_code( - &mut err, - &obligation.predicate, - &obligation.cause.code, - &mut vec![], - ); - - err.emit(); - self.tcx.sess.abort_if_errors(); - bug!(); - } - - /// Reports that a cycle was detected which led to overflow and halts - /// compilation. This is equivalent to `report_overflow_error` except - /// that we can give a more helpful error message (and, in particular, - /// we do not suggest increasing the overflow limit, which is not - /// going to help). - pub fn report_overflow_error_cycle(&self, cycle: &[PredicateObligation<'tcx>]) -> ! { - let cycle = self.resolve_vars_if_possible(&cycle.to_owned()); - assert!(cycle.len() > 0); - - debug!("report_overflow_error_cycle: cycle={:?}", cycle); - - self.report_overflow_error(&cycle[0], false); - } - - pub fn report_extra_impl_obligation( - &self, - error_span: Span, - item_name: ast::Name, - _impl_item_def_id: DefId, - trait_item_def_id: DefId, - requirement: &dyn fmt::Display, - ) -> DiagnosticBuilder<'tcx> { - let msg = "impl has stricter requirements than trait"; - let sp = self.tcx.sess.source_map().def_span(error_span); - - let mut err = struct_span_err!(self.tcx.sess, sp, E0276, "{}", msg); - - if let Some(trait_item_span) = self.tcx.hir().span_if_local(trait_item_def_id) { - let span = self.tcx.sess.source_map().def_span(trait_item_span); - err.span_label(span, format!("definition of `{}` from trait", item_name)); - } - - err.span_label(sp, format!("impl has extra requirement {}", requirement)); - - err - } - - /// Gets the parent trait chain start - fn get_parent_trait_ref( - &self, - code: &ObligationCauseCode<'tcx>, - ) -> Option<(String, Option)> { - match code { - &ObligationCauseCode::BuiltinDerivedObligation(ref data) => { - let parent_trait_ref = self.resolve_vars_if_possible(&data.parent_trait_ref); - match self.get_parent_trait_ref(&data.parent_code) { - Some(t) => Some(t), - None => { - let ty = parent_trait_ref.skip_binder().self_ty(); - let span = - TyCategory::from_ty(ty).map(|(_, def_id)| self.tcx.def_span(def_id)); - Some((ty.to_string(), span)) - } - } - } - _ => None, - } - } - - pub fn report_selection_error( - &self, - obligation: &PredicateObligation<'tcx>, - error: &SelectionError<'tcx>, - fallback_has_occurred: bool, - points_at_arg: bool, - ) { - let tcx = self.tcx; - let span = obligation.cause.span; - - let mut err = match *error { - SelectionError::Unimplemented => { - if let ObligationCauseCode::CompareImplMethodObligation { - item_name, - impl_item_def_id, - trait_item_def_id, - } - | ObligationCauseCode::CompareImplTypeObligation { - item_name, - impl_item_def_id, - trait_item_def_id, - } = obligation.cause.code - { - self.report_extra_impl_obligation( - span, - item_name, - impl_item_def_id, - trait_item_def_id, - &format!("`{}`", obligation.predicate), - ) - .emit(); - return; - } - match obligation.predicate { - ty::Predicate::Trait(ref trait_predicate) => { - let trait_predicate = self.resolve_vars_if_possible(trait_predicate); - - if self.tcx.sess.has_errors() && trait_predicate.references_error() { - return; - } - let trait_ref = trait_predicate.to_poly_trait_ref(); - let (post_message, pre_message, type_def) = self - .get_parent_trait_ref(&obligation.cause.code) - .map(|(t, s)| { - ( - format!(" in `{}`", t), - format!("within `{}`, ", t), - s.map(|s| (format!("within this `{}`", t), s)), - ) - }) - .unwrap_or_default(); - - let OnUnimplementedNote { message, label, note, enclosing_scope } = - self.on_unimplemented_note(trait_ref, obligation); - let have_alt_message = message.is_some() || label.is_some(); - let is_try = self - .tcx - .sess - .source_map() - .span_to_snippet(span) - .map(|s| &s == "?") - .unwrap_or(false); - let is_from = format!("{}", trait_ref.print_only_trait_path()) - .starts_with("std::convert::From<"); - let (message, note) = if is_try && is_from { - ( - Some(format!( - "`?` couldn't convert the error to `{}`", - trait_ref.self_ty(), - )), - Some( - "the question mark operation (`?`) implicitly performs a \ - conversion on the error value using the `From` trait" - .to_owned(), - ), - ) - } else { - (message, note) - }; - - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0277, - "{}", - message.unwrap_or_else(|| format!( - "the trait bound `{}` is not satisfied{}", - trait_ref.to_predicate(), - post_message, - )) - ); - - let explanation = - if obligation.cause.code == ObligationCauseCode::MainFunctionType { - "consider using `()`, or a `Result`".to_owned() - } else { - format!( - "{}the trait `{}` is not implemented for `{}`", - pre_message, - trait_ref.print_only_trait_path(), - trait_ref.self_ty(), - ) - }; - - if self.suggest_add_reference_to_arg( - &obligation, - &mut err, - &trait_ref, - points_at_arg, - have_alt_message, - ) { - self.note_obligation_cause(&mut err, obligation); - err.emit(); - return; - } - if let Some(ref s) = label { - // If it has a custom `#[rustc_on_unimplemented]` - // error message, let's display it as the label! - err.span_label(span, s.as_str()); - err.help(&explanation); - } else { - err.span_label(span, explanation); - } - if let Some((msg, span)) = type_def { - err.span_label(span, &msg); - } - if let Some(ref s) = note { - // If it has a custom `#[rustc_on_unimplemented]` note, let's display it - err.note(s.as_str()); - } - if let Some(ref s) = enclosing_scope { - let enclosing_scope_span = tcx.def_span( - tcx.hir() - .opt_local_def_id(obligation.cause.body_id) - .unwrap_or_else(|| { - tcx.hir().body_owner_def_id(hir::BodyId { - hir_id: obligation.cause.body_id, - }) - }), - ); - - err.span_label(enclosing_scope_span, s.as_str()); - } - - self.suggest_borrow_on_unsized_slice(&obligation.cause.code, &mut err); - self.suggest_fn_call(&obligation, &mut err, &trait_ref, points_at_arg); - self.suggest_remove_reference(&obligation, &mut err, &trait_ref); - self.suggest_semicolon_removal(&obligation, &mut err, span, &trait_ref); - self.note_version_mismatch(&mut err, &trait_ref); - if self.suggest_impl_trait(&mut err, span, &obligation, &trait_ref) { - err.emit(); - return; - } - - // Try to report a help message - if !trait_ref.has_infer_types() - && self.predicate_can_apply(obligation.param_env, trait_ref) - { - // If a where-clause may be useful, remind the - // user that they can add it. - // - // don't display an on-unimplemented note, as - // these notes will often be of the form - // "the type `T` can't be frobnicated" - // which is somewhat confusing. - self.suggest_restricting_param_bound( - &mut err, - &trait_ref, - obligation.cause.body_id, - ); - } else { - if !have_alt_message { - // Can't show anything else useful, try to find similar impls. - let impl_candidates = self.find_similar_impl_candidates(trait_ref); - self.report_similar_impl_candidates(impl_candidates, &mut err); - } - self.suggest_change_mut( - &obligation, - &mut err, - &trait_ref, - points_at_arg, - ); - } - - // If this error is due to `!: Trait` not implemented but `(): Trait` is - // implemented, and fallback has occurred, then it could be due to a - // variable that used to fallback to `()` now falling back to `!`. Issue a - // note informing about the change in behaviour. - if trait_predicate.skip_binder().self_ty().is_never() - && fallback_has_occurred - { - let predicate = trait_predicate.map_bound(|mut trait_pred| { - trait_pred.trait_ref.substs = self.tcx.mk_substs_trait( - self.tcx.mk_unit(), - &trait_pred.trait_ref.substs[1..], - ); - trait_pred - }); - let unit_obligation = Obligation { - predicate: ty::Predicate::Trait(predicate), - ..obligation.clone() - }; - if self.predicate_may_hold(&unit_obligation) { - err.note( - "the trait is implemented for `()`. \ - Possibly this error has been caused by changes to \ - Rust's type-inference algorithm \ - (see: https://github.com/rust-lang/rust/issues/48950 \ - for more info). Consider whether you meant to use the \ - type `()` here instead.", - ); - } - } - - err - } - - ty::Predicate::Subtype(ref predicate) => { - // Errors for Subtype predicates show up as - // `FulfillmentErrorCode::CodeSubtypeError`, - // not selection error. - span_bug!(span, "subtype requirement gave wrong error: `{:?}`", predicate) - } - - ty::Predicate::RegionOutlives(ref predicate) => { - let predicate = self.resolve_vars_if_possible(predicate); - let err = self - .region_outlives_predicate(&obligation.cause, &predicate) - .err() - .unwrap(); - struct_span_err!( - self.tcx.sess, - span, - E0279, - "the requirement `{}` is not satisfied (`{}`)", - predicate, - err, - ) - } - - ty::Predicate::Projection(..) | ty::Predicate::TypeOutlives(..) => { - let predicate = self.resolve_vars_if_possible(&obligation.predicate); - struct_span_err!( - self.tcx.sess, - span, - E0280, - "the requirement `{}` is not satisfied", - predicate - ) - } - - ty::Predicate::ObjectSafe(trait_def_id) => { - let violations = object_safety_violations(self.tcx, trait_def_id); - report_object_safety_error(self.tcx, span, trait_def_id, violations) - } - - ty::Predicate::ClosureKind(closure_def_id, closure_substs, kind) => { - let found_kind = self.closure_kind(closure_def_id, closure_substs).unwrap(); - let closure_span = self - .tcx - .sess - .source_map() - .def_span(self.tcx.hir().span_if_local(closure_def_id).unwrap()); - let hir_id = self.tcx.hir().as_local_hir_id(closure_def_id).unwrap(); - let mut err = struct_span_err!( - self.tcx.sess, - closure_span, - E0525, - "expected a closure that implements the `{}` trait, \ - but this closure only implements `{}`", - kind, - found_kind - ); - - err.span_label( - closure_span, - format!("this closure implements `{}`, not `{}`", found_kind, kind), - ); - err.span_label( - obligation.cause.span, - format!("the requirement to implement `{}` derives from here", kind), - ); - - // Additional context information explaining why the closure only implements - // a particular trait. - if let Some(tables) = self.in_progress_tables { - let tables = tables.borrow(); - match (found_kind, tables.closure_kind_origins().get(hir_id)) { - (ty::ClosureKind::FnOnce, Some((span, name))) => { - err.span_label( - *span, - format!( - "closure is `FnOnce` because it moves the \ - variable `{}` out of its environment", - name - ), - ); - } - (ty::ClosureKind::FnMut, Some((span, name))) => { - err.span_label( - *span, - format!( - "closure is `FnMut` because it mutates the \ - variable `{}` here", - name - ), - ); - } - _ => {} - } - } - - err.emit(); - return; - } - - ty::Predicate::WellFormed(ty) => { - if !self.tcx.sess.opts.debugging_opts.chalk { - // WF predicates cannot themselves make - // errors. They can only block due to - // ambiguity; otherwise, they always - // degenerate into other obligations - // (which may fail). - span_bug!(span, "WF predicate not satisfied for {:?}", ty); - } else { - // FIXME: we'll need a better message which takes into account - // which bounds actually failed to hold. - self.tcx.sess.struct_span_err( - span, - &format!("the type `{}` is not well-formed (chalk)", ty), - ) - } - } - - ty::Predicate::ConstEvaluatable(..) => { - // Errors for `ConstEvaluatable` predicates show up as - // `SelectionError::ConstEvalFailure`, - // not `Unimplemented`. - span_bug!( - span, - "const-evaluatable requirement gave wrong error: `{:?}`", - obligation - ) - } - } - } - - OutputTypeParameterMismatch(ref found_trait_ref, ref expected_trait_ref, _) => { - let found_trait_ref = self.resolve_vars_if_possible(&*found_trait_ref); - let expected_trait_ref = self.resolve_vars_if_possible(&*expected_trait_ref); - - if expected_trait_ref.self_ty().references_error() { - return; - } - - let found_trait_ty = found_trait_ref.self_ty(); - - let found_did = match found_trait_ty.kind { - ty::Closure(did, _) | ty::Foreign(did) | ty::FnDef(did, _) => Some(did), - ty::Adt(def, _) => Some(def.did), - _ => None, - }; - - let found_span = found_did - .and_then(|did| self.tcx.hir().span_if_local(did)) - .map(|sp| self.tcx.sess.source_map().def_span(sp)); // the sp could be an fn def - - if self.reported_closure_mismatch.borrow().contains(&(span, found_span)) { - // We check closures twice, with obligations flowing in different directions, - // but we want to complain about them only once. - return; - } - - self.reported_closure_mismatch.borrow_mut().insert((span, found_span)); - - let found = match found_trait_ref.skip_binder().substs.type_at(1).kind { - ty::Tuple(ref tys) => vec![ArgKind::empty(); tys.len()], - _ => vec![ArgKind::empty()], - }; - - let expected_ty = expected_trait_ref.skip_binder().substs.type_at(1); - let expected = match expected_ty.kind { - ty::Tuple(ref tys) => tys - .iter() - .map(|t| ArgKind::from_expected_ty(t.expect_ty(), Some(span))) - .collect(), - _ => vec![ArgKind::Arg("_".to_owned(), expected_ty.to_string())], - }; - - if found.len() == expected.len() { - self.report_closure_arg_mismatch( - span, - found_span, - found_trait_ref, - expected_trait_ref, - ) - } else { - let (closure_span, found) = found_did - .and_then(|did| self.tcx.hir().get_if_local(did)) - .map(|node| { - let (found_span, found) = self.get_fn_like_arguments(node); - (Some(found_span), found) - }) - .unwrap_or((found_span, found)); - - self.report_arg_count_mismatch( - span, - closure_span, - expected, - found, - found_trait_ty.is_closure(), - ) - } - } - - TraitNotObjectSafe(did) => { - let violations = object_safety_violations(self.tcx, did); - report_object_safety_error(self.tcx, span, did, violations) - } - - // already reported in the query - ConstEvalFailure(err) => { - if let ErrorHandled::TooGeneric = err { - // Silence this error, as it can be produced during intermediate steps - // when a constant is not yet able to be evaluated (but will be later). - return; - } - self.tcx.sess.delay_span_bug( - span, - &format!("constant in type had an ignored error: {:?}", err), - ); - return; - } - - Overflow => { - bug!("overflow should be handled before the `report_selection_error` path"); - } - }; - - self.note_obligation_cause(&mut err, obligation); - self.point_at_returns_when_relevant(&mut err, &obligation); - - err.emit(); - } - - /// If the `Self` type of the unsatisfied trait `trait_ref` implements a trait - /// with the same path as `trait_ref`, a help message about - /// a probable version mismatch is added to `err` - fn note_version_mismatch( - &self, - err: &mut DiagnosticBuilder<'_>, - trait_ref: &ty::PolyTraitRef<'tcx>, - ) { - let get_trait_impl = |trait_def_id| { - let mut trait_impl = None; - self.tcx.for_each_relevant_impl(trait_def_id, trait_ref.self_ty(), |impl_def_id| { - if trait_impl.is_none() { - trait_impl = Some(impl_def_id); - } - }); - trait_impl - }; - let required_trait_path = self.tcx.def_path_str(trait_ref.def_id()); - let all_traits = self.tcx.all_traits(LOCAL_CRATE); - let traits_with_same_path: std::collections::BTreeSet<_> = all_traits - .iter() - .filter(|trait_def_id| **trait_def_id != trait_ref.def_id()) - .filter(|trait_def_id| self.tcx.def_path_str(**trait_def_id) == required_trait_path) - .collect(); - for trait_with_same_path in traits_with_same_path { - if let Some(impl_def_id) = get_trait_impl(*trait_with_same_path) { - let impl_span = self.tcx.def_span(impl_def_id); - err.span_help(impl_span, "trait impl with same name found"); - let trait_crate = self.tcx.crate_name(trait_with_same_path.krate); - let crate_msg = format!( - "perhaps two different versions of crate `{}` are being used?", - trait_crate - ); - err.note(&crate_msg); - } - } - } - fn suggest_restricting_param_bound( + crate fn suggest_restricting_param_bound( &self, mut err: &mut DiagnosticBuilder<'_>, trait_ref: &ty::PolyTraitRef<'_>, @@ -1318,7 +168,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// When encountering an assignment of an unsized trait, like `let x = ""[..];`, provide a /// suggestion to borrow the initializer in order to use have a slice instead. - fn suggest_borrow_on_unsized_slice( + crate fn suggest_borrow_on_unsized_slice( &self, code: &ObligationCauseCode<'tcx>, err: &mut DiagnosticBuilder<'tcx>, @@ -1342,22 +192,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } - fn mk_obligation_for_def_id( - &self, - def_id: DefId, - output_ty: Ty<'tcx>, - cause: ObligationCause<'tcx>, - param_env: ty::ParamEnv<'tcx>, - ) -> PredicateObligation<'tcx> { - let new_trait_ref = - ty::TraitRef { def_id, substs: self.tcx.mk_substs_trait(output_ty, &[]) }; - Obligation::new(cause, param_env, new_trait_ref.to_predicate()) - } - /// Given a closure's `DefId`, return the given name of the closure. /// /// This doesn't account for reassignments, but it's only used for suggestions. - fn get_closure_name( + crate fn get_closure_name( &self, def_id: DefId, err: &mut DiagnosticBuilder<'_>, @@ -1395,7 +233,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// We tried to apply the bound to an `fn` or closure. Check whether calling it would /// evaluate to a type that *would* satisfy the trait binding. If it would, suggest calling /// it: `bar(foo)` → `bar(foo())`. This case is *very* likely to be hit if `foo` is `async`. - fn suggest_fn_call( + crate fn suggest_fn_call( &self, obligation: &PredicateObligation<'tcx>, err: &mut DiagnosticBuilder<'_>, @@ -1479,7 +317,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } - fn suggest_add_reference_to_arg( + crate fn suggest_add_reference_to_arg( &self, obligation: &PredicateObligation<'tcx>, err: &mut DiagnosticBuilder<'tcx>, @@ -1548,7 +386,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// Whenever references are used by mistake, like `for (i, e) in &vec.iter().enumerate()`, /// suggest removing these references until we reach a type that implements the trait. - fn suggest_remove_reference( + crate fn suggest_remove_reference( &self, obligation: &PredicateObligation<'tcx>, err: &mut DiagnosticBuilder<'tcx>, @@ -1608,7 +446,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// Check if the trait bound is implemented for a different mutability and note it in the /// final error. - fn suggest_change_mut( + crate fn suggest_change_mut( &self, obligation: &PredicateObligation<'tcx>, err: &mut DiagnosticBuilder<'tcx>, @@ -1672,7 +510,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } - fn suggest_semicolon_removal( + crate fn suggest_semicolon_removal( &self, obligation: &PredicateObligation<'tcx>, err: &mut DiagnosticBuilder<'tcx>, @@ -1705,7 +543,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } - fn suggest_impl_trait( + crate fn suggest_impl_trait( &self, err: &mut DiagnosticBuilder<'tcx>, span: Span, @@ -1865,7 +703,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { false } - fn point_at_returns_when_relevant( + crate fn point_at_returns_when_relevant( &self, err: &mut DiagnosticBuilder<'tcx>, obligation: &PredicateObligation<'tcx>, @@ -2110,14 +948,17 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { err } - fn report_closure_arg_mismatch( + crate fn report_closure_arg_mismatch( &self, span: Span, found_span: Option, expected_ref: ty::PolyTraitRef<'tcx>, found: ty::PolyTraitRef<'tcx>, ) -> DiagnosticBuilder<'tcx> { - fn build_fn_sig_string<'tcx>(tcx: TyCtxt<'tcx>, trait_ref: &ty::TraitRef<'tcx>) -> String { + crate fn build_fn_sig_string<'tcx>( + tcx: TyCtxt<'tcx>, + trait_ref: &ty::TraitRef<'tcx>, + ) -> String { let inputs = trait_ref.substs.type_at(1); let sig = if let ty::Tuple(inputs) = inputs.kind { tcx.mk_fn_sig( @@ -2165,238 +1006,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } -pub fn recursive_type_with_infinite_size_error( - tcx: TyCtxt<'tcx>, - type_def_id: DefId, -) -> DiagnosticBuilder<'tcx> { - assert!(type_def_id.is_local()); - let span = tcx.hir().span_if_local(type_def_id).unwrap(); - let span = tcx.sess.source_map().def_span(span); - let mut err = struct_span_err!( - tcx.sess, - span, - E0072, - "recursive type `{}` has infinite size", - tcx.def_path_str(type_def_id) - ); - err.span_label(span, "recursive type has infinite size"); - err.help(&format!( - "insert indirection (e.g., a `Box`, `Rc`, or `&`) \ - at some point to make `{}` representable", - tcx.def_path_str(type_def_id) - )); - err -} - -pub fn report_object_safety_error( - tcx: TyCtxt<'tcx>, - span: Span, - trait_def_id: DefId, - violations: Vec, -) -> DiagnosticBuilder<'tcx> { - let trait_str = tcx.def_path_str(trait_def_id); - let span = tcx.sess.source_map().def_span(span); - let mut err = struct_span_err!( - tcx.sess, - span, - E0038, - "the trait `{}` cannot be made into an object", - trait_str - ); - err.span_label(span, format!("the trait `{}` cannot be made into an object", trait_str)); - - let mut reported_violations = FxHashSet::default(); - for violation in violations { - if reported_violations.insert(violation.clone()) { - match violation.span() { - Some(span) => err.span_label(span, violation.error_msg()), - None => err.note(&violation.error_msg()), - }; - } - } - - if tcx.sess.trait_methods_not_found.borrow().contains(&span) { - // Avoid emitting error caused by non-existing method (#58734) - err.cancel(); - } - - err -} - impl<'a, 'tcx> InferCtxt<'a, 'tcx> { - fn maybe_report_ambiguity( - &self, - obligation: &PredicateObligation<'tcx>, - body_id: Option, - ) { - // Unable to successfully determine, probably means - // insufficient type information, but could mean - // ambiguous impls. The latter *ought* to be a - // coherence violation, so we don't report it here. - - let predicate = self.resolve_vars_if_possible(&obligation.predicate); - let span = obligation.cause.span; - - debug!( - "maybe_report_ambiguity(predicate={:?}, obligation={:?} body_id={:?}, code={:?})", - predicate, obligation, body_id, obligation.cause.code, - ); - - // Ambiguity errors are often caused as fallout from earlier - // errors. So just ignore them if this infcx is tainted. - if self.is_tainted_by_errors() { - return; - } - - let mut err = match predicate { - ty::Predicate::Trait(ref data) => { - let trait_ref = data.to_poly_trait_ref(); - let self_ty = trait_ref.self_ty(); - debug!("self_ty {:?} {:?} trait_ref {:?}", self_ty, self_ty.kind, trait_ref); - - if predicate.references_error() { - return; - } - // Typically, this ambiguity should only happen if - // there are unresolved type inference variables - // (otherwise it would suggest a coherence - // failure). But given #21974 that is not necessarily - // the case -- we can have multiple where clauses that - // are only distinguished by a region, which results - // in an ambiguity even when all types are fully - // known, since we don't dispatch based on region - // relationships. - - // This is kind of a hack: it frequently happens that some earlier - // error prevents types from being fully inferred, and then we get - // a bunch of uninteresting errors saying something like " doesn't implement Sized". It may even be true that we - // could just skip over all checks where the self-ty is an - // inference variable, but I was afraid that there might be an - // inference variable created, registered as an obligation, and - // then never forced by writeback, and hence by skipping here we'd - // be ignoring the fact that we don't KNOW the type works - // out. Though even that would probably be harmless, given that - // we're only talking about builtin traits, which are known to be - // inhabited. We used to check for `self.tcx.sess.has_errors()` to - // avoid inundating the user with unnecessary errors, but we now - // check upstream for type errors and dont add the obligations to - // begin with in those cases. - if self - .tcx - .lang_items() - .sized_trait() - .map_or(false, |sized_id| sized_id == trait_ref.def_id()) - { - self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0282).emit(); - return; - } - let mut err = self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0283); - err.note(&format!("cannot resolve `{}`", predicate)); - if let ObligationCauseCode::ItemObligation(def_id) = obligation.cause.code { - self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id()); - } else if let ( - Ok(ref snippet), - ObligationCauseCode::BindingObligation(ref def_id, _), - ) = - (self.tcx.sess.source_map().span_to_snippet(span), &obligation.cause.code) - { - let generics = self.tcx.generics_of(*def_id); - if !generics.params.is_empty() && !snippet.ends_with('>') { - // FIXME: To avoid spurious suggestions in functions where type arguments - // where already supplied, we check the snippet to make sure it doesn't - // end with a turbofish. Ideally we would have access to a `PathSegment` - // instead. Otherwise we would produce the following output: - // - // error[E0283]: type annotations needed - // --> $DIR/issue-54954.rs:3:24 - // | - // LL | const ARR_LEN: usize = Tt::const_val::<[i8; 123]>(); - // | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - // | | - // | cannot infer type - // | help: consider specifying the type argument - // | in the function call: - // | `Tt::const_val::<[i8; 123]>::` - // ... - // LL | const fn const_val() -> usize { - // | --------- - required by this bound in `Tt::const_val` - // | - // = note: cannot resolve `_: Tt` - - err.span_suggestion( - span, - &format!( - "consider specifying the type argument{} in the function call", - if generics.params.len() > 1 { "s" } else { "" }, - ), - format!( - "{}::<{}>", - snippet, - generics - .params - .iter() - .map(|p| p.name.to_string()) - .collect::>() - .join(", ") - ), - Applicability::HasPlaceholders, - ); - } - } - err - } - - ty::Predicate::WellFormed(ty) => { - // Same hacky approach as above to avoid deluging user - // with error messages. - if ty.references_error() || self.tcx.sess.has_errors() { - return; - } - self.need_type_info_err(body_id, span, ty, ErrorCode::E0282) - } - - ty::Predicate::Subtype(ref data) => { - if data.references_error() || self.tcx.sess.has_errors() { - // no need to overload user in such cases - return; - } - let &SubtypePredicate { a_is_expected: _, a, b } = data.skip_binder(); - // both must be type variables, or the other would've been instantiated - assert!(a.is_ty_var() && b.is_ty_var()); - self.need_type_info_err(body_id, span, a, ErrorCode::E0282) - } - ty::Predicate::Projection(ref data) => { - let trait_ref = data.to_poly_trait_ref(self.tcx); - let self_ty = trait_ref.self_ty(); - if predicate.references_error() { - return; - } - let mut err = self.need_type_info_err(body_id, span, self_ty, ErrorCode::E0284); - err.note(&format!("cannot resolve `{}`", predicate)); - err - } - - _ => { - if self.tcx.sess.has_errors() { - return; - } - let mut err = struct_span_err!( - self.tcx.sess, - span, - E0284, - "type annotations needed: cannot resolve `{}`", - predicate, - ); - err.span_label(span, &format!("cannot resolve `{}`", predicate)); - err - } - }; - self.note_obligation_cause(&mut err, obligation); - err.emit(); - } - - fn suggest_fully_qualified_path( + crate fn suggest_fully_qualified_path( &self, err: &mut DiagnosticBuilder<'_>, def_id: DefId, @@ -2420,76 +1031,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } - /// Returns `true` if the trait predicate may apply for *some* assignment - /// to the type parameters. - fn predicate_can_apply( - &self, - param_env: ty::ParamEnv<'tcx>, - pred: ty::PolyTraitRef<'tcx>, - ) -> bool { - struct ParamToVarFolder<'a, 'tcx> { - infcx: &'a InferCtxt<'a, 'tcx>, - var_map: FxHashMap, Ty<'tcx>>, - } - - impl<'a, 'tcx> TypeFolder<'tcx> for ParamToVarFolder<'a, 'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { - self.infcx.tcx - } - - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - if let ty::Param(ty::ParamTy { name, .. }) = ty.kind { - let infcx = self.infcx; - self.var_map.entry(ty).or_insert_with(|| { - infcx.next_ty_var(TypeVariableOrigin { - kind: TypeVariableOriginKind::TypeParameterDefinition(name, None), - span: DUMMY_SP, - }) - }) - } else { - ty.super_fold_with(self) - } - } - } - - self.probe(|_| { - let mut selcx = SelectionContext::new(self); - - let cleaned_pred = - pred.fold_with(&mut ParamToVarFolder { infcx: self, var_map: Default::default() }); - - let cleaned_pred = super::project::normalize( - &mut selcx, - param_env, - ObligationCause::dummy(), - &cleaned_pred, - ) - .value; - - let obligation = - Obligation::new(ObligationCause::dummy(), param_env, cleaned_pred.to_predicate()); - - self.predicate_may_hold(&obligation) - }) - } - - fn note_obligation_cause( - &self, - err: &mut DiagnosticBuilder<'_>, - obligation: &PredicateObligation<'tcx>, - ) { - // First, attempt to add note to this error with an async-await-specific - // message, and fall back to regular note otherwise. - if !self.maybe_note_obligation_cause_for_async_await(err, obligation) { - self.note_obligation_cause_code( - err, - &obligation.predicate, - &obligation.cause.code, - &mut vec![], - ); - } - } - /// Adds an async-await specific note to the diagnostic when the future does not implement /// an auto trait because of a captured type. /// @@ -2532,7 +1073,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// ``` /// /// Returns `true` if an async-await specific note was added to the diagnostic. - fn maybe_note_obligation_cause_for_async_await( + crate fn maybe_note_obligation_cause_for_async_await( &self, err: &mut DiagnosticBuilder<'_>, obligation: &PredicateObligation<'tcx>, @@ -2712,7 +1253,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// Unconditionally adds the diagnostic note described in /// `maybe_note_obligation_cause_for_async_await`'s documentation comment. - fn note_obligation_cause_for_async_await( + crate fn note_obligation_cause_for_async_await( &self, err: &mut DiagnosticBuilder<'_>, target_span: Span, @@ -2838,7 +1379,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { ); } - fn note_obligation_cause_code( + crate fn note_obligation_cause_code( &self, err: &mut DiagnosticBuilder<'_>, predicate: &T, @@ -3053,7 +1594,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } - fn suggest_new_overflow_limit(&self, err: &mut DiagnosticBuilder<'_>) { + crate fn suggest_new_overflow_limit(&self, err: &mut DiagnosticBuilder<'_>) { let current_limit = self.tcx.sess.recursion_limit.get(); let suggested_limit = current_limit * 2; err.help(&format!( @@ -3061,52 +1602,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { suggested_limit )); } - - fn is_recursive_obligation( - &self, - obligated_types: &mut Vec<&ty::TyS<'tcx>>, - cause_code: &ObligationCauseCode<'tcx>, - ) -> bool { - if let ObligationCauseCode::BuiltinDerivedObligation(ref data) = cause_code { - let parent_trait_ref = self.resolve_vars_if_possible(&data.parent_trait_ref); - - if obligated_types.iter().any(|ot| ot == &parent_trait_ref.skip_binder().self_ty()) { - return true; - } - } - false - } -} - -/// Summarizes information -#[derive(Clone)] -pub enum ArgKind { - /// An argument of non-tuple type. Parameters are (name, ty) - Arg(String, String), - - /// An argument of tuple type. For a "found" argument, the span is - /// the locationo in the source of the pattern. For a "expected" - /// argument, it will be None. The vector is a list of (name, ty) - /// strings for the components of the tuple. - Tuple(Option, Vec<(String, String)>), -} - -impl ArgKind { - fn empty() -> ArgKind { - ArgKind::Arg("_".to_owned(), "_".to_owned()) - } - - /// Creates an `ArgKind` from the expected type of an - /// argument. It has no name (`_`) and an optional source span. - pub fn from_expected_ty(t: Ty<'_>, span: Option) -> ArgKind { - match t.kind { - ty::Tuple(ref tys) => ArgKind::Tuple( - span, - tys.iter().map(|ty| ("_".to_owned(), ty.to_string())).collect::>(), - ), - _ => ArgKind::Arg("_".to_owned(), t.to_string()), - } - } } /// Suggest restricting a type param with a new bound. From 4a75ef91f37dd0bd5267a852fa05ee0a5547a62b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 14 Jan 2020 10:29:13 -0800 Subject: [PATCH 114/169] fix error code index comment --- src/librustc_error_codes/error_codes/E0746.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_error_codes/error_codes/E0746.md b/src/librustc_error_codes/error_codes/E0746.md index 538c9d720d71b..acf369d8e144f 100644 --- a/src/librustc_error_codes/error_codes/E0746.md +++ b/src/librustc_error_codes/error_codes/E0746.md @@ -12,7 +12,7 @@ impl T for S { } // Having the trait `T` as return type is invalid because bare traits do not -have a statically known size: +// have a statically known size: fn foo() -> dyn T { S(42) } From 5b36c187dcbb8a4b6555fe046194f2b6deb74230 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 14 Jan 2020 13:18:06 -0800 Subject: [PATCH 115/169] review comments --- src/librustc/traits/error_reporting/mod.rs | 2 + .../traits/error_reporting/suggestions.rs | 243 +++++++++--------- src/librustc/traits/mod.rs | 14 +- src/librustc/ty/error.rs | 4 +- src/librustc_typeck/check/coercion.rs | 31 +-- src/librustc_typeck/check/mod.rs | 12 - .../coerce-expect-unsized-ascribed.stderr | 14 +- .../into-iter-no-impls-length-33.stderr | 14 +- src/test/ui/destructure-trait-ref.rs | 2 - src/test/ui/destructure-trait-ref.stderr | 10 +- src/test/ui/dst/dst-bad-assign-3.rs | 2 +- src/test/ui/dst/dst-bad-assign-3.stderr | 2 +- src/test/ui/dst/dst-bad-assign.rs | 2 +- src/test/ui/dst/dst-bad-assign.stderr | 2 +- src/test/ui/error-codes/E0746.stderr | 8 +- ...n-trait-return-should-be-impl-trait.stderr | 38 +-- src/test/ui/impl-trait/equality.stderr | 2 +- src/test/ui/issues/issue-58344.stderr | 4 +- .../lifetime-elision-return-type-trait.stderr | 2 +- .../feature-gate-never_type_fallback.stderr | 2 +- ...type-err-cause-on-impl-trait-return.stderr | 12 +- ...e-57673-ice-on-deref-of-boxed-trait.stderr | 2 +- 22 files changed, 206 insertions(+), 218 deletions(-) diff --git a/src/librustc/traits/error_reporting/mod.rs b/src/librustc/traits/error_reporting/mod.rs index f8329124851b0..17d7b75a7f7d6 100644 --- a/src/librustc/traits/error_reporting/mod.rs +++ b/src/librustc/traits/error_reporting/mod.rs @@ -1412,6 +1412,8 @@ pub fn suggest_constraining_type_param( false } +/// Collect all the returned expressions within the input expression. +/// Used to point at the return spans when we want to suggest some change to them. struct ReturnsVisitor<'v>(Vec<&'v hir::Expr<'v>>); impl<'v> Visitor<'v> for ReturnsVisitor<'v> { diff --git a/src/librustc/traits/error_reporting/suggestions.rs b/src/librustc/traits/error_reporting/suggestions.rs index 389edfa071794..0a9747b631e87 100644 --- a/src/librustc/traits/error_reporting/suggestions.rs +++ b/src/librustc/traits/error_reporting/suggestions.rs @@ -4,6 +4,7 @@ use super::{ }; use crate::infer::InferCtxt; +use crate::traits::object_safety::object_safety_violations; use crate::ty::TypeckTables; use crate::ty::{self, AdtKind, DefIdTree, ToPredicate, Ty, TyCtxt, TypeFoldable}; @@ -543,6 +544,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } + /// If all conditions are met to identify a returned `dyn Trait`, suggest using `impl Trait` if + /// applicable and signal that the error has been expanded appropriately and needs to be + /// emitted. crate fn suggest_impl_trait( &self, err: &mut DiagnosticBuilder<'tcx>, @@ -550,9 +554,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { obligation: &PredicateObligation<'tcx>, trait_ref: &ty::Binder>, ) -> bool { - if let ObligationCauseCode::SizedReturnType = obligation.cause.code.peel_derives() { - } else { - return false; + match obligation.cause.code.peel_derives() { + // Only suggest `impl Trait` if the return type is unsized because it is `dyn Trait`. + ObligationCauseCode::SizedReturnType => {} + _ => return false, } let hir = self.tcx.hir(); @@ -565,12 +570,25 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let body = hir.body(*body_id); let trait_ref = self.resolve_vars_if_possible(trait_ref); let ty = trait_ref.skip_binder().self_ty(); - if let ty::Dynamic(..) = ty.kind { - } else { + let is_object_safe; + match ty.kind { + ty::Dynamic(predicates, _) => { + // The `dyn Trait` is not object safe, do not suggest `Box`. + is_object_safe = predicates.principal_def_id().map_or(true, |def_id| { + !object_safety_violations(self.tcx, def_id).is_empty() + }) + } // We only want to suggest `impl Trait` to `dyn Trait`s. // For example, `fn foo() -> str` needs to be filtered out. - return false; + _ => return false, } + + let ret_ty = if let hir::FunctionRetTy::Return(ret_ty) = sig.decl.output { + ret_ty + } else { + return false; + }; + // Use `TypeVisitor` instead of the output type directly to find the span of `ty` for // cases like `fn foo() -> (dyn Trait, i32) {}`. // Recursively look for `TraitObject` types and if there's only one, use that span to @@ -583,122 +601,120 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let tables = self.in_progress_tables.map(|t| t.borrow()).unwrap(); - if let hir::FunctionRetTy::Return(ret_ty) = sig.decl.output { - let mut all_returns_conform_to_trait = true; - let mut all_returns_have_same_type = true; - let mut last_ty = None; - if let Some(ty_ret_ty) = tables.node_type_opt(ret_ty.hir_id) { - let cause = ObligationCause::misc(ret_ty.span, ret_ty.hir_id); - if let ty::Dynamic(predicates, _) = &ty_ret_ty.kind { - for predicate in predicates.iter() { - for expr in &visitor.0 { - if let Some(returned_ty) = tables.node_type_opt(expr.hir_id) { - if let Some(ty) = last_ty { - all_returns_have_same_type &= ty == returned_ty; - } - last_ty = Some(returned_ty); - - let param_env = ty::ParamEnv::empty(); - let pred = predicate.with_self_ty(self.tcx, returned_ty); - let obligation = - Obligation::new(cause.clone(), param_env, pred); - all_returns_conform_to_trait &= - self.predicate_may_hold(&obligation); - } - } - } - } - } else { - // We still want to verify whether all the return types conform to each other. + let mut all_returns_conform_to_trait = true; + let mut all_returns_have_same_type = true; + let mut last_ty = None; + if let Some(ty_ret_ty) = tables.node_type_opt(ret_ty.hir_id) { + let cause = ObligationCause::misc(ret_ty.span, ret_ty.hir_id); + let param_env = ty::ParamEnv::empty(); + if let ty::Dynamic(predicates, _) = &ty_ret_ty.kind { for expr in &visitor.0 { if let Some(returned_ty) = tables.node_type_opt(expr.hir_id) { - if let Some(ty) = last_ty { - all_returns_have_same_type &= ty == returned_ty; - } + all_returns_have_same_type &= + Some(returned_ty) == last_ty || last_ty.is_none(); last_ty = Some(returned_ty); + for predicate in predicates.iter() { + let pred = predicate.with_self_ty(self.tcx, returned_ty); + let obl = Obligation::new(cause.clone(), param_env, pred); + all_returns_conform_to_trait &= self.predicate_may_hold(&obl); + } + } + } + } + } else { + // We still want to verify whether all the return types conform to each other. + for expr in &visitor.0 { + if let Some(returned_ty) = tables.node_type_opt(expr.hir_id) { + if let Some(ty) = last_ty { + all_returns_have_same_type &= ty == returned_ty; } + last_ty = Some(returned_ty); } } + } + let (snippet, last_ty) = if let (true, hir::TyKind::TraitObject(..), Ok(snippet), true, Some(last_ty)) = ( + // Verify that we're dealing with a return `dyn Trait` ret_ty.span.overlaps(span), &ret_ty.kind, self.tcx.sess.source_map().span_to_snippet(ret_ty.span), + // If any of the return types does not conform to the trait, then we can't + // suggest `impl Trait` nor trait objects, it is a type mismatch error. all_returns_conform_to_trait, last_ty, ) { - err.code = Some(error_code!(E0746)); - err.set_primary_message( - "return type cannot have a bare trait because it must be `Sized`", + (snippet, last_ty) + } else { + return false; + }; + err.code(error_code!(E0746)); + err.set_primary_message("return type cannot have an unboxed trait object"); + err.children.clear(); + let impl_trait_msg = "for information on `impl Trait`, see \ + "; + let trait_obj_msg = "for information on trait objects, see \ + "; + let has_dyn = snippet.split_whitespace().next().map_or(false, |s| s == "dyn"); + let trait_obj = if has_dyn { &snippet[4..] } else { &snippet[..] }; + if all_returns_have_same_type { + // Suggest `-> impl Trait`. + err.span_suggestion( + ret_ty.span, + &format!( + "return `impl {1}` instead, as all return paths are of type `{}`, \ + which implements `{1}`", + last_ty, trait_obj, + ), + format!("impl {}", trait_obj), + Applicability::MachineApplicable, + ); + err.note(impl_trait_msg); + } else { + if is_object_safe { + // Suggest `-> Box` and `Box::new(returned_value)`. + // Get all the return values and collect their span and suggestion. + let mut suggestions = visitor + .0 + .iter() + .map(|expr| { + ( + expr.span, + format!( + "Box::new({})", + self.tcx.sess.source_map().span_to_snippet(expr.span).unwrap() + ), + ) + }) + .collect::>(); + // Add the suggestion for the return type. + suggestions.push(( + ret_ty.span, + format!("Box<{}{}>", if has_dyn { "" } else { "dyn " }, snippet), + )); + err.multipart_suggestion( + "return a trait object instead", + suggestions, + Applicability::MaybeIncorrect, ); - err.children.clear(); - let impl_trait_msg = "for information on `impl Trait`, see \ - "; - let trait_obj_msg = "for information on trait objects, see \ - "; - let has_dyn = snippet.split_whitespace().next().map_or(false, |s| s == "dyn"); - let trait_obj = if has_dyn { &snippet[4..] } else { &snippet[..] }; - if all_returns_have_same_type { - err.span_suggestion( - ret_ty.span, - &format!( - "you can use the `impl Trait` feature \ - in the return type because all the return paths are of type \ - `{}`, which implements `dyn {}`", - last_ty, trait_obj, - ), - format!("impl {}", trait_obj), - Applicability::MachineApplicable, - ); - err.note(impl_trait_msg); - } else { - let mut suggestions = visitor - .0 - .iter() - .map(|expr| { - ( - expr.span, - format!( - "Box::new({})", - self.tcx - .sess - .source_map() - .span_to_snippet(expr.span) - .unwrap() - ), - ) - }) - .collect::>(); - suggestions.push(( - ret_ty.span, - format!("Box<{}{}>", if has_dyn { "" } else { "dyn " }, snippet), - )); - err.multipart_suggestion( - "if the performance implications are acceptable, you can return a \ - trait object", - suggestions, - Applicability::MaybeIncorrect, - ); - err.span_help( - visitor.0.iter().map(|expr| expr.span).collect::>(), - &format!( - "if all the returned values were of the same type you could use \ - `impl {}` as the return type", - trait_obj, - ), - ); - err.help( - "alternatively, you can always create a new `enum` with a variant \ - for each returned type", - ); - err.note(impl_trait_msg); - err.note(trait_obj_msg); - } - return true; + } else { + err.note(&format!( + "if trait `{}` was object safe, you could return a trait object", + trait_obj, + )); } + err.note(&format!( + "if all the returned values were of the same type you could use \ + `impl {}` as the return type", + trait_obj, + )); + err.note(impl_trait_msg); + err.note(trait_obj_msg); + err.note("you can create a new `enum` with a variant for each returned type"); } + return true; } false } @@ -708,9 +724,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { err: &mut DiagnosticBuilder<'tcx>, obligation: &PredicateObligation<'tcx>, ) { - if let ObligationCauseCode::SizedReturnType = obligation.cause.code.peel_derives() { - } else { - return; + match obligation.cause.code.peel_derives() { + ObligationCauseCode::SizedReturnType => {} + _ => return, } let hir = self.tcx.hir(); @@ -726,10 +742,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let tables = self.in_progress_tables.map(|t| t.borrow()).unwrap(); for expr in &visitor.0 { if let Some(returned_ty) = tables.node_type_opt(expr.hir_id) { - err.span_label( - expr.span, - &format!("this returned value is of type `{}`", returned_ty), - ); + let ty = self.resolve_vars_if_possible(&returned_ty); + err.span_label(expr.span, &format!("this returned value is of type `{}`", ty)); } } } @@ -1685,9 +1699,8 @@ impl<'v> Visitor<'v> for ReturnsVisitor<'v> { } fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { - match ex.kind { - hir::ExprKind::Ret(Some(ex)) => self.0.push(ex), - _ => {} + if let hir::ExprKind::Ret(Some(ex)) = ex.kind { + self.0.push(ex); } hir::intravisit::walk_expr(self, ex); } diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index f68711c06205b..b4998d4486f09 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -155,8 +155,8 @@ pub struct ObligationCause<'tcx> { pub code: ObligationCauseCode<'tcx>, } -impl<'tcx> ObligationCause<'tcx> { - pub fn span(&self, tcx: TyCtxt<'tcx>) -> Span { +impl ObligationCause<'_> { + pub fn span(&self, tcx: TyCtxt<'_>) -> Span { match self.code { ObligationCauseCode::CompareImplMethodObligation { .. } | ObligationCauseCode::MainFunctionType @@ -1172,13 +1172,13 @@ impl<'tcx> ObligationCause<'tcx> { } impl<'tcx> ObligationCauseCode<'tcx> { + // Return the base obligation, ignoring derived obligations. pub fn peel_derives(&self) -> &Self { - match self { - BuiltinDerivedObligation(cause) | ImplDerivedObligation(cause) => { - cause.parent_code.peel_derives() - } - _ => self, + let mut base_cause = self; + while let BuiltinDerivedObligation(cause) | ImplDerivedObligation(cause) = base_cause { + base_cause = &cause.parent_code; } + base_cause } } diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index f7612874e05b6..217ca0ca3f6f5 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -244,9 +244,9 @@ impl<'tcx> ty::TyS<'tcx> { ty::FnPtr(_) => "fn pointer".into(), ty::Dynamic(ref inner, ..) => { if let Some(principal) = inner.principal() { - format!("trait `{}`", tcx.def_path_str(principal.def_id())).into() + format!("trait object `dyn {}`", tcx.def_path_str(principal.def_id())).into() } else { - "trait".into() + "trait object".into() } } ty::Closure(..) => "closure".into(), diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 77f16fb79141d..66499b1753fdd 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -50,6 +50,7 @@ //! sort of a minor point so I've opted to leave it for later -- after all, //! we may want to adjust precisely when coercions occur. +use crate::astconv::AstConv; use crate::check::{FnCtxt, Needs}; use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc::infer::{Coercion, InferOk, InferResult}; @@ -1245,7 +1246,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { expression.map(|expr| (expr, blk_id)), ); if !fcx.tcx.features().unsized_locals { - unsized_return = fcx.is_unsized_return(blk_id); + unsized_return = self.is_return_ty_unsized(fcx, blk_id); } } ObligationCauseCode::ReturnValue(id) => { @@ -1260,7 +1261,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { ); if !fcx.tcx.features().unsized_locals { let id = fcx.tcx.hir().get_parent_node(id); - unsized_return = fcx.is_unsized_return(id); + unsized_return = self.is_return_ty_unsized(fcx, id); } } _ => { @@ -1290,15 +1291,6 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { .filter(|e| fcx.is_assign_to_bool(e, self.expected_ty())) .is_some(); - if unsized_return { - fcx.tcx.sess.delay_span_bug( - cause.span, - &format!( - "elided E0308 in favor of more detailed E0277 or E0746: {:?}", - cause.code - ), - ); - } err.emit_unless(assign_to_bool || unsized_return); self.final_ty = Some(fcx.tcx.types.err); @@ -1365,10 +1357,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { "...is found to be `{}` here", fcx.resolve_vars_with_obligations(expected), )); - err.note( - "`impl Trait` as a return type requires that all the returned values must have \ - the same type", - ); + err.note("to return `impl Trait`, all returned values must be of the same type"); let snippet = fcx .tcx .sess @@ -1397,6 +1386,18 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { err } + fn is_return_ty_unsized(&self, fcx: &FnCtxt<'a, 'tcx>, blk_id: hir::HirId) -> bool { + if let Some((fn_decl, _)) = fcx.get_fn_decl(blk_id) { + if let hir::FunctionRetTy::Return(ty) = fn_decl.output { + let ty = AstConv::ast_ty_to_ty(fcx, ty); + if let ty::Dynamic(..) = ty.kind { + return true; + } + } + } + false + } + pub fn complete<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Ty<'tcx> { if let Some(final_ty) = self.final_ty { final_ty diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 8f531ea6199e1..baf9ae1ac2911 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4964,18 +4964,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - fn is_unsized_return(&self, blk_id: hir::HirId) -> bool { - if let Some((fn_decl, _)) = self.get_fn_decl(blk_id) { - if let hir::FunctionRetTy::Return(ty) = fn_decl.output { - let ty = AstConv::ast_ty_to_ty(self, ty); - if let ty::Dynamic(..) = ty.kind { - return true; - } - } - } - false - } - /// A possible error is to forget to add a return type that is needed: /// /// ``` diff --git a/src/test/ui/coercion/coerce-expect-unsized-ascribed.stderr b/src/test/ui/coercion/coerce-expect-unsized-ascribed.stderr index 303d83d342625..44e5c6a99f727 100644 --- a/src/test/ui/coercion/coerce-expect-unsized-ascribed.stderr +++ b/src/test/ui/coercion/coerce-expect-unsized-ascribed.stderr @@ -29,7 +29,7 @@ error[E0308]: mismatched types --> $DIR/coerce-expect-unsized-ascribed.rs:13:13 | LL | let _ = box { |x| (x as u8) }: Box _>; - | ^^^^^^^^^^^^^^^^^^^^^ expected trait `std::ops::Fn`, found closure + | ^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn std::ops::Fn`, found closure | = note: expected struct `std::boxed::Box u8>` found struct `std::boxed::Box<[closure@$DIR/coerce-expect-unsized-ascribed.rs:13:19: 13:32]>` @@ -38,7 +38,7 @@ error[E0308]: mismatched types --> $DIR/coerce-expect-unsized-ascribed.rs:14:13 | LL | let _ = box if true { false } else { true }: Box; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait `std::fmt::Debug`, found `bool` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn std::fmt::Debug`, found `bool` | = note: expected struct `std::boxed::Box` found struct `std::boxed::Box` @@ -47,7 +47,7 @@ error[E0308]: mismatched types --> $DIR/coerce-expect-unsized-ascribed.rs:15:13 | LL | let _ = box match true { true => 'a', false => 'b' }: Box; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait `std::fmt::Debug`, found `char` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn std::fmt::Debug`, found `char` | = note: expected struct `std::boxed::Box` found struct `std::boxed::Box` @@ -83,7 +83,7 @@ error[E0308]: mismatched types --> $DIR/coerce-expect-unsized-ascribed.rs:21:13 | LL | let _ = &{ |x| (x as u8) }: &dyn Fn(i32) -> _; - | ^^^^^^^^^^^^^^^^^^ expected trait `std::ops::Fn`, found closure + | ^^^^^^^^^^^^^^^^^^ expected trait object `dyn std::ops::Fn`, found closure | = note: expected reference `&dyn std::ops::Fn(i32) -> u8` found reference `&[closure@$DIR/coerce-expect-unsized-ascribed.rs:21:16: 21:29]` @@ -92,7 +92,7 @@ error[E0308]: mismatched types --> $DIR/coerce-expect-unsized-ascribed.rs:22:13 | LL | let _ = &if true { false } else { true }: &dyn Debug; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait `std::fmt::Debug`, found `bool` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn std::fmt::Debug`, found `bool` | = note: expected reference `&dyn std::fmt::Debug` found reference `&bool` @@ -101,7 +101,7 @@ error[E0308]: mismatched types --> $DIR/coerce-expect-unsized-ascribed.rs:23:13 | LL | let _ = &match true { true => 'a', false => 'b' }: &dyn Debug; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait `std::fmt::Debug`, found `char` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn std::fmt::Debug`, found `char` | = note: expected reference `&dyn std::fmt::Debug` found reference `&char` @@ -119,7 +119,7 @@ error[E0308]: mismatched types --> $DIR/coerce-expect-unsized-ascribed.rs:26:13 | LL | let _ = Box::new(|x| (x as u8)): Box _>; - | ^^^^^^^^^^^^^^^^^^^^^^^ expected trait `std::ops::Fn`, found closure + | ^^^^^^^^^^^^^^^^^^^^^^^ expected trait object `dyn std::ops::Fn`, found closure | = note: expected struct `std::boxed::Box _>` found struct `std::boxed::Box<[closure@$DIR/coerce-expect-unsized-ascribed.rs:26:22: 26:35]>` diff --git a/src/test/ui/const-generics/array-impls/into-iter-no-impls-length-33.stderr b/src/test/ui/const-generics/array-impls/into-iter-no-impls-length-33.stderr index e615e10bd5f5f..4869f48363447 100644 --- a/src/test/ui/const-generics/array-impls/into-iter-no-impls-length-33.stderr +++ b/src/test/ui/const-generics/array-impls/into-iter-no-impls-length-33.stderr @@ -13,7 +13,7 @@ LL | pub fn no_iterator() -> impl Iterator { | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]` LL | LL | IntoIter::new([0i32; 33]) - | ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>` + | ------------------------- this returned value is of type `std::array::IntoIter` | = note: required because of the requirements on the impl of `std::iter::Iterator` for `std::array::IntoIter` = note: the return type of a function must have a statically known size @@ -33,7 +33,7 @@ LL | pub fn no_double_ended_iterator() -> impl DoubleEndedIterator { | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]` LL | LL | IntoIter::new([0i32; 33]) - | ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>` + | ------------------------- this returned value is of type `std::array::IntoIter` | = note: required because of the requirements on the impl of `std::iter::DoubleEndedIterator` for `std::array::IntoIter` = note: the return type of a function must have a statically known size @@ -53,7 +53,7 @@ LL | pub fn no_exact_size_iterator() -> impl ExactSizeIterator { | ^^^^^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]` LL | LL | IntoIter::new([0i32; 33]) - | ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>` + | ------------------------- this returned value is of type `std::array::IntoIter` | = note: required because of the requirements on the impl of `std::iter::ExactSizeIterator` for `std::array::IntoIter` = note: the return type of a function must have a statically known size @@ -73,7 +73,7 @@ LL | pub fn no_fused_iterator() -> impl FusedIterator { | ^^^^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]` LL | LL | IntoIter::new([0i32; 33]) - | ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>` + | ------------------------- this returned value is of type `std::array::IntoIter` | = note: required because of the requirements on the impl of `std::iter::FusedIterator` for `std::array::IntoIter` = note: the return type of a function must have a statically known size @@ -93,7 +93,7 @@ LL | pub fn no_trusted_len() -> impl TrustedLen { | ^^^^^^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]` LL | LL | IntoIter::new([0i32; 33]) - | ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>` + | ------------------------- this returned value is of type `std::array::IntoIter` | = note: required because of the requirements on the impl of `std::iter::TrustedLen` for `std::array::IntoIter` = note: the return type of a function must have a statically known size @@ -113,7 +113,7 @@ LL | pub fn no_clone() -> impl Clone { | ^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]` LL | LL | IntoIter::new([0i32; 33]) - | ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>` + | ------------------------- this returned value is of type `std::array::IntoIter` | = note: required because of the requirements on the impl of `std::clone::Clone` for `std::array::IntoIter` = note: the return type of a function must have a statically known size @@ -133,7 +133,7 @@ LL | pub fn no_debug() -> impl Debug { | ^^^^^^^^^^ the trait `std::array::LengthAtMost32` is not implemented for `[i32; 33]` LL | LL | IntoIter::new([0i32; 33]) - | ------------------------- this returned value is of type `std::array::IntoIter<_, _: usize>` + | ------------------------- this returned value is of type `std::array::IntoIter` | = note: required because of the requirements on the impl of `std::fmt::Debug` for `std::array::IntoIter` = note: the return type of a function must have a statically known size diff --git a/src/test/ui/destructure-trait-ref.rs b/src/test/ui/destructure-trait-ref.rs index fb92196b2bd56..34e7cad935aeb 100644 --- a/src/test/ui/destructure-trait-ref.rs +++ b/src/test/ui/destructure-trait-ref.rs @@ -33,12 +33,10 @@ fn main() { //~^ ERROR mismatched types //~| expected trait object `dyn T` //~| found reference `&_` - //~| expected trait `T`, found reference let &&&x = &(&1isize as &dyn T); //~^ ERROR mismatched types //~| expected trait object `dyn T` //~| found reference `&_` - //~| expected trait `T`, found reference let box box x = box 1isize as Box; //~^ ERROR mismatched types //~| expected trait object `dyn T` diff --git a/src/test/ui/destructure-trait-ref.stderr b/src/test/ui/destructure-trait-ref.stderr index c78166f411d28..f99bf2ffdc9d4 100644 --- a/src/test/ui/destructure-trait-ref.stderr +++ b/src/test/ui/destructure-trait-ref.stderr @@ -22,31 +22,31 @@ error[E0308]: mismatched types LL | let &&x = &1isize as &dyn T; | ^^ | | - | expected trait `T`, found reference + | expected trait object `dyn T`, found reference | help: you can probably remove the explicit borrow: `x` | = note: expected trait object `dyn T` found reference `&_` error[E0308]: mismatched types - --> $DIR/destructure-trait-ref.rs:37:11 + --> $DIR/destructure-trait-ref.rs:36:11 | LL | let &&&x = &(&1isize as &dyn T); | ^^ | | - | expected trait `T`, found reference + | expected trait object `dyn T`, found reference | help: you can probably remove the explicit borrow: `x` | = note: expected trait object `dyn T` found reference `&_` error[E0308]: mismatched types - --> $DIR/destructure-trait-ref.rs:42:13 + --> $DIR/destructure-trait-ref.rs:40:13 | LL | let box box x = box 1isize as Box; | ^^^^^ ------------------------ this expression has type `std::boxed::Box` | | - | expected trait `T`, found struct `std::boxed::Box` + | expected trait object `dyn T`, found struct `std::boxed::Box` | = note: expected trait object `dyn T` found struct `std::boxed::Box<_>` diff --git a/src/test/ui/dst/dst-bad-assign-3.rs b/src/test/ui/dst/dst-bad-assign-3.rs index e3b621b909a0c..d05b3937c998c 100644 --- a/src/test/ui/dst/dst-bad-assign-3.rs +++ b/src/test/ui/dst/dst-bad-assign-3.rs @@ -32,7 +32,7 @@ pub fn main() { let z: Box = Box::new(Bar1 {f: 36}); f5.2 = Bar1 {f: 36}; //~^ ERROR mismatched types - //~| expected trait `ToBar`, found struct `Bar1` + //~| expected trait object `dyn ToBar`, found struct `Bar1` //~| expected trait object `dyn ToBar` //~| found struct `Bar1` //~| ERROR the size for values of type diff --git a/src/test/ui/dst/dst-bad-assign-3.stderr b/src/test/ui/dst/dst-bad-assign-3.stderr index dc03f38e10387..0b6f9df2d83ee 100644 --- a/src/test/ui/dst/dst-bad-assign-3.stderr +++ b/src/test/ui/dst/dst-bad-assign-3.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/dst-bad-assign-3.rs:33:12 | LL | f5.2 = Bar1 {f: 36}; - | ^^^^^^^^^^^^ expected trait `ToBar`, found struct `Bar1` + | ^^^^^^^^^^^^ expected trait object `dyn ToBar`, found struct `Bar1` | = note: expected trait object `dyn ToBar` found struct `Bar1` diff --git a/src/test/ui/dst/dst-bad-assign.rs b/src/test/ui/dst/dst-bad-assign.rs index ed94242f5bfd0..496e01ae00532 100644 --- a/src/test/ui/dst/dst-bad-assign.rs +++ b/src/test/ui/dst/dst-bad-assign.rs @@ -34,7 +34,7 @@ pub fn main() { let z: Box = Box::new(Bar1 {f: 36}); f5.ptr = Bar1 {f: 36}; //~^ ERROR mismatched types - //~| expected trait `ToBar`, found struct `Bar1` + //~| expected trait object `dyn ToBar`, found struct `Bar1` //~| expected trait object `dyn ToBar` //~| found struct `Bar1` //~| ERROR the size for values of type diff --git a/src/test/ui/dst/dst-bad-assign.stderr b/src/test/ui/dst/dst-bad-assign.stderr index 8031f162482e3..434c460759fb4 100644 --- a/src/test/ui/dst/dst-bad-assign.stderr +++ b/src/test/ui/dst/dst-bad-assign.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/dst-bad-assign.rs:35:14 | LL | f5.ptr = Bar1 {f: 36}; - | ^^^^^^^^^^^^ expected trait `ToBar`, found struct `Bar1` + | ^^^^^^^^^^^^ expected trait object `dyn ToBar`, found struct `Bar1` | = note: expected trait object `dyn ToBar` found struct `Bar1` diff --git a/src/test/ui/error-codes/E0746.stderr b/src/test/ui/error-codes/E0746.stderr index 1c88ce64749ae..e7a8fd304cabe 100644 --- a/src/test/ui/error-codes/E0746.stderr +++ b/src/test/ui/error-codes/E0746.stderr @@ -1,23 +1,23 @@ -error[E0746]: return type cannot have a bare trait because it must be `Sized` +error[E0746]: return type cannot have an unboxed trait object --> $DIR/E0746.rs:8:13 | LL | fn foo() -> dyn Trait { Struct } | ^^^^^^^^^ doesn't have a size known at compile-time | = note: for information on `impl Trait`, see -help: you can use the `impl Trait` feature in the return type because all the return paths are of type `Struct`, which implements `dyn Trait` +help: return `impl Trait` instead, as all return paths are of type `Struct`, which implements `Trait` | LL | fn foo() -> impl Trait { Struct } | ^^^^^^^^^^ -error[E0746]: return type cannot have a bare trait because it must be `Sized` +error[E0746]: return type cannot have an unboxed trait object --> $DIR/E0746.rs:11:13 | LL | fn bar() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time | = note: for information on `impl Trait`, see -help: you can use the `impl Trait` feature in the return type because all the return paths are of type `{integer}`, which implements `dyn Trait` +help: return `impl Trait` instead, as all return paths are of type `{integer}`, which implements `Trait` | LL | fn bar() -> impl Trait { | ^^^^^^^^^^ diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr index ff7438e9affc1..3d0707c091644 100644 --- a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr +++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/dyn-trait-return-should-be-impl-trait.rs:7:35 | LL | fn fuz() -> (usize, Trait) { (42, Struct) } - | ^^^^^^ expected trait `Trait`, found struct `Struct` + | ^^^^^^ expected trait object `dyn Trait`, found struct `Struct` | = note: expected trait object `(dyn Trait + 'static)` found struct `Struct` @@ -24,7 +24,7 @@ error[E0308]: mismatched types --> $DIR/dyn-trait-return-should-be-impl-trait.rs:10:39 | LL | fn bar() -> (usize, dyn Trait) { (42, Struct) } - | ^^^^^^ expected trait `Trait`, found struct `Struct` + | ^^^^^^ expected trait object `dyn Trait`, found struct `Struct` | = note: expected trait object `(dyn Trait + 'static)` found struct `Struct` @@ -42,26 +42,26 @@ LL | fn bar() -> (usize, dyn Trait) { (42, Struct) } = note: required because it appears within the type `(usize, (dyn Trait + 'static))` = note: the return type of a function must have a statically known size -error[E0746]: return type cannot have a bare trait because it must be `Sized` +error[E0746]: return type cannot have an unboxed trait object --> $DIR/dyn-trait-return-should-be-impl-trait.rs:13:13 | LL | fn bap() -> Trait { Struct } | ^^^^^ doesn't have a size known at compile-time | = note: for information on `impl Trait`, see -help: you can use the `impl Trait` feature in the return type because all the return paths are of type `Struct`, which implements `dyn Trait` +help: return `impl Trait` instead, as all return paths are of type `Struct`, which implements `Trait` | LL | fn bap() -> impl Trait { Struct } | ^^^^^^^^^^ -error[E0746]: return type cannot have a bare trait because it must be `Sized` +error[E0746]: return type cannot have an unboxed trait object --> $DIR/dyn-trait-return-should-be-impl-trait.rs:15:13 | LL | fn ban() -> dyn Trait { Struct } | ^^^^^^^^^ doesn't have a size known at compile-time | = note: for information on `impl Trait`, see -help: you can use the `impl Trait` feature in the return type because all the return paths are of type `Struct`, which implements `dyn Trait` +help: return `impl Trait` instead, as all return paths are of type `Struct`, which implements `Trait` | LL | fn ban() -> impl Trait { Struct } | ^^^^^^^^^^ @@ -76,40 +76,26 @@ LL | fn bak() -> dyn Trait { unimplemented!() } = note: to learn more, visit = note: the return type of a function must have a statically known size -error[E0746]: return type cannot have a bare trait because it must be `Sized` +error[E0746]: return type cannot have an unboxed trait object --> $DIR/dyn-trait-return-should-be-impl-trait.rs:19:13 | LL | fn bal() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time | -help: if all the returned values were of the same type you could use `impl Trait` as the return type - --> $DIR/dyn-trait-return-should-be-impl-trait.rs:23:5 - | -LL | return Struct; - | ^^^^^^ -LL | } -LL | 42 - | ^^ - = help: alternatively, you can always create a new `enum` with a variant for each returned type + = note: if trait `Trait` was object safe, you could return a trait object + = note: if all the returned values were of the same type you could use `impl Trait` as the return type = note: for information on `impl Trait`, see = note: for information on trait objects, see -help: if the performance implications are acceptable, you can return a trait object - | -LL | fn bal() -> Box { -LL | if true { -LL | return Box::new(Struct); -LL | } -LL | Box::new(42) - | + = note: you can create a new `enum` with a variant for each returned type -error[E0746]: return type cannot have a bare trait because it must be `Sized` +error[E0746]: return type cannot have an unboxed trait object --> $DIR/dyn-trait-return-should-be-impl-trait.rs:27:13 | LL | fn bat() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time | = note: for information on `impl Trait`, see -help: you can use the `impl Trait` feature in the return type because all the return paths are of type `{integer}`, which implements `dyn Trait` +help: return `impl Trait` instead, as all return paths are of type `{integer}`, which implements `Trait` | LL | fn bat() -> impl Trait { | ^^^^^^^^^^ diff --git a/src/test/ui/impl-trait/equality.stderr b/src/test/ui/impl-trait/equality.stderr index 215b6d52918ab..be8653d1689f8 100644 --- a/src/test/ui/impl-trait/equality.stderr +++ b/src/test/ui/impl-trait/equality.stderr @@ -10,7 +10,7 @@ LL | } LL | 0_u32 | ^^^^^ expected `i32`, found `u32` | - = note: `impl Trait` as a return type requires that all the returned values must have the same type + = note: to return `impl Trait`, all returned values must be of the same type = help: you can instead return a trait object using `Box` = note: for information on `impl Trait`, see = note: for information on trait objects, see diff --git a/src/test/ui/issues/issue-58344.stderr b/src/test/ui/issues/issue-58344.stderr index 9b07dbd7ab69c..e0c196e518ba3 100644 --- a/src/test/ui/issues/issue-58344.stderr +++ b/src/test/ui/issues/issue-58344.stderr @@ -5,7 +5,7 @@ LL | ) -> Either>::Output>, impl Trait<` is not implemented for `impl Trait<::Output>` ... LL | add_generic(value, 1u32) - | ------------------------ this returned value is of type `Either>::Output>, impl Trait<<_ as std::ops::Add<_>>::Output>>` + | ------------------------ this returned value is of type `Either::Output>, impl Trait<::Output>>` | = note: the return type of a function must have a statically known size @@ -16,7 +16,7 @@ LL | ) -> Either>::Output>, impl Trait<` is not implemented for `impl Trait<::Output>` ... LL | add_generic(value, 1u32) - | ------------------------ this returned value is of type `Either>::Output>, impl Trait<<_ as std::ops::Add<_>>::Output>>` + | ------------------------ this returned value is of type `Either::Output>, impl Trait<::Output>>` | = note: the return type of a function must have a statically known size diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr index 49fa11c35aef8..e43fb6d0edfb9 100644 --- a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr +++ b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr @@ -5,7 +5,7 @@ LL | fn foo() -> impl Future> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Future` is not implemented for `std::result::Result<(), _>` LL | LL | Ok(()) - | ------ this returned value is of type `std::result::Result<_, _>` + | ------ this returned value is of type `std::result::Result<(), _>` | = note: the return type of a function must have a statically known size diff --git a/src/test/ui/never_type/feature-gate-never_type_fallback.stderr b/src/test/ui/never_type/feature-gate-never_type_fallback.stderr index 88bfed2b54742..77288f1badac5 100644 --- a/src/test/ui/never_type/feature-gate-never_type_fallback.stderr +++ b/src/test/ui/never_type/feature-gate-never_type_fallback.stderr @@ -5,7 +5,7 @@ LL | fn should_ret_unit() -> impl T { | ^^^^^^ the trait `T` is not implemented for `()` LL | LL | panic!() - | -------- this returned value is of type `_` + | -------- this returned value is of type `()` | = note: the return type of a function must have a statically known size = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr index 9db5250e4d876..2c0425e718abc 100644 --- a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr +++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr @@ -10,7 +10,7 @@ LL | } LL | 1u32 | ^^^^ expected `i32`, found `u32` | - = note: `impl Trait` as a return type requires that all the returned values must have the same type + = note: to return `impl Trait`, all returned values must be of the same type = help: you can instead return a trait object using `Box` = note: for information on `impl Trait`, see = note: for information on trait objects, see @@ -27,7 +27,7 @@ LL | } else { LL | return 1u32; | ^^^^ expected `i32`, found `u32` | - = note: `impl Trait` as a return type requires that all the returned values must have the same type + = note: to return `impl Trait`, all returned values must be of the same type = help: you can instead return a trait object using `Box` = note: for information on `impl Trait`, see = note: for information on trait objects, see @@ -44,7 +44,7 @@ LL | } else { LL | 1u32 | ^^^^ expected `i32`, found `u32` | - = note: `impl Trait` as a return type requires that all the returned values must have the same type + = note: to return `impl Trait`, all returned values must be of the same type = help: you can instead return a trait object using `Box` = note: for information on `impl Trait`, see = note: for information on trait objects, see @@ -73,7 +73,7 @@ LL | 0 => return 0i32, LL | _ => 1u32, | ^^^^ expected `i32`, found `u32` | - = note: `impl Trait` as a return type requires that all the returned values must have the same type + = note: to return `impl Trait`, all returned values must be of the same type = help: you can instead return a trait object using `Box` = note: for information on `impl Trait`, see = note: for information on trait objects, see @@ -92,7 +92,7 @@ LL | | _ => 2u32, LL | | } | |_____^ expected `i32`, found `u32` | - = note: `impl Trait` as a return type requires that all the returned values must have the same type + = note: to return `impl Trait`, all returned values must be of the same type = help: you can instead return a trait object using `Box` = note: for information on `impl Trait`, see = note: for information on trait objects, see @@ -109,7 +109,7 @@ LL | return 0i32; LL | 1u32 | ^^^^ expected `i32`, found `u32` | - = note: `impl Trait` as a return type requires that all the returned values must have the same type + = note: to return `impl Trait`, all returned values must be of the same type = help: you can instead return a trait object using `Box` = note: for information on `impl Trait`, see = note: for information on trait objects, see diff --git a/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr b/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr index 14c09ade7dde3..a656b20c23ec3 100644 --- a/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr +++ b/src/test/ui/typeck/issue-57673-ice-on-deref-of-boxed-trait.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | fn ice(x: Box>) { | - possibly return type missing here? LL | *x - | ^^ expected `()`, found trait `std::iter::Iterator` + | ^^ expected `()`, found trait object `dyn std::iter::Iterator` | = note: expected unit type `()` found trait object `(dyn std::iter::Iterator + 'static)` From 509cb33dbcdb631625288f72c359a35dde6524b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 14 Jan 2020 14:49:30 -0800 Subject: [PATCH 116/169] review comments --- src/librustc/traits/error_reporting/suggestions.rs | 9 +++------ src/librustc_typeck/check/coercion.rs | 1 + src/test/ui/impl-trait/equality.stderr | 1 + .../point-to-type-err-cause-on-impl-trait-return.stderr | 6 ++++++ 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/librustc/traits/error_reporting/suggestions.rs b/src/librustc/traits/error_reporting/suggestions.rs index 0a9747b631e87..c2f562b4bc7b2 100644 --- a/src/librustc/traits/error_reporting/suggestions.rs +++ b/src/librustc/traits/error_reporting/suggestions.rs @@ -624,12 +624,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } else { // We still want to verify whether all the return types conform to each other. for expr in &visitor.0 { - if let Some(returned_ty) = tables.node_type_opt(expr.hir_id) { - if let Some(ty) = last_ty { - all_returns_have_same_type &= ty == returned_ty; - } - last_ty = Some(returned_ty); - } + let returned_ty = tables.node_type_opt(expr.hir_id); + all_returns_have_same_type &= last_ty == returned_ty || last_ty.is_none(); + last_ty = returned_ty; } } diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 66499b1753fdd..8aa2cb5034224 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -1372,6 +1372,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { &snippet[5..] )); } + err.help("alternatively, create a new `enum` with a variant for each returned type"); let impl_trait_msg = "for information on `impl Trait`, see \ "; diff --git a/src/test/ui/impl-trait/equality.stderr b/src/test/ui/impl-trait/equality.stderr index be8653d1689f8..ceb32dd4cd33e 100644 --- a/src/test/ui/impl-trait/equality.stderr +++ b/src/test/ui/impl-trait/equality.stderr @@ -12,6 +12,7 @@ LL | 0_u32 | = note: to return `impl Trait`, all returned values must be of the same type = help: you can instead return a trait object using `Box` + = help: alternatively, create a new `enum` with a variant for each returned type = note: for information on `impl Trait`, see = note: for information on trait objects, see diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr index 2c0425e718abc..87daab5ca7a22 100644 --- a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr +++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr @@ -12,6 +12,7 @@ LL | 1u32 | = note: to return `impl Trait`, all returned values must be of the same type = help: you can instead return a trait object using `Box` + = help: alternatively, create a new `enum` with a variant for each returned type = note: for information on `impl Trait`, see = note: for information on trait objects, see @@ -29,6 +30,7 @@ LL | return 1u32; | = note: to return `impl Trait`, all returned values must be of the same type = help: you can instead return a trait object using `Box` + = help: alternatively, create a new `enum` with a variant for each returned type = note: for information on `impl Trait`, see = note: for information on trait objects, see @@ -46,6 +48,7 @@ LL | 1u32 | = note: to return `impl Trait`, all returned values must be of the same type = help: you can instead return a trait object using `Box` + = help: alternatively, create a new `enum` with a variant for each returned type = note: for information on `impl Trait`, see = note: for information on trait objects, see @@ -75,6 +78,7 @@ LL | _ => 1u32, | = note: to return `impl Trait`, all returned values must be of the same type = help: you can instead return a trait object using `Box` + = help: alternatively, create a new `enum` with a variant for each returned type = note: for information on `impl Trait`, see = note: for information on trait objects, see @@ -94,6 +98,7 @@ LL | | } | = note: to return `impl Trait`, all returned values must be of the same type = help: you can instead return a trait object using `Box` + = help: alternatively, create a new `enum` with a variant for each returned type = note: for information on `impl Trait`, see = note: for information on trait objects, see @@ -111,6 +116,7 @@ LL | 1u32 | = note: to return `impl Trait`, all returned values must be of the same type = help: you can instead return a trait object using `Box` + = help: alternatively, create a new `enum` with a variant for each returned type = note: for information on `impl Trait`, see = note: for information on trait objects, see From c305ac31c09fdd5078fa0e69e718b4da10d9e354 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 15 Jan 2020 09:55:56 -0800 Subject: [PATCH 117/169] Fix error index test --- src/librustc_error_codes/error_codes/E0746.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/librustc_error_codes/error_codes/E0746.md b/src/librustc_error_codes/error_codes/E0746.md index acf369d8e144f..2df27bcf0bf09 100644 --- a/src/librustc_error_codes/error_codes/E0746.md +++ b/src/librustc_error_codes/error_codes/E0746.md @@ -2,7 +2,8 @@ Return types cannot be `dyn Trait`s as they must be `Sized`. Erroneous code example: -```compile_fail,E0746 +```compile_fail,E0277 +# // FIXME: after E0746 is in beta, change the above trait T { fn bar(&self); } From d7a62124018ce8438caeedca203d39997f130b49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 15 Jan 2020 11:14:05 -0800 Subject: [PATCH 118/169] review comments --- src/librustc/traits/error_reporting/mod.rs | 32 --- .../traits/error_reporting/suggestions.rs | 270 +++++++++--------- src/librustc/traits/mod.rs | 2 +- src/librustc_error_codes/error_codes/E0746.md | 10 +- src/librustc_typeck/check/coercion.rs | 67 +++-- ...n-trait-return-should-be-impl-trait.stderr | 11 +- src/test/ui/impl-trait/equality.stderr | 4 +- ...type-err-cause-on-impl-trait-return.stderr | 24 +- 8 files changed, 204 insertions(+), 216 deletions(-) diff --git a/src/librustc/traits/error_reporting/mod.rs b/src/librustc/traits/error_reporting/mod.rs index 17d7b75a7f7d6..db3173989ac60 100644 --- a/src/librustc/traits/error_reporting/mod.rs +++ b/src/librustc/traits/error_reporting/mod.rs @@ -25,7 +25,6 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; -use rustc_hir::intravisit::Visitor; use rustc_span::source_map::SourceMap; use rustc_span::{ExpnKind, Span, DUMMY_SP}; use std::fmt; @@ -1411,34 +1410,3 @@ pub fn suggest_constraining_type_param( } false } - -/// Collect all the returned expressions within the input expression. -/// Used to point at the return spans when we want to suggest some change to them. -struct ReturnsVisitor<'v>(Vec<&'v hir::Expr<'v>>); - -impl<'v> Visitor<'v> for ReturnsVisitor<'v> { - type Map = rustc::hir::map::Map<'v>; - - fn nested_visit_map(&mut self) -> hir::intravisit::NestedVisitorMap<'_, Self::Map> { - hir::intravisit::NestedVisitorMap::None - } - - fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { - match ex.kind { - hir::ExprKind::Ret(Some(ex)) => self.0.push(ex), - _ => {} - } - hir::intravisit::walk_expr(self, ex); - } - - fn visit_body(&mut self, body: &'v hir::Body<'v>) { - if body.generator_kind().is_none() { - if let hir::ExprKind::Block(block, None) = body.value.kind { - if let Some(expr) = block.expr { - self.0.push(expr); - } - } - } - hir::intravisit::walk_body(self, body); - } -} diff --git a/src/librustc/traits/error_reporting/suggestions.rs b/src/librustc/traits/error_reporting/suggestions.rs index c2f562b4bc7b2..7c1b1041c34c3 100644 --- a/src/librustc/traits/error_reporting/suggestions.rs +++ b/src/librustc/traits/error_reporting/suggestions.rs @@ -563,157 +563,159 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let hir = self.tcx.hir(); let parent_node = hir.get_parent_node(obligation.cause.body_id); let node = hir.find(parent_node); - if let Some(hir::Node::Item(hir::Item { - kind: hir::ItemKind::Fn(sig, _, body_id), .. + let (sig, body_id) = if let Some(hir::Node::Item(hir::Item { + kind: hir::ItemKind::Fn(sig, _, body_id), + .. })) = node { - let body = hir.body(*body_id); - let trait_ref = self.resolve_vars_if_possible(trait_ref); - let ty = trait_ref.skip_binder().self_ty(); - let is_object_safe; - match ty.kind { - ty::Dynamic(predicates, _) => { - // The `dyn Trait` is not object safe, do not suggest `Box`. - is_object_safe = predicates.principal_def_id().map_or(true, |def_id| { - !object_safety_violations(self.tcx, def_id).is_empty() - }) - } - // We only want to suggest `impl Trait` to `dyn Trait`s. - // For example, `fn foo() -> str` needs to be filtered out. - _ => return false, + (sig, body_id) + } else { + return false; + }; + let body = hir.body(*body_id); + let trait_ref = self.resolve_vars_if_possible(trait_ref); + let ty = trait_ref.skip_binder().self_ty(); + let is_object_safe = match ty.kind { + ty::Dynamic(predicates, _) => { + // If the `dyn Trait` is not object safe, do not suggest `Box`. + predicates + .principal_def_id() + .map_or(true, |def_id| object_safety_violations(self.tcx, def_id).is_empty()) } + // We only want to suggest `impl Trait` to `dyn Trait`s. + // For example, `fn foo() -> str` needs to be filtered out. + _ => return false, + }; - let ret_ty = if let hir::FunctionRetTy::Return(ret_ty) = sig.decl.output { - ret_ty - } else { - return false; - }; - - // Use `TypeVisitor` instead of the output type directly to find the span of `ty` for - // cases like `fn foo() -> (dyn Trait, i32) {}`. - // Recursively look for `TraitObject` types and if there's only one, use that span to - // suggest `impl Trait`. - - // Visit to make sure there's a single `return` type to suggest `impl Trait`, - // otherwise suggest using `Box` or an enum. - let mut visitor = ReturnsVisitor(vec![]); - visitor.visit_body(&body); - - let tables = self.in_progress_tables.map(|t| t.borrow()).unwrap(); + let ret_ty = if let hir::FunctionRetTy::Return(ret_ty) = sig.decl.output { + ret_ty + } else { + return false; + }; - let mut all_returns_conform_to_trait = true; - let mut all_returns_have_same_type = true; - let mut last_ty = None; - if let Some(ty_ret_ty) = tables.node_type_opt(ret_ty.hir_id) { - let cause = ObligationCause::misc(ret_ty.span, ret_ty.hir_id); - let param_env = ty::ParamEnv::empty(); - if let ty::Dynamic(predicates, _) = &ty_ret_ty.kind { - for expr in &visitor.0 { - if let Some(returned_ty) = tables.node_type_opt(expr.hir_id) { - all_returns_have_same_type &= - Some(returned_ty) == last_ty || last_ty.is_none(); - last_ty = Some(returned_ty); - for predicate in predicates.iter() { - let pred = predicate.with_self_ty(self.tcx, returned_ty); - let obl = Obligation::new(cause.clone(), param_env, pred); - all_returns_conform_to_trait &= self.predicate_may_hold(&obl); - } + // Use `TypeVisitor` instead of the output type directly to find the span of `ty` for + // cases like `fn foo() -> (dyn Trait, i32) {}`. + // Recursively look for `TraitObject` types and if there's only one, use that span to + // suggest `impl Trait`. + + // Visit to make sure there's a single `return` type to suggest `impl Trait`, + // otherwise suggest using `Box` or an enum. + let mut visitor = ReturnsVisitor(vec![]); + visitor.visit_body(&body); + + let tables = self.in_progress_tables.map(|t| t.borrow()).unwrap(); + + let mut all_returns_conform_to_trait = true; + let mut all_returns_have_same_type = true; + let mut last_ty = None; + if let Some(ty_ret_ty) = tables.node_type_opt(ret_ty.hir_id) { + let cause = ObligationCause::misc(ret_ty.span, ret_ty.hir_id); + let param_env = ty::ParamEnv::empty(); + if let ty::Dynamic(predicates, _) = &ty_ret_ty.kind { + for expr in &visitor.0 { + if let Some(returned_ty) = tables.node_type_opt(expr.hir_id) { + all_returns_have_same_type &= + Some(returned_ty) == last_ty || last_ty.is_none(); + last_ty = Some(returned_ty); + for predicate in predicates.iter() { + let pred = predicate.with_self_ty(self.tcx, returned_ty); + let obl = Obligation::new(cause.clone(), param_env, pred); + all_returns_conform_to_trait &= self.predicate_may_hold(&obl); } } } - } else { - // We still want to verify whether all the return types conform to each other. - for expr in &visitor.0 { - let returned_ty = tables.node_type_opt(expr.hir_id); - all_returns_have_same_type &= last_ty == returned_ty || last_ty.is_none(); - last_ty = returned_ty; - } } + } else { + // We still want to verify whether all the return types conform to each other. + for expr in &visitor.0 { + let returned_ty = tables.node_type_opt(expr.hir_id); + all_returns_have_same_type &= last_ty == returned_ty || last_ty.is_none(); + last_ty = returned_ty; + } + } - let (snippet, last_ty) = - if let (true, hir::TyKind::TraitObject(..), Ok(snippet), true, Some(last_ty)) = ( - // Verify that we're dealing with a return `dyn Trait` - ret_ty.span.overlaps(span), - &ret_ty.kind, - self.tcx.sess.source_map().span_to_snippet(ret_ty.span), - // If any of the return types does not conform to the trait, then we can't - // suggest `impl Trait` nor trait objects, it is a type mismatch error. - all_returns_conform_to_trait, - last_ty, - ) { - (snippet, last_ty) - } else { - return false; - }; - err.code(error_code!(E0746)); - err.set_primary_message("return type cannot have an unboxed trait object"); - err.children.clear(); - let impl_trait_msg = "for information on `impl Trait`, see \ - "; - let trait_obj_msg = "for information on trait objects, see \ - "; - let has_dyn = snippet.split_whitespace().next().map_or(false, |s| s == "dyn"); - let trait_obj = if has_dyn { &snippet[4..] } else { &snippet[..] }; - if all_returns_have_same_type { - // Suggest `-> impl Trait`. - err.span_suggestion( + let (snippet, last_ty) = + if let (true, hir::TyKind::TraitObject(..), Ok(snippet), true, Some(last_ty)) = ( + // Verify that we're dealing with a return `dyn Trait` + ret_ty.span.overlaps(span), + &ret_ty.kind, + self.tcx.sess.source_map().span_to_snippet(ret_ty.span), + // If any of the return types does not conform to the trait, then we can't + // suggest `impl Trait` nor trait objects, it is a type mismatch error. + all_returns_conform_to_trait, + last_ty, + ) { + (snippet, last_ty) + } else { + return false; + }; + err.code(error_code!(E0746)); + err.set_primary_message("return type cannot have an unboxed trait object"); + err.children.clear(); + let impl_trait_msg = "for information on `impl Trait`, see \ + "; + let trait_obj_msg = "for information on trait objects, see \ + "; + let has_dyn = snippet.split_whitespace().next().map_or(false, |s| s == "dyn"); + let trait_obj = if has_dyn { &snippet[4..] } else { &snippet[..] }; + if all_returns_have_same_type { + // Suggest `-> impl Trait`. + err.span_suggestion( + ret_ty.span, + &format!( + "return `impl {1}` instead, as all return paths are of type `{}`, \ + which implements `{1}`", + last_ty, trait_obj, + ), + format!("impl {}", trait_obj), + Applicability::MachineApplicable, + ); + err.note(impl_trait_msg); + } else { + if is_object_safe { + // Suggest `-> Box` and `Box::new(returned_value)`. + // Get all the return values and collect their span and suggestion. + let mut suggestions = visitor + .0 + .iter() + .map(|expr| { + ( + expr.span, + format!( + "Box::new({})", + self.tcx.sess.source_map().span_to_snippet(expr.span).unwrap() + ), + ) + }) + .collect::>(); + // Add the suggestion for the return type. + suggestions.push(( ret_ty.span, - &format!( - "return `impl {1}` instead, as all return paths are of type `{}`, \ - which implements `{1}`", - last_ty, trait_obj, - ), - format!("impl {}", trait_obj), - Applicability::MachineApplicable, + format!("Box<{}{}>", if has_dyn { "" } else { "dyn " }, snippet), + )); + err.multipart_suggestion( + "return a trait object instead", + suggestions, + Applicability::MaybeIncorrect, ); - err.note(impl_trait_msg); } else { - if is_object_safe { - // Suggest `-> Box` and `Box::new(returned_value)`. - // Get all the return values and collect their span and suggestion. - let mut suggestions = visitor - .0 - .iter() - .map(|expr| { - ( - expr.span, - format!( - "Box::new({})", - self.tcx.sess.source_map().span_to_snippet(expr.span).unwrap() - ), - ) - }) - .collect::>(); - // Add the suggestion for the return type. - suggestions.push(( - ret_ty.span, - format!("Box<{}{}>", if has_dyn { "" } else { "dyn " }, snippet), - )); - err.multipart_suggestion( - "return a trait object instead", - suggestions, - Applicability::MaybeIncorrect, - ); - } else { - err.note(&format!( - "if trait `{}` was object safe, you could return a trait object", - trait_obj, - )); - } err.note(&format!( - "if all the returned values were of the same type you could use \ - `impl {}` as the return type", + "if trait `{}` was object safe, you could return a trait object", trait_obj, )); - err.note(impl_trait_msg); - err.note(trait_obj_msg); - err.note("you can create a new `enum` with a variant for each returned type"); } - return true; + err.note(trait_obj_msg); + err.note(&format!( + "if all the returned values were of the same type you could use \ + `impl {}` as the return type", + trait_obj, + )); + err.note(impl_trait_msg); + err.note("you can create a new `enum` with a variant for each returned type"); } - false + true } crate fn point_at_returns_when_relevant( @@ -1686,6 +1688,8 @@ pub fn suggest_constraining_type_param( false } +/// Collect all the returned expressions within the input expression. +/// Used to point at the return spans when we want to suggest some change to them. struct ReturnsVisitor<'v>(Vec<&'v hir::Expr<'v>>); impl<'v> Visitor<'v> for ReturnsVisitor<'v> { diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index b4998d4486f09..2e5da2b038254 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -1171,7 +1171,7 @@ impl<'tcx> ObligationCause<'tcx> { } } -impl<'tcx> ObligationCauseCode<'tcx> { +impl ObligationCauseCode<'_> { // Return the base obligation, ignoring derived obligations. pub fn peel_derives(&self) -> &Self { let mut base_cause = self; diff --git a/src/librustc_error_codes/error_codes/E0746.md b/src/librustc_error_codes/error_codes/E0746.md index 2df27bcf0bf09..041061f3380c1 100644 --- a/src/librustc_error_codes/error_codes/E0746.md +++ b/src/librustc_error_codes/error_codes/E0746.md @@ -12,8 +12,8 @@ impl T for S { fn bar(&self) {} } -// Having the trait `T` as return type is invalid because bare traits do not -// have a statically known size: +// Having the trait `T` as return type is invalid because +// bare trait objects do not have a statically known size: fn foo() -> dyn T { S(42) } @@ -32,15 +32,15 @@ If there is a single type involved, you can use [`impl Trait`]: # fn bar(&self) {} # } // The compiler will select `S(usize)` as the materialized return type of this -// function, but callers will only be able to access associated items from `T`. +// function, but callers will only know that the return type implements `T`. fn foo() -> impl T { S(42) } ``` If there are multiple types involved, the only way you care to interact with -them is through the trait's interface and having to rely on dynamic dispatch is -acceptable, then you can use [trait objects] with `Box`, or other container +them is through the trait's interface, and having to rely on dynamic dispatch +is acceptable, then you can use [trait objects] with `Box`, or other container types like `Rc` or `Arc`: ``` diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 8aa2cb5034224..768e532fa3b91 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -68,7 +68,7 @@ use rustc_error_codes::*; use rustc_errors::{struct_span_err, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::DefId; -use rustc_span; +use rustc_span::{self, Span}; use rustc_span::symbol::sym; use rustc_target::spec::abi::Abi; use smallvec::{smallvec, SmallVec}; @@ -1352,39 +1352,48 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { } } if let (Some(sp), Some(return_sp)) = (fcx.ret_coercion_span.borrow().as_ref(), return_sp) { - err.span_label(return_sp, "expected because this return type..."); - err.span_label( *sp, format!( - "...is found to be `{}` here", - fcx.resolve_vars_with_obligations(expected), - )); - err.note("to return `impl Trait`, all returned values must be of the same type"); - let snippet = fcx - .tcx - .sess - .source_map() - .span_to_snippet(return_sp) - .unwrap_or_else(|_| "dyn Trait".to_string()); - let mut snippet_iter = snippet.split_whitespace(); - let has_impl = snippet_iter.next().map_or(false, |s| s == "impl"); - if has_impl { - err.help(&format!( - "you can instead return a trait object using `Box`", - &snippet[5..] - )); - } - err.help("alternatively, create a new `enum` with a variant for each returned type"); - let impl_trait_msg = "for information on `impl Trait`, see \ + self.add_impl_trait_explanation(&mut err, fcx, expected, *sp, return_sp); + } + err + } + + fn add_impl_trait_explanation<'a>( + &self, + err: &mut DiagnosticBuilder<'a>, + fcx: &FnCtxt<'a, 'tcx>, + expected: Ty<'tcx>, + sp: Span, + return_sp: Span, + ) { + err.span_label(return_sp, "expected because this return type..."); + err.span_label( + sp, + format!("...is found to be `{}` here", fcx.resolve_vars_with_obligations(expected)), + ); + let impl_trait_msg = "for information on `impl Trait`, see \ "; - let trait_obj_msg = "for information on trait objects, see \ + let trait_obj_msg = "for information on trait objects, see \ "; - err.note(impl_trait_msg); - if has_impl { - err.note(trait_obj_msg); - } + err.note("to return `impl Trait`, all returned values must be of the same type"); + err.note(impl_trait_msg); + let snippet = fcx + .tcx + .sess + .source_map() + .span_to_snippet(return_sp) + .unwrap_or_else(|_| "dyn Trait".to_string()); + let mut snippet_iter = snippet.split_whitespace(); + let has_impl = snippet_iter.next().map_or(false, |s| s == "impl"); + if has_impl { + err.help(&format!( + "you can instead return a trait object using `Box`", + &snippet[5..] + )); + err.note(trait_obj_msg); } - err + err.help("alternatively, create a new `enum` with a variant for each returned type"); } fn is_return_ty_unsized(&self, fcx: &FnCtxt<'a, 'tcx>, blk_id: hir::HirId) -> bool { diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr index 3d0707c091644..ac101f8f3ce36 100644 --- a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr +++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr @@ -82,11 +82,18 @@ error[E0746]: return type cannot have an unboxed trait object LL | fn bal() -> dyn Trait { | ^^^^^^^^^ doesn't have a size known at compile-time | - = note: if trait `Trait` was object safe, you could return a trait object + = note: for information on trait objects, see = note: if all the returned values were of the same type you could use `impl Trait` as the return type = note: for information on `impl Trait`, see - = note: for information on trait objects, see = note: you can create a new `enum` with a variant for each returned type +help: return a trait object instead + | +LL | fn bal() -> Box { +LL | if true { +LL | return Box::new(Struct); +LL | } +LL | Box::new(42) + | error[E0746]: return type cannot have an unboxed trait object --> $DIR/dyn-trait-return-should-be-impl-trait.rs:27:13 diff --git a/src/test/ui/impl-trait/equality.stderr b/src/test/ui/impl-trait/equality.stderr index ceb32dd4cd33e..a399fadbc5db5 100644 --- a/src/test/ui/impl-trait/equality.stderr +++ b/src/test/ui/impl-trait/equality.stderr @@ -11,10 +11,10 @@ LL | 0_u32 | ^^^^^ expected `i32`, found `u32` | = note: to return `impl Trait`, all returned values must be of the same type - = help: you can instead return a trait object using `Box` - = help: alternatively, create a new `enum` with a variant for each returned type = note: for information on `impl Trait`, see + = help: you can instead return a trait object using `Box` = note: for information on trait objects, see + = help: alternatively, create a new `enum` with a variant for each returned type error[E0277]: cannot add `impl Foo` to `u32` --> $DIR/equality.rs:24:11 diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr index 87daab5ca7a22..9859c73b7b18b 100644 --- a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr +++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr @@ -11,10 +11,10 @@ LL | 1u32 | ^^^^ expected `i32`, found `u32` | = note: to return `impl Trait`, all returned values must be of the same type - = help: you can instead return a trait object using `Box` - = help: alternatively, create a new `enum` with a variant for each returned type = note: for information on `impl Trait`, see + = help: you can instead return a trait object using `Box` = note: for information on trait objects, see + = help: alternatively, create a new `enum` with a variant for each returned type error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:13:16 @@ -29,10 +29,10 @@ LL | return 1u32; | ^^^^ expected `i32`, found `u32` | = note: to return `impl Trait`, all returned values must be of the same type - = help: you can instead return a trait object using `Box` - = help: alternatively, create a new `enum` with a variant for each returned type = note: for information on `impl Trait`, see + = help: you can instead return a trait object using `Box` = note: for information on trait objects, see + = help: alternatively, create a new `enum` with a variant for each returned type error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:22:9 @@ -47,10 +47,10 @@ LL | 1u32 | ^^^^ expected `i32`, found `u32` | = note: to return `impl Trait`, all returned values must be of the same type - = help: you can instead return a trait object using `Box` - = help: alternatively, create a new `enum` with a variant for each returned type = note: for information on `impl Trait`, see + = help: you can instead return a trait object using `Box` = note: for information on trait objects, see + = help: alternatively, create a new `enum` with a variant for each returned type error[E0308]: `if` and `else` have incompatible types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:31:9 @@ -77,10 +77,10 @@ LL | _ => 1u32, | ^^^^ expected `i32`, found `u32` | = note: to return `impl Trait`, all returned values must be of the same type - = help: you can instead return a trait object using `Box` - = help: alternatively, create a new `enum` with a variant for each returned type = note: for information on `impl Trait`, see + = help: you can instead return a trait object using `Box` = note: for information on trait objects, see + = help: alternatively, create a new `enum` with a variant for each returned type error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:45:5 @@ -97,10 +97,10 @@ LL | | } | |_____^ expected `i32`, found `u32` | = note: to return `impl Trait`, all returned values must be of the same type - = help: you can instead return a trait object using `Box` - = help: alternatively, create a new `enum` with a variant for each returned type = note: for information on `impl Trait`, see + = help: you can instead return a trait object using `Box` = note: for information on trait objects, see + = help: alternatively, create a new `enum` with a variant for each returned type error[E0308]: mismatched types --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:59:13 @@ -115,10 +115,10 @@ LL | 1u32 | ^^^^ expected `i32`, found `u32` | = note: to return `impl Trait`, all returned values must be of the same type - = help: you can instead return a trait object using `Box` - = help: alternatively, create a new `enum` with a variant for each returned type = note: for information on `impl Trait`, see + = help: you can instead return a trait object using `Box` = note: for information on trait objects, see + = help: alternatively, create a new `enum` with a variant for each returned type error: aborting due to 7 previous errors From 00e262689599a6a753bbf7ce8786e07ed100d238 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 15 Jan 2020 15:49:54 -0800 Subject: [PATCH 119/169] Account for object safety when suggesting `Box` --- .../traits/error_reporting/suggestions.rs | 4 +- src/librustc_hir/hir.rs | 7 +++ src/librustc_typeck/check/coercion.rs | 53 +++++++++++++++---- ...n-trait-return-should-be-impl-trait.stderr | 2 +- src/test/ui/impl-trait/equality.stderr | 2 +- ...safe-trait-in-return-position-dyn-trait.rs | 35 ++++++++++++ ...-trait-in-return-position-dyn-trait.stderr | 21 ++++++++ ...afe-trait-in-return-position-impl-trait.rs | 46 ++++++++++++++++ ...trait-in-return-position-impl-trait.stderr | 39 ++++++++++++++ ...type-err-cause-on-impl-trait-return.stderr | 12 ++--- 10 files changed, 202 insertions(+), 19 deletions(-) create mode 100644 src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.rs create mode 100644 src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr create mode 100644 src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.rs create mode 100644 src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr diff --git a/src/librustc/traits/error_reporting/suggestions.rs b/src/librustc/traits/error_reporting/suggestions.rs index 7c1b1041c34c3..c3af063d518f0 100644 --- a/src/librustc/traits/error_reporting/suggestions.rs +++ b/src/librustc/traits/error_reporting/suggestions.rs @@ -696,11 +696,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { format!("Box<{}{}>", if has_dyn { "" } else { "dyn " }, snippet), )); err.multipart_suggestion( - "return a trait object instead", + "return a boxed trait object instead", suggestions, Applicability::MaybeIncorrect, ); } else { + // This is currently not possible to trigger because E0038 takes precedence, but + // leave it in for completeness in case anything changes in an earlier stage. err.note(&format!( "if trait `{}` was object safe, you could return a trait object", trait_obj, diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs index 550e3654d0800..5c1d600c837c4 100644 --- a/src/librustc_hir/hir.rs +++ b/src/librustc_hir/hir.rs @@ -377,6 +377,13 @@ pub enum GenericBound<'hir> { } impl GenericBound<'_> { + pub fn trait_def_id(&self) -> Option { + match self { + GenericBound::Trait(data, _) => Some(data.trait_ref.trait_def_id()), + _ => None, + } + } + pub fn span(&self) -> Span { match self { &GenericBound::Trait(ref t, ..) => t.span, diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 768e532fa3b91..a32fbff7bfe2d 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -55,6 +55,7 @@ use crate::check::{FnCtxt, Needs}; use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc::infer::{Coercion, InferOk, InferResult}; use rustc::session::parse::feature_err; +use rustc::traits::object_safety_violations; use rustc::traits::{self, ObligationCause, ObligationCauseCode}; use rustc::ty::adjustment::{ Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCast, @@ -68,8 +69,8 @@ use rustc_error_codes::*; use rustc_errors::{struct_span_err, DiagnosticBuilder}; use rustc_hir as hir; use rustc_hir::def_id::DefId; -use rustc_span::{self, Span}; use rustc_span::symbol::sym; +use rustc_span::{self, Span}; use rustc_target::spec::abi::Abi; use smallvec::{smallvec, SmallVec}; use std::ops::Deref; @@ -1311,7 +1312,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { let mut err = fcx.report_mismatched_types(cause, expected, found, ty_err); let mut pointing_at_return_type = false; - let mut return_sp = None; + let mut fn_output = None; // Verify that this is a tail expression of a function, otherwise the // label pointing out the cause for the type coercion will be wrong @@ -1348,11 +1349,11 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { ); } if !pointing_at_return_type { - return_sp = Some(fn_decl.output.span()); // `impl Trait` return type + fn_output = Some(&fn_decl.output); // `impl Trait` return type } } - if let (Some(sp), Some(return_sp)) = (fcx.ret_coercion_span.borrow().as_ref(), return_sp) { - self.add_impl_trait_explanation(&mut err, fcx, expected, *sp, return_sp); + if let (Some(sp), Some(fn_output)) = (fcx.ret_coercion_span.borrow().as_ref(), fn_output) { + self.add_impl_trait_explanation(&mut err, fcx, expected, *sp, fn_output); } err } @@ -1363,8 +1364,9 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { fcx: &FnCtxt<'a, 'tcx>, expected: Ty<'tcx>, sp: Span, - return_sp: Span, + fn_output: &hir::FunctionRetTy<'_>, ) { + let return_sp = fn_output.span(); err.span_label(return_sp, "expected because this return type..."); err.span_label( sp, @@ -1386,11 +1388,42 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { .unwrap_or_else(|_| "dyn Trait".to_string()); let mut snippet_iter = snippet.split_whitespace(); let has_impl = snippet_iter.next().map_or(false, |s| s == "impl"); + // Only suggest `Box` if `Trait` in `impl Trait` is object safe. + let mut is_object_safe = false; + if let hir::FunctionRetTy::Return(ty) = fn_output { + // Get the return type. + if let hir::TyKind::Def(..) = ty.kind { + let ty = AstConv::ast_ty_to_ty(fcx, ty); + // Get the `impl Trait`'s `DefId`. + if let ty::Opaque(def_id, _) = ty.kind { + let hir_id = fcx.tcx.hir().as_local_hir_id(def_id).unwrap(); + // Get the `impl Trait`'s `Item` so that we can get its trait bounds and + // get the `Trait`'s `DefId`. + if let hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds, .. }) = + fcx.tcx.hir().expect_item(hir_id).kind + { + // Are of this `impl Trait`'s traits object safe? + is_object_safe = bounds.iter().all(|bound| { + bound.trait_def_id().map_or(false, |def_id| { + object_safety_violations(fcx.tcx, def_id).is_empty() + }) + }) + } + } + } + }; if has_impl { - err.help(&format!( - "you can instead return a trait object using `Box`", - &snippet[5..] - )); + if is_object_safe { + err.help(&format!( + "you can instead return a boxed trait object using `Box`", + &snippet[5..] + )); + } else { + err.help(&format!( + "if the trait `{}` were object safe, you could return a boxed trait object", + &snippet[5..] + )); + } err.note(trait_obj_msg); } err.help("alternatively, create a new `enum` with a variant for each returned type"); diff --git a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr index ac101f8f3ce36..977a7ef0e0244 100644 --- a/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr +++ b/src/test/ui/impl-trait/dyn-trait-return-should-be-impl-trait.stderr @@ -86,7 +86,7 @@ LL | fn bal() -> dyn Trait { = note: if all the returned values were of the same type you could use `impl Trait` as the return type = note: for information on `impl Trait`, see = note: you can create a new `enum` with a variant for each returned type -help: return a trait object instead +help: return a boxed trait object instead | LL | fn bal() -> Box { LL | if true { diff --git a/src/test/ui/impl-trait/equality.stderr b/src/test/ui/impl-trait/equality.stderr index a399fadbc5db5..9178358b60a9c 100644 --- a/src/test/ui/impl-trait/equality.stderr +++ b/src/test/ui/impl-trait/equality.stderr @@ -12,7 +12,7 @@ LL | 0_u32 | = note: to return `impl Trait`, all returned values must be of the same type = note: for information on `impl Trait`, see - = help: you can instead return a trait object using `Box` + = help: if the trait `Foo` were object safe, you could return a boxed trait object = note: for information on trait objects, see = help: alternatively, create a new `enum` with a variant for each returned type diff --git a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.rs b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.rs new file mode 100644 index 0000000000000..ab3086c78b3a1 --- /dev/null +++ b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.rs @@ -0,0 +1,35 @@ +#![allow(bare_trait_objects)] +trait NotObjectSafe { + fn foo() -> Self; +} + +struct A; +struct B; + +impl NotObjectSafe for A { + fn foo() -> Self { + A + } +} + +impl NotObjectSafe for B { + fn foo() -> Self { + B + } +} + +fn car() -> dyn NotObjectSafe { //~ ERROR the trait `NotObjectSafe` cannot be made into an object + if true { + return A; + } + B +} + +fn cat() -> Box { //~ ERROR the trait `NotObjectSafe` cannot be made into an + if true { + return Box::new(A); + } + Box::new(B) +} + +fn main() {} diff --git a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr new file mode 100644 index 0000000000000..0c8d267c13434 --- /dev/null +++ b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr @@ -0,0 +1,21 @@ +error[E0038]: the trait `NotObjectSafe` cannot be made into an object + --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:21:1 + | +LL | fn foo() -> Self; + | --- associated function `foo` has no `self` parameter +... +LL | fn car() -> dyn NotObjectSafe { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object + +error[E0038]: the trait `NotObjectSafe` cannot be made into an object + --> $DIR/object-unsafe-trait-in-return-position-dyn-trait.rs:28:1 + | +LL | fn foo() -> Self; + | --- associated function `foo` has no `self` parameter +... +LL | fn cat() -> Box { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.rs b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.rs new file mode 100644 index 0000000000000..503515013b9ab --- /dev/null +++ b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.rs @@ -0,0 +1,46 @@ +trait NotObjectSafe { + fn foo() -> Self; +} + +trait ObjectSafe { + fn bar(&self); +} + +struct A; +struct B; + +impl NotObjectSafe for A { + fn foo() -> Self { + A + } +} + +impl NotObjectSafe for B { + fn foo() -> Self { + B + } +} + +impl ObjectSafe for A { + fn bar(&self) {} +} + +impl ObjectSafe for B { + fn bar(&self) {} +} + +fn can() -> impl NotObjectSafe { + if true { + return A; + } + B //~ ERROR mismatched types +} + +fn cat() -> impl ObjectSafe { + if true { + return A; + } + B //~ ERROR mismatched types +} + +fn main() {} diff --git a/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr new file mode 100644 index 0000000000000..dd4260fbe4f91 --- /dev/null +++ b/src/test/ui/impl-trait/object-unsafe-trait-in-return-position-impl-trait.stderr @@ -0,0 +1,39 @@ +error[E0308]: mismatched types + --> $DIR/object-unsafe-trait-in-return-position-impl-trait.rs:36:5 + | +LL | fn can() -> impl NotObjectSafe { + | ------------------ expected because this return type... +LL | if true { +LL | return A; + | - ...is found to be `A` here +LL | } +LL | B + | ^ expected struct `A`, found struct `B` + | + = note: to return `impl Trait`, all returned values must be of the same type + = note: for information on `impl Trait`, see + = help: if the trait `NotObjectSafe` were object safe, you could return a boxed trait object + = note: for information on trait objects, see + = help: alternatively, create a new `enum` with a variant for each returned type + +error[E0308]: mismatched types + --> $DIR/object-unsafe-trait-in-return-position-impl-trait.rs:43:5 + | +LL | fn cat() -> impl ObjectSafe { + | --------------- expected because this return type... +LL | if true { +LL | return A; + | - ...is found to be `A` here +LL | } +LL | B + | ^ expected struct `A`, found struct `B` + | + = note: to return `impl Trait`, all returned values must be of the same type + = note: for information on `impl Trait`, see + = help: you can instead return a boxed trait object using `Box` + = note: for information on trait objects, see + = help: alternatively, create a new `enum` with a variant for each returned type + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr index 9859c73b7b18b..b663cccbeef0f 100644 --- a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr +++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr @@ -12,7 +12,7 @@ LL | 1u32 | = note: to return `impl Trait`, all returned values must be of the same type = note: for information on `impl Trait`, see - = help: you can instead return a trait object using `Box` + = help: you can instead return a boxed trait object using `Box` = note: for information on trait objects, see = help: alternatively, create a new `enum` with a variant for each returned type @@ -30,7 +30,7 @@ LL | return 1u32; | = note: to return `impl Trait`, all returned values must be of the same type = note: for information on `impl Trait`, see - = help: you can instead return a trait object using `Box` + = help: you can instead return a boxed trait object using `Box` = note: for information on trait objects, see = help: alternatively, create a new `enum` with a variant for each returned type @@ -48,7 +48,7 @@ LL | 1u32 | = note: to return `impl Trait`, all returned values must be of the same type = note: for information on `impl Trait`, see - = help: you can instead return a trait object using `Box` + = help: you can instead return a boxed trait object using `Box` = note: for information on trait objects, see = help: alternatively, create a new `enum` with a variant for each returned type @@ -78,7 +78,7 @@ LL | _ => 1u32, | = note: to return `impl Trait`, all returned values must be of the same type = note: for information on `impl Trait`, see - = help: you can instead return a trait object using `Box` + = help: you can instead return a boxed trait object using `Box` = note: for information on trait objects, see = help: alternatively, create a new `enum` with a variant for each returned type @@ -98,7 +98,7 @@ LL | | } | = note: to return `impl Trait`, all returned values must be of the same type = note: for information on `impl Trait`, see - = help: you can instead return a trait object using `Box` + = help: you can instead return a boxed trait object using `Box` = note: for information on trait objects, see = help: alternatively, create a new `enum` with a variant for each returned type @@ -116,7 +116,7 @@ LL | 1u32 | = note: to return `impl Trait`, all returned values must be of the same type = note: for information on `impl Trait`, see - = help: you can instead return a trait object using `Box` + = help: you can instead return a boxed trait object using `Box` = note: for information on trait objects, see = help: alternatively, create a new `enum` with a variant for each returned type From 3fd1af5fdb59a49e9eb5e05ff15fef6b8514ae31 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 3 Jan 2020 13:33:28 +0100 Subject: [PATCH 120/169] let rustfmt undo most of my edits :( --- src/librustc/mir/interpret/error.rs | 3 +-- src/librustc_mir/interpret/cast.rs | 20 +++++++++----------- src/librustc_mir/interpret/eval_context.rs | 12 +++--------- src/librustc_mir/interpret/memory.rs | 3 +-- src/librustc_mir/interpret/operand.rs | 4 +--- src/librustc_mir/interpret/validity.rs | 6 ++---- 6 files changed, 17 insertions(+), 31 deletions(-) diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index 29b3b045ca5fe..42d896af8014d 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -137,8 +137,7 @@ impl<'tcx> ConstEvalErr<'tcx> { ) -> Result, ErrorHandled> { let must_error = match self.error { InterpError::MachineStop(_) => bug!("CTFE does not stop"), - err_inval!(Layout(LayoutError::Unknown(_))) - | err_inval!(TooGeneric) => { + err_inval!(Layout(LayoutError::Unknown(_))) | err_inval!(TooGeneric) => { return Err(ErrorHandled::TooGeneric); } err_inval!(TypeckError) => return Err(ErrorHandled::Reported), diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index 6d0b6bf70ad8c..9461a06690212 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -118,17 +118,15 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } // The rest is integer/pointer-"like", including fn ptr casts and casts from enums that // are represented as integers. - _ => { - assert!( - src.layout.ty.is_bool() - || src.layout.ty.is_char() - || src.layout.ty.is_enum() - || src.layout.ty.is_integral() - || src.layout.ty.is_any_ptr(), - "Unexpected cast from type {:?}", - src.layout.ty - ) - } + _ => assert!( + src.layout.ty.is_bool() + || src.layout.ty.is_char() + || src.layout.ty.is_enum() + || src.layout.ty.is_integral() + || src.layout.ty.is_any_ptr(), + "Unexpected cast from type {:?}", + src.layout.ty + ), } // Handle cast from a univariant (ZST) enum. diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 3d590fb820359..206d3d156735e 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -152,16 +152,10 @@ impl<'tcx, Tag: Copy + 'static> LocalState<'tcx, Tag> { &mut self, ) -> InterpResult<'tcx, Result<&mut LocalValue, MemPlace>> { match self.value { - LocalValue::Dead => { - throw_unsup!(DeadLocal) - } - LocalValue::Live(Operand::Indirect(mplace)) => { - Ok(Err(mplace)) - } + LocalValue::Dead => throw_unsup!(DeadLocal), + LocalValue::Live(Operand::Indirect(mplace)) => Ok(Err(mplace)), ref mut local @ LocalValue::Live(Operand::Immediate(_)) - | ref mut local @ LocalValue::Uninitialized => { - Ok(Ok(local)) - } + | ref mut local @ LocalValue::Uninitialized => Ok(Ok(local)), } } } diff --git a/src/librustc_mir/interpret/memory.rs b/src/librustc_mir/interpret/memory.rs index 3386254c93b75..0bcdf9ae3c1f2 100644 --- a/src/librustc_mir/interpret/memory.rs +++ b/src/librustc_mir/interpret/memory.rs @@ -580,8 +580,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> { let layout = self.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap(); Ok((layout.size, layout.align.abi)) } - Some(GlobalAlloc::Memory(alloc)) => - { + Some(GlobalAlloc::Memory(alloc)) => { // Need to duplicate the logic here, because the global allocations have // different associated types than the interpreter-local ones. Ok((alloc.size, alloc.align)) diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 34a32daaab65f..d1c08da6cbee5 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -543,9 +543,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { | ty::ConstKind::Placeholder(..) => { bug!("eval_const_to_op: Unexpected ConstKind {:?}", val) } - ty::ConstKind::Value(val_val) => { - val_val - } + ty::ConstKind::Value(val_val) => val_val, }; // Other cases need layout. let layout = from_known_layout(layout, || self.layout_of(val.ty))?; diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index d0fef08bb60c7..9f713dfd5e607 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -114,8 +114,7 @@ fn write_path(out: &mut String, path: &Vec) { ClosureVar(name) => write!(out, ".", name), TupleElem(idx) => write!(out, ".{}", idx), ArrayElem(idx) => write!(out, "[{}]", idx), - Deref => - { + Deref => { // This does not match Rust syntax, but it is more readable for long paths -- and // some of the other items here also are not Rust syntax. Actually we can't // even use the usual syntax because we are just showing the projections, @@ -206,8 +205,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M ty::Adt(def, ..) if def.is_enum() => { // we might be projecting *to* a variant, or to a field *in*a variant. match layout.variants { - layout::Variants::Single { index } => - { + layout::Variants::Single { index } => { // Inside a variant PathElem::Field(def.variants[index].fields[field].ident.name) } From c781d15da32bf82977311af6f056ee2fc3506bda Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 6 Jan 2020 11:35:55 +0100 Subject: [PATCH 121/169] adjust Deref comment --- src/librustc_mir/interpret/validity.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index 9f713dfd5e607..ec9ac52a87c3a 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -114,13 +114,11 @@ fn write_path(out: &mut String, path: &Vec) { ClosureVar(name) => write!(out, ".", name), TupleElem(idx) => write!(out, ".{}", idx), ArrayElem(idx) => write!(out, "[{}]", idx), - Deref => { - // This does not match Rust syntax, but it is more readable for long paths -- and - // some of the other items here also are not Rust syntax. Actually we can't - // even use the usual syntax because we are just showing the projections, - // not the root. - write!(out, ".") - } + // `.` does not match Rust syntax, but it is more readable for long paths -- and + // some of the other items here also are not Rust syntax. Actually we can't + // even use the usual syntax because we are just showing the projections, + // not the root. + Deref => write!(out, "."), Tag => write!(out, "."), DynDowncast => write!(out, "."), } From 0f70daa9b06882d7fb684a60160e4949d2861136 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 12 Jan 2020 13:29:00 +0300 Subject: [PATCH 122/169] resolve: Move privacy error reporting into a separate method Give named fields to `struct PrivacyError` Move `fn report_ambiguity_error` to `diagnostics.rs` --- src/librustc_resolve/diagnostics.rs | 153 +++++++++++++++++++++++++- src/librustc_resolve/imports.rs | 6 +- src/librustc_resolve/lib.rs | 162 ++-------------------------- 3 files changed, 166 insertions(+), 155 deletions(-) diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 9742067975499..f83daa1636752 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -8,7 +8,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_feature::BUILTIN_ATTRIBUTES; use rustc_hir::def::Namespace::{self, *}; -use rustc_hir::def::{self, DefKind, NonMacroAttrKind}; +use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, NonMacroAttrKind}; use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::SourceMap; @@ -20,8 +20,9 @@ use syntax::util::lev_distance::find_best_match_for_name; use crate::imports::{ImportDirective, ImportDirectiveSubclass, ImportResolver}; use crate::path_names_to_string; -use crate::VisResolutionError; +use crate::{AmbiguityError, AmbiguityErrorMisc, AmbiguityKind}; use crate::{BindingError, CrateLint, HasGenericParams, LegacyScope, Module, ModuleOrUniformRoot}; +use crate::{NameBinding, NameBindingKind, PrivacyError, VisResolutionError}; use crate::{ParentScope, PathResult, ResolutionError, Resolver, Scope, ScopeSet, Segment}; use rustc_error_codes::*; @@ -802,6 +803,154 @@ impl<'a> Resolver<'a> { } false } + + fn binding_description(&self, b: &NameBinding<'_>, ident: Ident, from_prelude: bool) -> String { + let res = b.res(); + if b.span.is_dummy() { + let add_built_in = match b.res() { + // These already contain the "built-in" prefix or look bad with it. + Res::NonMacroAttr(..) | Res::PrimTy(..) | Res::ToolMod => false, + _ => true, + }; + let (built_in, from) = if from_prelude { + ("", " from prelude") + } else if b.is_extern_crate() + && !b.is_import() + && self.session.opts.externs.get(&ident.as_str()).is_some() + { + ("", " passed with `--extern`") + } else if add_built_in { + (" built-in", "") + } else { + ("", "") + }; + + let article = if built_in.is_empty() { res.article() } else { "a" }; + format!( + "{a}{built_in} {thing}{from}", + a = article, + thing = res.descr(), + built_in = built_in, + from = from + ) + } else { + let introduced = if b.is_import() { "imported" } else { "defined" }; + format!("the {thing} {introduced} here", thing = res.descr(), introduced = introduced) + } + } + + crate fn report_ambiguity_error(&self, ambiguity_error: &AmbiguityError<'_>) { + let AmbiguityError { kind, ident, b1, b2, misc1, misc2 } = *ambiguity_error; + let (b1, b2, misc1, misc2, swapped) = if b2.span.is_dummy() && !b1.span.is_dummy() { + // We have to print the span-less alternative first, otherwise formatting looks bad. + (b2, b1, misc2, misc1, true) + } else { + (b1, b2, misc1, misc2, false) + }; + + let mut err = struct_span_err!( + self.session, + ident.span, + E0659, + "`{ident}` is ambiguous ({why})", + ident = ident, + why = kind.descr() + ); + err.span_label(ident.span, "ambiguous name"); + + let mut could_refer_to = |b: &NameBinding<'_>, misc: AmbiguityErrorMisc, also: &str| { + let what = self.binding_description(b, ident, misc == AmbiguityErrorMisc::FromPrelude); + let note_msg = format!( + "`{ident}` could{also} refer to {what}", + ident = ident, + also = also, + what = what + ); + + let thing = b.res().descr(); + let mut help_msgs = Vec::new(); + if b.is_glob_import() + && (kind == AmbiguityKind::GlobVsGlob + || kind == AmbiguityKind::GlobVsExpanded + || kind == AmbiguityKind::GlobVsOuter && swapped != also.is_empty()) + { + help_msgs.push(format!( + "consider adding an explicit import of \ + `{ident}` to disambiguate", + ident = ident + )) + } + if b.is_extern_crate() && ident.span.rust_2018() { + help_msgs.push(format!( + "use `::{ident}` to refer to this {thing} unambiguously", + ident = ident, + thing = thing, + )) + } + if misc == AmbiguityErrorMisc::SuggestCrate { + help_msgs.push(format!( + "use `crate::{ident}` to refer to this {thing} unambiguously", + ident = ident, + thing = thing, + )) + } else if misc == AmbiguityErrorMisc::SuggestSelf { + help_msgs.push(format!( + "use `self::{ident}` to refer to this {thing} unambiguously", + ident = ident, + thing = thing, + )) + } + + err.span_note(b.span, ¬e_msg); + for (i, help_msg) in help_msgs.iter().enumerate() { + let or = if i == 0 { "" } else { "or " }; + err.help(&format!("{}{}", or, help_msg)); + } + }; + + could_refer_to(b1, misc1, ""); + could_refer_to(b2, misc2, " also"); + err.emit(); + } + + crate fn report_privacy_error(&self, privacy_error: &PrivacyError<'_>) { + let PrivacyError { ident, binding, .. } = *privacy_error; + let session = &self.session; + let mk_struct_span_error = |is_constructor| { + struct_span_err!( + session, + ident.span, + E0603, + "{}{} `{}` is private", + binding.res().descr(), + if is_constructor { " constructor" } else { "" }, + ident.name, + ) + }; + + let mut err = if let NameBindingKind::Res( + Res::Def(DefKind::Ctor(CtorOf::Struct, CtorKind::Fn), ctor_def_id), + _, + ) = binding.kind + { + let def_id = (&*self).parent(ctor_def_id).expect("no parent for a constructor"); + if let Some(fields) = self.field_names.get(&def_id) { + let mut err = mk_struct_span_error(true); + let first_field = fields.first().expect("empty field list in the map"); + err.span_label( + fields.iter().fold(first_field.span, |acc, field| acc.to(field.span)), + "a constructor is private if any of the fields is private", + ); + err + } else { + mk_struct_span_error(false) + } + } else { + mk_struct_span_error(false) + }; + + err.emit(); + } } impl<'a, 'b> ImportResolver<'a, 'b> { diff --git a/src/librustc_resolve/imports.rs b/src/librustc_resolve/imports.rs index 5bd10303162b2..9f459834175c1 100644 --- a/src/librustc_resolve/imports.rs +++ b/src/librustc_resolve/imports.rs @@ -319,7 +319,11 @@ impl<'a> Resolver<'a> { // Remove this together with `PUB_USE_OF_PRIVATE_EXTERN_CRATE` !(self.last_import_segment && binding.is_extern_crate()) { - self.privacy_errors.push(PrivacyError(path_span, ident, binding)); + self.privacy_errors.push(PrivacyError { + ident, + binding, + dedup_span: path_span, + }); } Ok(binding) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 8d5afb194a175..60a0049f5da37 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2,12 +2,9 @@ //! //! Module structure of the crate is built here. //! Paths in macros, imports, expressions, types, patterns are resolved here. -//! Label names are resolved here as well. +//! Label and lifetime names are resolved here as well. //! //! Type-relative name resolution (methods, fields, associated items) happens in `librustc_typeck`. -//! Lifetime names are resolved in `librustc/middle/resolve_lifetime.rs`. - -// ignore-tidy-filelength #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(bool_to_option)] @@ -33,7 +30,7 @@ use rustc_data_structures::sync::Lrc; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_expand::base::SyntaxExtension; use rustc_hir::def::Namespace::*; -use rustc_hir::def::{self, CtorKind, CtorOf, DefKind, NonMacroAttrKind, PartialRes}; +use rustc_hir::def::{self, CtorOf, DefKind, NonMacroAttrKind, PartialRes}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_hir::PrimTy::{self, Bool, Char, Float, Int, Str, Uint}; use rustc_hir::{GlobMap, TraitMap}; @@ -604,7 +601,11 @@ impl<'a> NameBindingKind<'a> { } } -struct PrivacyError<'a>(Span, Ident, &'a NameBinding<'a>); +struct PrivacyError<'a> { + ident: Ident, + binding: &'a NameBinding<'a>, + dedup_span: Span, +} struct UseError<'a> { err: DiagnosticBuilder<'a>, @@ -2446,115 +2447,6 @@ impl<'a> Resolver<'a> { } } - fn binding_description(&self, b: &NameBinding<'_>, ident: Ident, from_prelude: bool) -> String { - let res = b.res(); - if b.span.is_dummy() { - let add_built_in = match b.res() { - // These already contain the "built-in" prefix or look bad with it. - Res::NonMacroAttr(..) | Res::PrimTy(..) | Res::ToolMod => false, - _ => true, - }; - let (built_in, from) = if from_prelude { - ("", " from prelude") - } else if b.is_extern_crate() - && !b.is_import() - && self.session.opts.externs.get(&ident.as_str()).is_some() - { - ("", " passed with `--extern`") - } else if add_built_in { - (" built-in", "") - } else { - ("", "") - }; - - let article = if built_in.is_empty() { res.article() } else { "a" }; - format!( - "{a}{built_in} {thing}{from}", - a = article, - thing = res.descr(), - built_in = built_in, - from = from - ) - } else { - let introduced = if b.is_import() { "imported" } else { "defined" }; - format!("the {thing} {introduced} here", thing = res.descr(), introduced = introduced) - } - } - - fn report_ambiguity_error(&self, ambiguity_error: &AmbiguityError<'_>) { - let AmbiguityError { kind, ident, b1, b2, misc1, misc2 } = *ambiguity_error; - let (b1, b2, misc1, misc2, swapped) = if b2.span.is_dummy() && !b1.span.is_dummy() { - // We have to print the span-less alternative first, otherwise formatting looks bad. - (b2, b1, misc2, misc1, true) - } else { - (b1, b2, misc1, misc2, false) - }; - - let mut err = struct_span_err!( - self.session, - ident.span, - E0659, - "`{ident}` is ambiguous ({why})", - ident = ident, - why = kind.descr() - ); - err.span_label(ident.span, "ambiguous name"); - - let mut could_refer_to = |b: &NameBinding<'_>, misc: AmbiguityErrorMisc, also: &str| { - let what = self.binding_description(b, ident, misc == AmbiguityErrorMisc::FromPrelude); - let note_msg = format!( - "`{ident}` could{also} refer to {what}", - ident = ident, - also = also, - what = what - ); - - let thing = b.res().descr(); - let mut help_msgs = Vec::new(); - if b.is_glob_import() - && (kind == AmbiguityKind::GlobVsGlob - || kind == AmbiguityKind::GlobVsExpanded - || kind == AmbiguityKind::GlobVsOuter && swapped != also.is_empty()) - { - help_msgs.push(format!( - "consider adding an explicit import of \ - `{ident}` to disambiguate", - ident = ident - )) - } - if b.is_extern_crate() && ident.span.rust_2018() { - help_msgs.push(format!( - "use `::{ident}` to refer to this {thing} unambiguously", - ident = ident, - thing = thing, - )) - } - if misc == AmbiguityErrorMisc::SuggestCrate { - help_msgs.push(format!( - "use `crate::{ident}` to refer to this {thing} unambiguously", - ident = ident, - thing = thing, - )) - } else if misc == AmbiguityErrorMisc::SuggestSelf { - help_msgs.push(format!( - "use `self::{ident}` to refer to this {thing} unambiguously", - ident = ident, - thing = thing, - )) - } - - err.span_note(b.span, ¬e_msg); - for (i, help_msg) in help_msgs.iter().enumerate() { - let or = if i == 0 { "" } else { "or " }; - err.help(&format!("{}{}", or, help_msg)); - } - }; - - could_refer_to(b1, misc1, ""); - could_refer_to(b2, misc2, " also"); - err.emit(); - } - fn report_errors(&mut self, krate: &Crate) { self.report_with_use_injections(krate); @@ -2575,43 +2467,9 @@ impl<'a> Resolver<'a> { } let mut reported_spans = FxHashSet::default(); - for &PrivacyError(dedup_span, ident, binding) in &self.privacy_errors { - if reported_spans.insert(dedup_span) { - let session = &self.session; - let mk_struct_span_error = |is_constructor| { - struct_span_err!( - session, - ident.span, - E0603, - "{}{} `{}` is private", - binding.res().descr(), - if is_constructor { " constructor" } else { "" }, - ident.name, - ) - }; - - let mut err = if let NameBindingKind::Res( - Res::Def(DefKind::Ctor(CtorOf::Struct, CtorKind::Fn), ctor_def_id), - _, - ) = binding.kind - { - let def_id = (&*self).parent(ctor_def_id).expect("no parent for a constructor"); - if let Some(fields) = self.field_names.get(&def_id) { - let mut err = mk_struct_span_error(true); - let first_field = fields.first().expect("empty field list in the map"); - err.span_label( - fields.iter().fold(first_field.span, |acc, field| acc.to(field.span)), - "a constructor is private if any of the fields is private", - ); - err - } else { - mk_struct_span_error(false) - } - } else { - mk_struct_span_error(false) - }; - - err.emit(); + for error in &self.privacy_errors { + if reported_spans.insert(error.dedup_span) { + self.report_privacy_error(error); } } } From 28c3f6eb409596be9c0c0a59dc1c26e216d9e57a Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 12 Jan 2020 16:04:03 +0300 Subject: [PATCH 123/169] resolve: Point at the private item definitions in privacy errors --- src/librustc_resolve/diagnostics.rs | 24 +- src/test/ui/error-codes/E0603.stderr | 8 +- src/test/ui/error-festival.stderr | 8 +- src/test/ui/export-import.stderr | 8 +- src/test/ui/export-tag-variant.stderr | 8 +- src/test/ui/export.stderr | 8 +- .../ui/extern/extern-crate-visibility.stderr | 16 +- src/test/ui/hygiene/privacy.stderr | 8 +- src/test/ui/import.stderr | 8 +- src/test/ui/imports/issue-55884-2.stderr | 8 +- src/test/ui/imports/reexports.stderr | 16 +- .../ui/imports/unresolved-imports-used.stderr | 8 +- src/test/ui/issues/issue-10545.stderr | 8 +- src/test/ui/issues/issue-11593.stderr | 8 +- src/test/ui/issues/issue-11680.stderr | 16 +- src/test/ui/issues/issue-13407.stderr | 8 +- src/test/ui/issues/issue-13641.stderr | 16 +- src/test/ui/issues/issue-16725.stderr | 8 +- .../issues/issue-17718-const-privacy.stderr | 16 +- src/test/ui/issues/issue-28388-2.stderr | 8 +- src/test/ui/issues/issue-29161.stderr | 8 +- src/test/ui/issues/issue-38857.stderr | 8 +- src/test/ui/issues/issue-3993.stderr | 8 +- .../macros/macro-local-data-key-priv.stderr | 9 +- .../ui/parser/macro/pub-item-macro.stderr | 11 +- src/test/ui/privacy/decl-macro.stderr | 8 +- src/test/ui/privacy/privacy-in-paths.stderr | 24 +- src/test/ui/privacy/privacy-ns2.stderr | 24 +- src/test/ui/privacy/privacy-ufcs.stderr | 8 +- src/test/ui/privacy/privacy1.stderr | 104 ++++- src/test/ui/privacy/privacy2.stderr | 8 +- src/test/ui/privacy/privacy4.stderr | 8 +- src/test/ui/privacy/privacy5.stderr | 384 +++++++++++++++--- .../ui/privacy/private-item-simple.stderr | 8 +- src/test/ui/privacy/restricted/test.stderr | 16 +- .../proc-macro/disappearing-resolution.stderr | 8 +- .../ui/reachable/unreachable-variant.stderr | 8 +- src/test/ui/resolve/privacy-enum-ctor.stderr | 32 +- .../ui/resolve/privacy-struct-ctor.stderr | 48 ++- .../ui/rfc-2008-non-exhaustive/struct.stderr | 16 +- .../ui/rfc-2008-non-exhaustive/variant.stderr | 40 +- .../shadowed/shadowed-use-visibility.stderr | 16 +- .../ui/stability-in-private-module.stderr | 8 +- .../ui/static/static-priv-by-default2.stderr | 16 +- .../structs/struct-variant-privacy-xc.stderr | 16 +- .../ui/structs/struct-variant-privacy.stderr | 16 +- src/test/ui/use/use-from-trait-xc.stderr | 16 +- src/test/ui/use/use-mod/use-mod-3.stderr | 16 +- .../xcrate/xcrate-private-by-default.stderr | 80 +++- 49 files changed, 1034 insertions(+), 154 deletions(-) diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index f83daa1636752..20c8f78b1cf0e 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -917,15 +917,21 @@ impl<'a> Resolver<'a> { let PrivacyError { ident, binding, .. } = *privacy_error; let session = &self.session; let mk_struct_span_error = |is_constructor| { - struct_span_err!( - session, - ident.span, - E0603, - "{}{} `{}` is private", - binding.res().descr(), - if is_constructor { " constructor" } else { "" }, - ident.name, - ) + let mut descr = binding.res().descr().to_string(); + if is_constructor { + descr += " constructor"; + } + + let mut err = + struct_span_err!(session, ident.span, E0603, "{} `{}` is private", descr, ident); + + err.span_label(ident.span, &format!("this {} is private", descr)); + err.span_note( + session.source_map().def_span(binding.span), + &format!("the {} `{}` is defined here", descr, ident), + ); + + err }; let mut err = if let NameBindingKind::Res( diff --git a/src/test/ui/error-codes/E0603.stderr b/src/test/ui/error-codes/E0603.stderr index 444005e086f1b..724d04954a3c7 100644 --- a/src/test/ui/error-codes/E0603.stderr +++ b/src/test/ui/error-codes/E0603.stderr @@ -2,7 +2,13 @@ error[E0603]: constant `PRIVATE` is private --> $DIR/E0603.rs:6:17 | LL | SomeModule::PRIVATE; - | ^^^^^^^ + | ^^^^^^^ this constant is private + | +note: the constant `PRIVATE` is defined here + --> $DIR/E0603.rs:2:5 + | +LL | const PRIVATE: u32 = 0x_a_bad_1dea_u32; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/error-festival.stderr b/src/test/ui/error-festival.stderr index 6b80d99b3afe9..9b69b3733642b 100644 --- a/src/test/ui/error-festival.stderr +++ b/src/test/ui/error-festival.stderr @@ -8,7 +8,13 @@ error[E0603]: constant `FOO` is private --> $DIR/error-festival.rs:22:10 | LL | foo::FOO; - | ^^^ + | ^^^ this constant is private + | +note: the constant `FOO` is defined here + --> $DIR/error-festival.rs:7:5 + | +LL | const FOO: u32 = 0; + | ^^^^^^^^^^^^^^^^^^^ error[E0368]: binary assignment operation `+=` cannot be applied to type `&str` --> $DIR/error-festival.rs:12:5 diff --git a/src/test/ui/export-import.stderr b/src/test/ui/export-import.stderr index e02952e0fe092..8160775ab589e 100644 --- a/src/test/ui/export-import.stderr +++ b/src/test/ui/export-import.stderr @@ -2,7 +2,13 @@ error[E0603]: function `unexported` is private --> $DIR/export-import.rs:1:8 | LL | use m::unexported; - | ^^^^^^^^^^ + | ^^^^^^^^^^ this function is private + | +note: the function `unexported` is defined here + --> $DIR/export-import.rs:7:5 + | +LL | fn unexported() { } + | ^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/export-tag-variant.stderr b/src/test/ui/export-tag-variant.stderr index b5a2c12c436d0..f4537a2fb6fae 100644 --- a/src/test/ui/export-tag-variant.stderr +++ b/src/test/ui/export-tag-variant.stderr @@ -2,7 +2,13 @@ error[E0603]: enum `Y` is private --> $DIR/export-tag-variant.rs:7:26 | LL | fn main() { let z = foo::Y::Y1; } - | ^ + | ^ this enum is private + | +note: the enum `Y` is defined here + --> $DIR/export-tag-variant.rs:4:5 + | +LL | enum Y { Y1 } + | ^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/export.stderr b/src/test/ui/export.stderr index a3668a502cdd4..107f531c09a3a 100644 --- a/src/test/ui/export.stderr +++ b/src/test/ui/export.stderr @@ -26,7 +26,13 @@ error[E0603]: function `z` is private --> $DIR/export.rs:10:18 | LL | fn main() { foo::z(10); } - | ^ + | ^ this function is private + | +note: the function `z` is defined here + --> $DIR/export.rs:5:5 + | +LL | fn z(y: isize) { log(debug, y); } + | ^^^^^^^^^^^^^^ error: aborting due to 5 previous errors diff --git a/src/test/ui/extern/extern-crate-visibility.stderr b/src/test/ui/extern/extern-crate-visibility.stderr index 38c791ab83237..6d38b4d8d66d6 100644 --- a/src/test/ui/extern/extern-crate-visibility.stderr +++ b/src/test/ui/extern/extern-crate-visibility.stderr @@ -2,13 +2,25 @@ error[E0603]: crate `core` is private --> $DIR/extern-crate-visibility.rs:6:10 | LL | use foo::core::cell; - | ^^^^ + | ^^^^ this crate is private + | +note: the crate `core` is defined here + --> $DIR/extern-crate-visibility.rs:2:5 + | +LL | extern crate core; + | ^^^^^^^^^^^^^^^^^^ error[E0603]: crate `core` is private --> $DIR/extern-crate-visibility.rs:9:10 | LL | foo::core::cell::Cell::new(0); - | ^^^^ + | ^^^^ this crate is private + | +note: the crate `core` is defined here + --> $DIR/extern-crate-visibility.rs:2:5 + | +LL | extern crate core; + | ^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/hygiene/privacy.stderr b/src/test/ui/hygiene/privacy.stderr index 80fb4dd0f314a..0649dc0ec5836 100644 --- a/src/test/ui/hygiene/privacy.stderr +++ b/src/test/ui/hygiene/privacy.stderr @@ -2,7 +2,13 @@ error[E0603]: function `f` is private --> $DIR/privacy.rs:16:14 | LL | foo::f() - | ^ + | ^ this function is private + | +note: the function `f` is defined here + --> $DIR/privacy.rs:4:5 + | +LL | fn f() {} + | ^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/import.stderr b/src/test/ui/import.stderr index 6b320b198a0b1..c66a4fa7151dc 100644 --- a/src/test/ui/import.stderr +++ b/src/test/ui/import.stderr @@ -17,7 +17,13 @@ error[E0603]: unresolved item `foo` is private --> $DIR/import.rs:15:10 | LL | zed::foo(); - | ^^^ + | ^^^ this unresolved item is private + | +note: the unresolved item `foo` is defined here + --> $DIR/import.rs:10:9 + | +LL | use foo; + | ^^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/imports/issue-55884-2.stderr b/src/test/ui/imports/issue-55884-2.stderr index d3b43783ee9c8..9e77283cd5946 100644 --- a/src/test/ui/imports/issue-55884-2.stderr +++ b/src/test/ui/imports/issue-55884-2.stderr @@ -2,7 +2,13 @@ error[E0603]: struct `ParseOptions` is private --> $DIR/issue-55884-2.rs:12:17 | LL | pub use parser::ParseOptions; - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ this struct is private + | +note: the struct `ParseOptions` is defined here + --> $DIR/issue-55884-2.rs:9:9 + | +LL | use ParseOptions; + | ^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/imports/reexports.stderr b/src/test/ui/imports/reexports.stderr index 4388e2c276b8e..67c12e0c8d3ca 100644 --- a/src/test/ui/imports/reexports.stderr +++ b/src/test/ui/imports/reexports.stderr @@ -14,13 +14,25 @@ error[E0603]: module `foo` is private --> $DIR/reexports.rs:33:15 | LL | use b::a::foo::S; - | ^^^ + | ^^^ this module is private + | +note: the module `foo` is defined here + --> $DIR/reexports.rs:21:17 + | +LL | pub use super::foo; // This is OK since the value `foo` is visible enough. + | ^^^^^^^^^^ error[E0603]: module `foo` is private --> $DIR/reexports.rs:34:15 | LL | use b::b::foo::S as T; - | ^^^ + | ^^^ this module is private + | +note: the module `foo` is defined here + --> $DIR/reexports.rs:26:17 + | +LL | pub use super::*; // This is also OK since the value `foo` is visible enough. + | ^^^^^^^^ warning: glob import doesn't reexport anything because no candidate is public enough --> $DIR/reexports.rs:9:17 diff --git a/src/test/ui/imports/unresolved-imports-used.stderr b/src/test/ui/imports/unresolved-imports-used.stderr index b341e8e059288..d7280d2583a76 100644 --- a/src/test/ui/imports/unresolved-imports-used.stderr +++ b/src/test/ui/imports/unresolved-imports-used.stderr @@ -38,7 +38,13 @@ error[E0603]: function `quz` is private --> $DIR/unresolved-imports-used.rs:9:10 | LL | use qux::quz; - | ^^^ + | ^^^ this function is private + | +note: the function `quz` is defined here + --> $DIR/unresolved-imports-used.rs:5:4 + | +LL | fn quz() {} + | ^^^^^^^^ error: unused import: `qux::quy` --> $DIR/unresolved-imports-used.rs:16:5 diff --git a/src/test/ui/issues/issue-10545.stderr b/src/test/ui/issues/issue-10545.stderr index 59d4fedcd2b40..4ed7028c0a06b 100644 --- a/src/test/ui/issues/issue-10545.stderr +++ b/src/test/ui/issues/issue-10545.stderr @@ -2,7 +2,13 @@ error[E0603]: struct `S` is private --> $DIR/issue-10545.rs:6:14 | LL | fn foo(_: a::S) { - | ^ + | ^ this struct is private + | +note: the struct `S` is defined here + --> $DIR/issue-10545.rs:2:5 + | +LL | struct S; + | ^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-11593.stderr b/src/test/ui/issues/issue-11593.stderr index c3e4412b042d7..bfb4d31323b13 100644 --- a/src/test/ui/issues/issue-11593.stderr +++ b/src/test/ui/issues/issue-11593.stderr @@ -2,7 +2,13 @@ error[E0603]: trait `Foo` is private --> $DIR/issue-11593.rs:7:24 | LL | impl private_trait_xc::Foo for Bar {} - | ^^^ + | ^^^ this trait is private + | +note: the trait `Foo` is defined here + --> $DIR/auxiliary/private-trait-xc.rs:1:1 + | +LL | trait Foo {} + | ^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-11680.stderr b/src/test/ui/issues/issue-11680.stderr index 35cb2476992ac..898ac10f7d9a9 100644 --- a/src/test/ui/issues/issue-11680.stderr +++ b/src/test/ui/issues/issue-11680.stderr @@ -2,13 +2,25 @@ error[E0603]: enum `Foo` is private --> $DIR/issue-11680.rs:6:21 | LL | let _b = other::Foo::Bar(1); - | ^^^ + | ^^^ this enum is private + | +note: the enum `Foo` is defined here + --> $DIR/auxiliary/issue-11680.rs:1:1 + | +LL | enum Foo { + | ^^^^^^^^ error[E0603]: enum `Foo` is private --> $DIR/issue-11680.rs:9:27 | LL | let _b = other::test::Foo::Bar(1); - | ^^^ + | ^^^ this enum is private + | +note: the enum `Foo` is defined here + --> $DIR/auxiliary/issue-11680.rs:6:5 + | +LL | enum Foo { + | ^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-13407.stderr b/src/test/ui/issues/issue-13407.stderr index b280de3158fed..f211d623ab12b 100644 --- a/src/test/ui/issues/issue-13407.stderr +++ b/src/test/ui/issues/issue-13407.stderr @@ -2,7 +2,13 @@ error[E0603]: unit struct `C` is private --> $DIR/issue-13407.rs:6:8 | LL | A::C = 1; - | ^ + | ^ this unit struct is private + | +note: the unit struct `C` is defined here + --> $DIR/issue-13407.rs:2:5 + | +LL | struct C; + | ^^^^^^^^^ error[E0308]: mismatched types --> $DIR/issue-13407.rs:6:12 diff --git a/src/test/ui/issues/issue-13641.stderr b/src/test/ui/issues/issue-13641.stderr index 8e5001e3b694d..f90cb18b6fc9d 100644 --- a/src/test/ui/issues/issue-13641.stderr +++ b/src/test/ui/issues/issue-13641.stderr @@ -2,13 +2,25 @@ error[E0603]: struct `Foo` is private --> $DIR/issue-13641.rs:9:8 | LL | a::Foo::new(); - | ^^^ + | ^^^ this struct is private + | +note: the struct `Foo` is defined here + --> $DIR/issue-13641.rs:2:5 + | +LL | struct Foo; + | ^^^^^^^^^^^ error[E0603]: enum `Bar` is private --> $DIR/issue-13641.rs:11:8 | LL | a::Bar::new(); - | ^^^ + | ^^^ this enum is private + | +note: the enum `Bar` is defined here + --> $DIR/issue-13641.rs:4:5 + | +LL | enum Bar {} + | ^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-16725.stderr b/src/test/ui/issues/issue-16725.stderr index 562ad940423c2..e0a1ca8a5ac31 100644 --- a/src/test/ui/issues/issue-16725.stderr +++ b/src/test/ui/issues/issue-16725.stderr @@ -2,7 +2,13 @@ error[E0603]: function `bar` is private --> $DIR/issue-16725.rs:6:19 | LL | unsafe { foo::bar(); } - | ^^^ + | ^^^ this function is private + | +note: the function `bar` is defined here + --> $DIR/auxiliary/issue-16725.rs:2:5 + | +LL | fn bar(); + | ^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-17718-const-privacy.stderr b/src/test/ui/issues/issue-17718-const-privacy.stderr index 0b0de8a52590b..07d825ba9cb3b 100644 --- a/src/test/ui/issues/issue-17718-const-privacy.stderr +++ b/src/test/ui/issues/issue-17718-const-privacy.stderr @@ -2,13 +2,25 @@ error[E0603]: constant `B` is private --> $DIR/issue-17718-const-privacy.rs:5:8 | LL | use a::B; - | ^ + | ^ this constant is private + | +note: the constant `B` is defined here + --> $DIR/issue-17718-const-privacy.rs:13:5 + | +LL | const B: usize = 3; + | ^^^^^^^^^^^^^^^^^^^ error[E0603]: constant `BAR` is private --> $DIR/issue-17718-const-privacy.rs:8:5 | LL | BAR, - | ^^^ + | ^^^ this constant is private + | +note: the constant `BAR` is defined here + --> $DIR/auxiliary/issue-17718-const-privacy.rs:4:1 + | +LL | const BAR: usize = 3; + | ^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-28388-2.stderr b/src/test/ui/issues/issue-28388-2.stderr index 7bbe0bc5ff154..58bd775f295fc 100644 --- a/src/test/ui/issues/issue-28388-2.stderr +++ b/src/test/ui/issues/issue-28388-2.stderr @@ -2,7 +2,13 @@ error[E0603]: module `n` is private --> $DIR/issue-28388-2.rs:7:8 | LL | use m::n::{}; - | ^ + | ^ this module is private + | +note: the module `n` is defined here + --> $DIR/issue-28388-2.rs:4:5 + | +LL | mod n {} + | ^^^^^ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-29161.stderr b/src/test/ui/issues/issue-29161.stderr index d30fd28a4a351..1bfa211ef7962 100644 --- a/src/test/ui/issues/issue-29161.stderr +++ b/src/test/ui/issues/issue-29161.stderr @@ -8,7 +8,13 @@ error[E0603]: struct `A` is private --> $DIR/issue-29161.rs:13:8 | LL | a::A::default(); - | ^ + | ^ this struct is private + | +note: the struct `A` is defined here + --> $DIR/issue-29161.rs:2:5 + | +LL | struct A; + | ^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-38857.stderr b/src/test/ui/issues/issue-38857.stderr index 5762e3d6ac00a..dd7970e014fdb 100644 --- a/src/test/ui/issues/issue-38857.stderr +++ b/src/test/ui/issues/issue-38857.stderr @@ -8,7 +8,13 @@ error[E0603]: module `sys` is private --> $DIR/issue-38857.rs:2:18 | LL | let a = std::sys::imp::process::process_common::StdioPipes { ..panic!() }; - | ^^^ + | ^^^ this module is private + | +note: the module `sys` is defined here + --> $SRC_DIR/libstd/lib.rs:LL:COL + | +LL | mod sys; + | ^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-3993.stderr b/src/test/ui/issues/issue-3993.stderr index ce594a3f9bb27..3fa8ed4af28fa 100644 --- a/src/test/ui/issues/issue-3993.stderr +++ b/src/test/ui/issues/issue-3993.stderr @@ -2,7 +2,13 @@ error[E0603]: function `fly` is private --> $DIR/issue-3993.rs:1:10 | LL | use zoo::fly; - | ^^^ + | ^^^ this function is private + | +note: the function `fly` is defined here + --> $DIR/issue-3993.rs:4:5 + | +LL | fn fly() {} + | ^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/macros/macro-local-data-key-priv.stderr b/src/test/ui/macros/macro-local-data-key-priv.stderr index 9b44421808e88..72994d1652cd0 100644 --- a/src/test/ui/macros/macro-local-data-key-priv.stderr +++ b/src/test/ui/macros/macro-local-data-key-priv.stderr @@ -2,7 +2,14 @@ error[E0603]: constant `baz` is private --> $DIR/macro-local-data-key-priv.rs:8:10 | LL | bar::baz.with(|_| ()); - | ^^^ + | ^^^ this constant is private + | +note: the constant `baz` is defined here + --> $DIR/macro-local-data-key-priv.rs:4:5 + | +LL | thread_local!(static baz: f64 = 0.0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/parser/macro/pub-item-macro.stderr b/src/test/ui/parser/macro/pub-item-macro.stderr index fa25161ab50b2..ae981ac4cbee3 100644 --- a/src/test/ui/parser/macro/pub-item-macro.stderr +++ b/src/test/ui/parser/macro/pub-item-macro.stderr @@ -13,7 +13,16 @@ error[E0603]: static `x` is private --> $DIR/pub-item-macro.rs:17:23 | LL | let y: u32 = foo::x; - | ^ + | ^ this static is private + | +note: the static `x` is defined here + --> $DIR/pub-item-macro.rs:4:5 + | +LL | static x: u32 = 0; + | ^^^^^^^^^^^^^^^^^^ +... +LL | pub_x!(); + | --------- in this macro invocation error: aborting due to 2 previous errors diff --git a/src/test/ui/privacy/decl-macro.stderr b/src/test/ui/privacy/decl-macro.stderr index 230cf95de6206..ae2e1b4b644a3 100644 --- a/src/test/ui/privacy/decl-macro.stderr +++ b/src/test/ui/privacy/decl-macro.stderr @@ -2,7 +2,13 @@ error[E0603]: macro `mac` is private --> $DIR/decl-macro.rs:8:8 | LL | m::mac!(); - | ^^^ + | ^^^ this macro is private + | +note: the macro `mac` is defined here + --> $DIR/decl-macro.rs:4:5 + | +LL | macro mac() {} + | ^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/privacy/privacy-in-paths.stderr b/src/test/ui/privacy/privacy-in-paths.stderr index 4b9faca045709..8860d8f15f748 100644 --- a/src/test/ui/privacy/privacy-in-paths.stderr +++ b/src/test/ui/privacy/privacy-in-paths.stderr @@ -2,19 +2,37 @@ error[E0603]: module `bar` is private --> $DIR/privacy-in-paths.rs:24:16 | LL | ::foo::bar::baz::f(); - | ^^^ + | ^^^ this module is private + | +note: the module `bar` is defined here + --> $DIR/privacy-in-paths.rs:3:5 + | +LL | mod bar { + | ^^^^^^^ error[E0603]: module `bar` is private --> $DIR/privacy-in-paths.rs:25:16 | LL | ::foo::bar::S::f(); - | ^^^ + | ^^^ this module is private + | +note: the module `bar` is defined here + --> $DIR/privacy-in-paths.rs:3:5 + | +LL | mod bar { + | ^^^^^^^ error[E0603]: trait `T` is private --> $DIR/privacy-in-paths.rs:26:23 | LL | <() as ::foo::T>::Assoc::f(); - | ^ + | ^ this trait is private + | +note: the trait `T` is defined here + --> $DIR/privacy-in-paths.rs:8:5 + | +LL | trait T { + | ^^^^^^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/privacy/privacy-ns2.stderr b/src/test/ui/privacy/privacy-ns2.stderr index 2871573130a60..8b12109b37307 100644 --- a/src/test/ui/privacy/privacy-ns2.stderr +++ b/src/test/ui/privacy/privacy-ns2.stderr @@ -58,19 +58,37 @@ error[E0603]: trait `Bar` is private --> $DIR/privacy-ns2.rs:63:15 | LL | use foo3::Bar; - | ^^^ + | ^^^ this trait is private + | +note: the trait `Bar` is defined here + --> $DIR/privacy-ns2.rs:55:5 + | +LL | trait Bar { + | ^^^^^^^^^ error[E0603]: trait `Bar` is private --> $DIR/privacy-ns2.rs:67:15 | LL | use foo3::Bar; - | ^^^ + | ^^^ this trait is private + | +note: the trait `Bar` is defined here + --> $DIR/privacy-ns2.rs:55:5 + | +LL | trait Bar { + | ^^^^^^^^^ error[E0603]: trait `Bar` is private --> $DIR/privacy-ns2.rs:74:16 | LL | use foo3::{Bar,Baz}; - | ^^^ + | ^^^ this trait is private + | +note: the trait `Bar` is defined here + --> $DIR/privacy-ns2.rs:55:5 + | +LL | trait Bar { + | ^^^^^^^^^ error[E0107]: wrong number of const arguments: expected 0, found 1 --> $DIR/privacy-ns2.rs:41:18 diff --git a/src/test/ui/privacy/privacy-ufcs.stderr b/src/test/ui/privacy/privacy-ufcs.stderr index 6be14df89d20a..08640b802a244 100644 --- a/src/test/ui/privacy/privacy-ufcs.stderr +++ b/src/test/ui/privacy/privacy-ufcs.stderr @@ -2,7 +2,13 @@ error[E0603]: trait `Bar` is private --> $DIR/privacy-ufcs.rs:12:20 | LL | ::baz(); - | ^^^ + | ^^^ this trait is private + | +note: the trait `Bar` is defined here + --> $DIR/privacy-ufcs.rs:4:5 + | +LL | trait Bar { + | ^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/privacy/privacy1.stderr b/src/test/ui/privacy/privacy1.stderr index 29f53cd0e3545..215df0dc75441 100644 --- a/src/test/ui/privacy/privacy1.stderr +++ b/src/test/ui/privacy/privacy1.stderr @@ -2,79 +2,157 @@ error[E0603]: module `baz` is private --> $DIR/privacy1.rs:132:18 | LL | use bar::baz::{foo, bar}; - | ^^^ + | ^^^ this module is private + | +note: the module `baz` is defined here + --> $DIR/privacy1.rs:50:5 + | +LL | mod baz { + | ^^^^^^^ error[E0603]: module `baz` is private --> $DIR/privacy1.rs:132:18 | LL | use bar::baz::{foo, bar}; - | ^^^ + | ^^^ this module is private + | +note: the module `baz` is defined here + --> $DIR/privacy1.rs:50:5 + | +LL | mod baz { + | ^^^^^^^ error[E0603]: module `baz` is private --> $DIR/privacy1.rs:141:18 | LL | use bar::baz; - | ^^^ + | ^^^ this module is private + | +note: the module `baz` is defined here + --> $DIR/privacy1.rs:50:5 + | +LL | mod baz { + | ^^^^^^^ error[E0603]: module `i` is private --> $DIR/privacy1.rs:165:20 | LL | use self::foo::i::A; - | ^ + | ^ this module is private + | +note: the module `i` is defined here + --> $DIR/privacy1.rs:170:9 + | +LL | mod i { + | ^^^^^ error[E0603]: module `baz` is private --> $DIR/privacy1.rs:104:16 | LL | ::bar::baz::A::foo(); - | ^^^ + | ^^^ this module is private + | +note: the module `baz` is defined here + --> $DIR/privacy1.rs:50:5 + | +LL | mod baz { + | ^^^^^^^ error[E0603]: module `baz` is private --> $DIR/privacy1.rs:105:16 | LL | ::bar::baz::A::bar(); - | ^^^ + | ^^^ this module is private + | +note: the module `baz` is defined here + --> $DIR/privacy1.rs:50:5 + | +LL | mod baz { + | ^^^^^^^ error[E0603]: module `baz` is private --> $DIR/privacy1.rs:107:16 | LL | ::bar::baz::A.foo2(); - | ^^^ + | ^^^ this module is private + | +note: the module `baz` is defined here + --> $DIR/privacy1.rs:50:5 + | +LL | mod baz { + | ^^^^^^^ error[E0603]: module `baz` is private --> $DIR/privacy1.rs:108:16 | LL | ::bar::baz::A.bar2(); - | ^^^ + | ^^^ this module is private + | +note: the module `baz` is defined here + --> $DIR/privacy1.rs:50:5 + | +LL | mod baz { + | ^^^^^^^ error[E0603]: trait `B` is private --> $DIR/privacy1.rs:112:16 | LL | ::bar::B::foo(); - | ^ + | ^ this trait is private + | +note: the trait `B` is defined here + --> $DIR/privacy1.rs:40:5 + | +LL | trait B { + | ^^^^^^^ error[E0603]: function `epriv` is private --> $DIR/privacy1.rs:118:20 | LL | ::bar::epriv(); - | ^^^^^ + | ^^^^^ this function is private + | +note: the function `epriv` is defined here + --> $DIR/privacy1.rs:65:9 + | +LL | fn epriv(); + | ^^^^^^^^^^^ error[E0603]: module `baz` is private --> $DIR/privacy1.rs:127:16 | LL | ::bar::baz::foo(); - | ^^^ + | ^^^ this module is private + | +note: the module `baz` is defined here + --> $DIR/privacy1.rs:50:5 + | +LL | mod baz { + | ^^^^^^^ error[E0603]: module `baz` is private --> $DIR/privacy1.rs:128:16 | LL | ::bar::baz::bar(); - | ^^^ + | ^^^ this module is private + | +note: the module `baz` is defined here + --> $DIR/privacy1.rs:50:5 + | +LL | mod baz { + | ^^^^^^^ error[E0603]: trait `B` is private --> $DIR/privacy1.rs:157:17 | LL | impl ::bar::B for f32 { fn foo() -> f32 { 1.0 } } - | ^ + | ^ this trait is private + | +note: the trait `B` is defined here + --> $DIR/privacy1.rs:40:5 + | +LL | trait B { + | ^^^^^^^ error[E0624]: method `bar` is private --> $DIR/privacy1.rs:77:9 diff --git a/src/test/ui/privacy/privacy2.stderr b/src/test/ui/privacy/privacy2.stderr index 9f2359657bd7c..d9f003ddae7ac 100644 --- a/src/test/ui/privacy/privacy2.stderr +++ b/src/test/ui/privacy/privacy2.stderr @@ -8,7 +8,13 @@ error[E0603]: function `foo` is private --> $DIR/privacy2.rs:23:20 | LL | use bar::glob::foo; - | ^^^ + | ^^^ this function is private + | +note: the function `foo` is defined here + --> $DIR/privacy2.rs:10:13 + | +LL | use foo; + | ^^^ error: requires `sized` lang_item diff --git a/src/test/ui/privacy/privacy4.stderr b/src/test/ui/privacy/privacy4.stderr index e4a20f920a062..e34b2d5049b9e 100644 --- a/src/test/ui/privacy/privacy4.stderr +++ b/src/test/ui/privacy/privacy4.stderr @@ -2,7 +2,13 @@ error[E0603]: module `glob` is private --> $DIR/privacy4.rs:21:14 | LL | use bar::glob::gpriv; - | ^^^^ + | ^^^^ this module is private + | +note: the module `glob` is defined here + --> $DIR/privacy4.rs:13:5 + | +LL | mod glob { + | ^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/privacy/privacy5.stderr b/src/test/ui/privacy/privacy5.stderr index 2ee83149b695f..197a857cc3dc4 100644 --- a/src/test/ui/privacy/privacy5.stderr +++ b/src/test/ui/privacy/privacy5.stderr @@ -5,7 +5,13 @@ LL | pub struct A(()); | -- a constructor is private if any of the fields is private ... LL | let a = a::A(()); - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `A` is defined here + --> $DIR/privacy5.rs:6:5 + | +LL | pub struct A(()); + | ^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:52:16 @@ -14,7 +20,13 @@ LL | pub struct B(isize); | ----- a constructor is private if any of the fields is private ... LL | let b = a::B(2); - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `B` is defined here + --> $DIR/privacy5.rs:7:5 + | +LL | pub struct B(isize); + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:53:16 @@ -23,7 +35,13 @@ LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private ... LL | let c = a::C(2, 3); - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/privacy5.rs:8:5 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:56:12 @@ -32,7 +50,13 @@ LL | pub struct A(()); | -- a constructor is private if any of the fields is private ... LL | let a::A(()) = a; - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `A` is defined here + --> $DIR/privacy5.rs:6:5 + | +LL | pub struct A(()); + | ^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:57:12 @@ -41,7 +65,13 @@ LL | pub struct A(()); | -- a constructor is private if any of the fields is private ... LL | let a::A(_) = a; - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `A` is defined here + --> $DIR/privacy5.rs:6:5 + | +LL | pub struct A(()); + | ^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:58:18 @@ -50,7 +80,13 @@ LL | pub struct A(()); | -- a constructor is private if any of the fields is private ... LL | match a { a::A(()) => {} } - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `A` is defined here + --> $DIR/privacy5.rs:6:5 + | +LL | pub struct A(()); + | ^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:59:18 @@ -59,7 +95,13 @@ LL | pub struct A(()); | -- a constructor is private if any of the fields is private ... LL | match a { a::A(_) => {} } - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `A` is defined here + --> $DIR/privacy5.rs:6:5 + | +LL | pub struct A(()); + | ^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:61:12 @@ -68,7 +110,13 @@ LL | pub struct B(isize); | ----- a constructor is private if any of the fields is private ... LL | let a::B(_) = b; - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `B` is defined here + --> $DIR/privacy5.rs:7:5 + | +LL | pub struct B(isize); + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:62:12 @@ -77,7 +125,13 @@ LL | pub struct B(isize); | ----- a constructor is private if any of the fields is private ... LL | let a::B(_b) = b; - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `B` is defined here + --> $DIR/privacy5.rs:7:5 + | +LL | pub struct B(isize); + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:63:18 @@ -86,7 +140,13 @@ LL | pub struct B(isize); | ----- a constructor is private if any of the fields is private ... LL | match b { a::B(_) => {} } - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `B` is defined here + --> $DIR/privacy5.rs:7:5 + | +LL | pub struct B(isize); + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:64:18 @@ -95,7 +155,13 @@ LL | pub struct B(isize); | ----- a constructor is private if any of the fields is private ... LL | match b { a::B(_b) => {} } - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `B` is defined here + --> $DIR/privacy5.rs:7:5 + | +LL | pub struct B(isize); + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:65:18 @@ -104,7 +170,13 @@ LL | pub struct B(isize); | ----- a constructor is private if any of the fields is private ... LL | match b { a::B(1) => {} a::B(_) => {} } - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `B` is defined here + --> $DIR/privacy5.rs:7:5 + | +LL | pub struct B(isize); + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:65:32 @@ -113,7 +185,13 @@ LL | pub struct B(isize); | ----- a constructor is private if any of the fields is private ... LL | match b { a::B(1) => {} a::B(_) => {} } - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `B` is defined here + --> $DIR/privacy5.rs:7:5 + | +LL | pub struct B(isize); + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:68:12 @@ -122,7 +200,13 @@ LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private ... LL | let a::C(_, _) = c; - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/privacy5.rs:8:5 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:69:12 @@ -131,7 +215,13 @@ LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private ... LL | let a::C(_a, _) = c; - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/privacy5.rs:8:5 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:70:12 @@ -140,7 +230,13 @@ LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private ... LL | let a::C(_, _b) = c; - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/privacy5.rs:8:5 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:71:12 @@ -149,7 +245,13 @@ LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private ... LL | let a::C(_a, _b) = c; - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/privacy5.rs:8:5 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:72:18 @@ -158,7 +260,13 @@ LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private ... LL | match c { a::C(_, _) => {} } - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/privacy5.rs:8:5 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:73:18 @@ -167,7 +275,13 @@ LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private ... LL | match c { a::C(_a, _) => {} } - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/privacy5.rs:8:5 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:74:18 @@ -176,7 +290,13 @@ LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private ... LL | match c { a::C(_, _b) => {} } - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/privacy5.rs:8:5 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:75:18 @@ -185,7 +305,13 @@ LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private ... LL | match c { a::C(_a, _b) => {} } - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/privacy5.rs:8:5 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:83:17 @@ -194,7 +320,13 @@ LL | pub struct A(()); | -- a constructor is private if any of the fields is private ... LL | let a2 = a::A; - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `A` is defined here + --> $DIR/privacy5.rs:6:5 + | +LL | pub struct A(()); + | ^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:84:17 @@ -203,7 +335,13 @@ LL | pub struct B(isize); | ----- a constructor is private if any of the fields is private ... LL | let b2 = a::B; - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `B` is defined here + --> $DIR/privacy5.rs:7:5 + | +LL | pub struct B(isize); + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:85:17 @@ -212,271 +350,421 @@ LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private ... LL | let c2 = a::C; - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/privacy5.rs:8:5 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:90:20 | LL | let a = other::A(()); - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:1:14 | LL | pub struct A(()); | -- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `A` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:1:1 + | +LL | pub struct A(()); + | ^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:91:20 | LL | let b = other::B(2); - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:2:14 | LL | pub struct B(isize); | ----- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `B` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:2:1 + | +LL | pub struct B(isize); + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:92:20 | LL | let c = other::C(2, 3); - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:3:1 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:95:16 | LL | let other::A(()) = a; - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:1:14 | LL | pub struct A(()); | -- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `A` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:1:1 + | +LL | pub struct A(()); + | ^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:96:16 | LL | let other::A(_) = a; - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:1:14 | LL | pub struct A(()); | -- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `A` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:1:1 + | +LL | pub struct A(()); + | ^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:97:22 | LL | match a { other::A(()) => {} } - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:1:14 | LL | pub struct A(()); | -- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `A` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:1:1 + | +LL | pub struct A(()); + | ^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:98:22 | LL | match a { other::A(_) => {} } - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:1:14 | LL | pub struct A(()); | -- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `A` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:1:1 + | +LL | pub struct A(()); + | ^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:100:16 | LL | let other::B(_) = b; - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:2:14 | LL | pub struct B(isize); | ----- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `B` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:2:1 + | +LL | pub struct B(isize); + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:101:16 | LL | let other::B(_b) = b; - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:2:14 | LL | pub struct B(isize); | ----- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `B` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:2:1 + | +LL | pub struct B(isize); + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:102:22 | LL | match b { other::B(_) => {} } - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:2:14 | LL | pub struct B(isize); | ----- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `B` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:2:1 + | +LL | pub struct B(isize); + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:103:22 | LL | match b { other::B(_b) => {} } - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:2:14 | LL | pub struct B(isize); | ----- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `B` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:2:1 + | +LL | pub struct B(isize); + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:104:22 | LL | match b { other::B(1) => {} - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:2:14 | LL | pub struct B(isize); | ----- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `B` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:2:1 + | +LL | pub struct B(isize); + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:105:16 | LL | other::B(_) => {} } - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:2:14 | LL | pub struct B(isize); | ----- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `B` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:2:1 + | +LL | pub struct B(isize); + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:107:16 | LL | let other::C(_, _) = c; - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:3:1 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:108:16 | LL | let other::C(_a, _) = c; - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:3:1 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:109:16 | LL | let other::C(_, _b) = c; - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:3:1 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:110:16 | LL | let other::C(_a, _b) = c; - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:3:1 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:111:22 | LL | match c { other::C(_, _) => {} } - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:3:1 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:112:22 | LL | match c { other::C(_a, _) => {} } - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:3:1 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:113:22 | LL | match c { other::C(_, _b) => {} } - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:3:1 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:114:22 | LL | match c { other::C(_a, _b) => {} } - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:3:1 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `A` is private --> $DIR/privacy5.rs:122:21 | LL | let a2 = other::A; - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:1:14 | LL | pub struct A(()); | -- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `A` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:1:1 + | +LL | pub struct A(()); + | ^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `B` is private --> $DIR/privacy5.rs:123:21 | LL | let b2 = other::B; - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:2:14 | LL | pub struct B(isize); | ----- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `B` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:2:1 + | +LL | pub struct B(isize); + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `C` is private --> $DIR/privacy5.rs:124:21 | LL | let c2 = other::C; - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy_tuple_struct.rs:3:14 | LL | pub struct C(pub isize, isize); | ---------------- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `C` is defined here + --> $DIR/auxiliary/privacy_tuple_struct.rs:3:1 + | +LL | pub struct C(pub isize, isize); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 48 previous errors diff --git a/src/test/ui/privacy/private-item-simple.stderr b/src/test/ui/privacy/private-item-simple.stderr index 0d5435e1c504b..f51b74f6cb53b 100644 --- a/src/test/ui/privacy/private-item-simple.stderr +++ b/src/test/ui/privacy/private-item-simple.stderr @@ -2,7 +2,13 @@ error[E0603]: function `f` is private --> $DIR/private-item-simple.rs:6:8 | LL | a::f(); - | ^ + | ^ this function is private + | +note: the function `f` is defined here + --> $DIR/private-item-simple.rs:2:5 + | +LL | fn f() {} + | ^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/privacy/restricted/test.stderr b/src/test/ui/privacy/restricted/test.stderr index e6a61fbefb0d8..aac444b8e3c98 100644 --- a/src/test/ui/privacy/restricted/test.stderr +++ b/src/test/ui/privacy/restricted/test.stderr @@ -26,13 +26,25 @@ error[E0603]: struct `Crate` is private --> $DIR/test.rs:38:25 | LL | use pub_restricted::Crate; - | ^^^^^ + | ^^^^^ this struct is private + | +note: the struct `Crate` is defined here + --> $DIR/auxiliary/pub_restricted.rs:3:1 + | +LL | pub(crate) struct Crate; + | ^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: function `f` is private --> $DIR/test.rs:30:19 | LL | use foo::bar::f; - | ^ + | ^ this function is private + | +note: the function `f` is defined here + --> $DIR/test.rs:8:9 + | +LL | pub(super) fn f() {} + | ^^^^^^^^^^^^^^^^^ error[E0616]: field `x` of struct `foo::bar::S` is private --> $DIR/test.rs:31:5 diff --git a/src/test/ui/proc-macro/disappearing-resolution.stderr b/src/test/ui/proc-macro/disappearing-resolution.stderr index a3377ef515f91..d81ab5ebf9bc6 100644 --- a/src/test/ui/proc-macro/disappearing-resolution.stderr +++ b/src/test/ui/proc-macro/disappearing-resolution.stderr @@ -8,7 +8,13 @@ error[E0603]: derive macro `Empty` is private --> $DIR/disappearing-resolution.rs:11:8 | LL | use m::Empty; - | ^^^^^ + | ^^^^^ this derive macro is private + | +note: the derive macro `Empty` is defined here + --> $DIR/disappearing-resolution.rs:9:9 + | +LL | use test_macros::Empty; + | ^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/reachable/unreachable-variant.stderr b/src/test/ui/reachable/unreachable-variant.stderr index 276c77f9b4249..c2e1d774e28ac 100644 --- a/src/test/ui/reachable/unreachable-variant.stderr +++ b/src/test/ui/reachable/unreachable-variant.stderr @@ -2,7 +2,13 @@ error[E0603]: module `super_sekrit` is private --> $DIR/unreachable-variant.rs:6:21 | LL | let _x = other::super_sekrit::sooper_sekrit::baz; - | ^^^^^^^^^^^^ + | ^^^^^^^^^^^^ this module is private + | +note: the module `super_sekrit` is defined here + --> $DIR/auxiliary/unreachable_variant.rs:1:1 + | +LL | mod super_sekrit { + | ^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/resolve/privacy-enum-ctor.stderr b/src/test/ui/resolve/privacy-enum-ctor.stderr index 688720e8cd388..08a1d790197a6 100644 --- a/src/test/ui/resolve/privacy-enum-ctor.stderr +++ b/src/test/ui/resolve/privacy-enum-ctor.stderr @@ -253,25 +253,49 @@ error[E0603]: enum `Z` is private --> $DIR/privacy-enum-ctor.rs:57:22 | LL | let _: Z = m::n::Z; - | ^ + | ^ this enum is private + | +note: the enum `Z` is defined here + --> $DIR/privacy-enum-ctor.rs:11:9 + | +LL | pub(in m) enum Z { + | ^^^^^^^^^^^^^^^^ error[E0603]: enum `Z` is private --> $DIR/privacy-enum-ctor.rs:61:22 | LL | let _: Z = m::n::Z::Fn; - | ^ + | ^ this enum is private + | +note: the enum `Z` is defined here + --> $DIR/privacy-enum-ctor.rs:11:9 + | +LL | pub(in m) enum Z { + | ^^^^^^^^^^^^^^^^ error[E0603]: enum `Z` is private --> $DIR/privacy-enum-ctor.rs:64:22 | LL | let _: Z = m::n::Z::Struct; - | ^ + | ^ this enum is private + | +note: the enum `Z` is defined here + --> $DIR/privacy-enum-ctor.rs:11:9 + | +LL | pub(in m) enum Z { + | ^^^^^^^^^^^^^^^^ error[E0603]: enum `Z` is private --> $DIR/privacy-enum-ctor.rs:68:22 | LL | let _: Z = m::n::Z::Unit {}; - | ^ + | ^ this enum is private + | +note: the enum `Z` is defined here + --> $DIR/privacy-enum-ctor.rs:11:9 + | +LL | pub(in m) enum Z { + | ^^^^^^^^^^^^^^^^ error[E0308]: mismatched types --> $DIR/privacy-enum-ctor.rs:27:20 diff --git a/src/test/ui/resolve/privacy-struct-ctor.stderr b/src/test/ui/resolve/privacy-struct-ctor.stderr index f1a1de4d9c0fd..1673ec46ba488 100644 --- a/src/test/ui/resolve/privacy-struct-ctor.stderr +++ b/src/test/ui/resolve/privacy-struct-ctor.stderr @@ -45,7 +45,13 @@ LL | pub(in m) struct Z(pub(in m::n) u8); | --------------- a constructor is private if any of the fields is private ... LL | n::Z; - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `Z` is defined here + --> $DIR/privacy-struct-ctor.rs:12:9 + | +LL | pub(in m) struct Z(pub(in m::n) u8); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `S` is private --> $DIR/privacy-struct-ctor.rs:29:8 @@ -54,7 +60,13 @@ LL | pub struct S(u8); | -- a constructor is private if any of the fields is private ... LL | m::S; - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `S` is defined here + --> $DIR/privacy-struct-ctor.rs:6:5 + | +LL | pub struct S(u8); + | ^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `S` is private --> $DIR/privacy-struct-ctor.rs:31:19 @@ -63,7 +75,13 @@ LL | pub struct S(u8); | -- a constructor is private if any of the fields is private ... LL | let _: S = m::S(2); - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `S` is defined here + --> $DIR/privacy-struct-ctor.rs:6:5 + | +LL | pub struct S(u8); + | ^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `Z` is private --> $DIR/privacy-struct-ctor.rs:35:11 @@ -72,29 +90,47 @@ LL | pub(in m) struct Z(pub(in m::n) u8); | --------------- a constructor is private if any of the fields is private ... LL | m::n::Z; - | ^ + | ^ this tuple struct constructor is private + | +note: the tuple struct constructor `Z` is defined here + --> $DIR/privacy-struct-ctor.rs:12:9 + | +LL | pub(in m) struct Z(pub(in m::n) u8); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `S` is private --> $DIR/privacy-struct-ctor.rs:41:16 | LL | xcrate::m::S; - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy-struct-ctor.rs:2:18 | LL | pub struct S(u8); | -- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `S` is defined here + --> $DIR/auxiliary/privacy-struct-ctor.rs:2:5 + | +LL | pub struct S(u8); + | ^^^^^^^^^^^^^^^^^ error[E0603]: tuple struct constructor `Z` is private --> $DIR/privacy-struct-ctor.rs:45:19 | LL | xcrate::m::n::Z; - | ^ + | ^ this tuple struct constructor is private | ::: $DIR/auxiliary/privacy-struct-ctor.rs:5:28 | LL | pub(in m) struct Z(pub(in m::n) u8); | --------------- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `Z` is defined here + --> $DIR/auxiliary/privacy-struct-ctor.rs:5:9 + | +LL | pub(in m) struct Z(pub(in m::n) u8); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 10 previous errors diff --git a/src/test/ui/rfc-2008-non-exhaustive/struct.stderr b/src/test/ui/rfc-2008-non-exhaustive/struct.stderr index 944965a15e3d0..f992988c93fcc 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/struct.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/struct.stderr @@ -14,18 +14,30 @@ error[E0603]: tuple struct constructor `TupleStruct` is private --> $DIR/struct.rs:23:32 | LL | let ts_explicit = structs::TupleStruct(640, 480); - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ this tuple struct constructor is private | ::: $DIR/auxiliary/structs.rs:11:24 | LL | pub struct TupleStruct(pub u16, pub u16); | ---------------- a constructor is private if any of the fields is private + | +note: the tuple struct constructor `TupleStruct` is defined here + --> $DIR/auxiliary/structs.rs:11:1 + | +LL | pub struct TupleStruct(pub u16, pub u16); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: unit struct `UnitStruct` is private --> $DIR/struct.rs:32:32 | LL | let us_explicit = structs::UnitStruct; - | ^^^^^^^^^^ + | ^^^^^^^^^^ this unit struct is private + | +note: the unit struct `UnitStruct` is defined here + --> $DIR/auxiliary/structs.rs:8:1 + | +LL | pub struct UnitStruct; + | ^^^^^^^^^^^^^^^^^^^^^^ error[E0639]: cannot create non-exhaustive struct using struct expression --> $DIR/struct.rs:7:14 diff --git a/src/test/ui/rfc-2008-non-exhaustive/variant.stderr b/src/test/ui/rfc-2008-non-exhaustive/variant.stderr index d9d6ea21b8bd4..2a438753a2c70 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/variant.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/variant.stderr @@ -2,31 +2,61 @@ error[E0603]: tuple variant `Tuple` is private --> $DIR/variant.rs:11:48 | LL | let variant_tuple = NonExhaustiveVariants::Tuple(640); - | ^^^^^ + | ^^^^^ this tuple variant is private + | +note: the tuple variant `Tuple` is defined here + --> $DIR/auxiliary/variants.rs:5:23 + | +LL | #[non_exhaustive] Tuple(u32), + | ^^^^^^^^^^ error[E0603]: unit variant `Unit` is private --> $DIR/variant.rs:14:47 | LL | let variant_unit = NonExhaustiveVariants::Unit; - | ^^^^ + | ^^^^ this unit variant is private + | +note: the unit variant `Unit` is defined here + --> $DIR/auxiliary/variants.rs:4:23 + | +LL | #[non_exhaustive] Unit, + | ^^^^ error[E0603]: unit variant `Unit` is private --> $DIR/variant.rs:18:32 | LL | NonExhaustiveVariants::Unit => "", - | ^^^^ + | ^^^^ this unit variant is private + | +note: the unit variant `Unit` is defined here + --> $DIR/auxiliary/variants.rs:4:23 + | +LL | #[non_exhaustive] Unit, + | ^^^^ error[E0603]: tuple variant `Tuple` is private --> $DIR/variant.rs:20:32 | LL | NonExhaustiveVariants::Tuple(fe_tpl) => "", - | ^^^^^ + | ^^^^^ this tuple variant is private + | +note: the tuple variant `Tuple` is defined here + --> $DIR/auxiliary/variants.rs:5:23 + | +LL | #[non_exhaustive] Tuple(u32), + | ^^^^^^^^^^ error[E0603]: tuple variant `Tuple` is private --> $DIR/variant.rs:26:35 | LL | if let NonExhaustiveVariants::Tuple(fe_tpl) = variant_struct { - | ^^^^^ + | ^^^^^ this tuple variant is private + | +note: the tuple variant `Tuple` is defined here + --> $DIR/auxiliary/variants.rs:5:23 + | +LL | #[non_exhaustive] Tuple(u32), + | ^^^^^^^^^^ error[E0639]: cannot create non-exhaustive variant using struct expression --> $DIR/variant.rs:8:26 diff --git a/src/test/ui/shadowed/shadowed-use-visibility.stderr b/src/test/ui/shadowed/shadowed-use-visibility.stderr index 7c66fdf60b1d4..77bf2abe34555 100644 --- a/src/test/ui/shadowed/shadowed-use-visibility.stderr +++ b/src/test/ui/shadowed/shadowed-use-visibility.stderr @@ -2,13 +2,25 @@ error[E0603]: module `bar` is private --> $DIR/shadowed-use-visibility.rs:9:14 | LL | use foo::bar::f as g; - | ^^^ + | ^^^ this module is private + | +note: the module `bar` is defined here + --> $DIR/shadowed-use-visibility.rs:4:9 + | +LL | use foo as bar; + | ^^^^^^^^^^ error[E0603]: module `f` is private --> $DIR/shadowed-use-visibility.rs:15:10 | LL | use bar::f::f; - | ^ + | ^ this module is private + | +note: the module `f` is defined here + --> $DIR/shadowed-use-visibility.rs:11:9 + | +LL | use foo as f; + | ^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/stability-in-private-module.stderr b/src/test/ui/stability-in-private-module.stderr index c3edd62a15eda..537a400664aaa 100644 --- a/src/test/ui/stability-in-private-module.stderr +++ b/src/test/ui/stability-in-private-module.stderr @@ -2,7 +2,13 @@ error[E0603]: module `thread_info` is private --> $DIR/stability-in-private-module.rs:2:26 | LL | let _ = std::thread::thread_info::current_thread(); - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ this module is private + | +note: the module `thread_info` is defined here + --> $SRC_DIR/libstd/thread/mod.rs:LL:COL + | +LL | use crate::sys_common::thread_info; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/static/static-priv-by-default2.stderr b/src/test/ui/static/static-priv-by-default2.stderr index 95bcf07633565..f6cd40412dd84 100644 --- a/src/test/ui/static/static-priv-by-default2.stderr +++ b/src/test/ui/static/static-priv-by-default2.stderr @@ -2,13 +2,25 @@ error[E0603]: static `private` is private --> $DIR/static-priv-by-default2.rs:15:30 | LL | use child::childs_child::private; - | ^^^^^^^ + | ^^^^^^^ this static is private + | +note: the static `private` is defined here + --> $DIR/static-priv-by-default2.rs:7:9 + | +LL | static private: isize = 0; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0603]: static `private` is private --> $DIR/static-priv-by-default2.rs:23:33 | LL | use static_priv_by_default::private; - | ^^^^^^^ + | ^^^^^^^ this static is private + | +note: the static `private` is defined here + --> $DIR/auxiliary/static_priv_by_default.rs:3:1 + | +LL | static private: isize = 0; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/structs/struct-variant-privacy-xc.stderr b/src/test/ui/structs/struct-variant-privacy-xc.stderr index 39241b6b3fc1d..0203b7b5242e5 100644 --- a/src/test/ui/structs/struct-variant-privacy-xc.stderr +++ b/src/test/ui/structs/struct-variant-privacy-xc.stderr @@ -2,13 +2,25 @@ error[E0603]: enum `Bar` is private --> $DIR/struct-variant-privacy-xc.rs:4:33 | LL | fn f(b: struct_variant_privacy::Bar) { - | ^^^ + | ^^^ this enum is private + | +note: the enum `Bar` is defined here + --> $DIR/auxiliary/struct_variant_privacy.rs:1:1 + | +LL | enum Bar { + | ^^^^^^^^ error[E0603]: enum `Bar` is private --> $DIR/struct-variant-privacy-xc.rs:6:33 | LL | struct_variant_privacy::Bar::Baz { a: _a } => {} - | ^^^ + | ^^^ this enum is private + | +note: the enum `Bar` is defined here + --> $DIR/auxiliary/struct_variant_privacy.rs:1:1 + | +LL | enum Bar { + | ^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/structs/struct-variant-privacy.stderr b/src/test/ui/structs/struct-variant-privacy.stderr index 127a650104485..d1b603f9d46fc 100644 --- a/src/test/ui/structs/struct-variant-privacy.stderr +++ b/src/test/ui/structs/struct-variant-privacy.stderr @@ -2,13 +2,25 @@ error[E0603]: enum `Bar` is private --> $DIR/struct-variant-privacy.rs:7:14 | LL | fn f(b: foo::Bar) { - | ^^^ + | ^^^ this enum is private + | +note: the enum `Bar` is defined here + --> $DIR/struct-variant-privacy.rs:2:5 + | +LL | enum Bar { + | ^^^^^^^^ error[E0603]: enum `Bar` is private --> $DIR/struct-variant-privacy.rs:9:14 | LL | foo::Bar::Baz { a: _a } => {} - | ^^^ + | ^^^ this enum is private + | +note: the enum `Bar` is defined here + --> $DIR/struct-variant-privacy.rs:2:5 + | +LL | enum Bar { + | ^^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/use/use-from-trait-xc.stderr b/src/test/ui/use/use-from-trait-xc.stderr index f7438cce22967..3f38a6cae7b81 100644 --- a/src/test/ui/use/use-from-trait-xc.stderr +++ b/src/test/ui/use/use-from-trait-xc.stderr @@ -44,13 +44,25 @@ error[E0603]: struct `Foo` is private --> $DIR/use-from-trait-xc.rs:14:24 | LL | use use_from_trait_xc::Foo::new; - | ^^^ + | ^^^ this struct is private + | +note: the struct `Foo` is defined here + --> $DIR/auxiliary/use-from-trait-xc.rs:9:1 + | +LL | struct Foo; + | ^^^^^^^^^^^ error[E0603]: struct `Foo` is private --> $DIR/use-from-trait-xc.rs:17:24 | LL | use use_from_trait_xc::Foo::C; - | ^^^ + | ^^^ this struct is private + | +note: the struct `Foo` is defined here + --> $DIR/auxiliary/use-from-trait-xc.rs:9:1 + | +LL | struct Foo; + | ^^^^^^^^^^^ error: aborting due to 9 previous errors diff --git a/src/test/ui/use/use-mod/use-mod-3.stderr b/src/test/ui/use/use-mod/use-mod-3.stderr index 0c800ec35e409..4852759286ae6 100644 --- a/src/test/ui/use/use-mod/use-mod-3.stderr +++ b/src/test/ui/use/use-mod/use-mod-3.stderr @@ -2,13 +2,25 @@ error[E0603]: module `bar` is private --> $DIR/use-mod-3.rs:1:10 | LL | use foo::bar::{ - | ^^^ + | ^^^ this module is private + | +note: the module `bar` is defined here + --> $DIR/use-mod-3.rs:9:5 + | +LL | mod bar { pub type Bar = isize; } + | ^^^^^^^ error[E0603]: module `bar` is private --> $DIR/use-mod-3.rs:4:10 | LL | use foo::bar::{ - | ^^^ + | ^^^ this module is private + | +note: the module `bar` is defined here + --> $DIR/use-mod-3.rs:9:5 + | +LL | mod bar { pub type Bar = isize; } + | ^^^^^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/xcrate/xcrate-private-by-default.stderr b/src/test/ui/xcrate/xcrate-private-by-default.stderr index da52b4249e319..842069d6135cb 100644 --- a/src/test/ui/xcrate/xcrate-private-by-default.stderr +++ b/src/test/ui/xcrate/xcrate-private-by-default.stderr @@ -2,61 +2,121 @@ error[E0603]: static `j` is private --> $DIR/xcrate-private-by-default.rs:23:29 | LL | static_priv_by_default::j; - | ^ + | ^ this static is private + | +note: the static `j` is defined here + --> $DIR/auxiliary/static_priv_by_default.rs:47:1 + | +LL | static j: isize = 0; + | ^^^^^^^^^^^^^^^^^^^^ error[E0603]: function `k` is private --> $DIR/xcrate-private-by-default.rs:25:29 | LL | static_priv_by_default::k; - | ^ + | ^ this function is private + | +note: the function `k` is defined here + --> $DIR/auxiliary/static_priv_by_default.rs:48:1 + | +LL | fn k() {} + | ^^^^^^ error[E0603]: unit struct `l` is private --> $DIR/xcrate-private-by-default.rs:27:29 | LL | static_priv_by_default::l; - | ^ + | ^ this unit struct is private + | +note: the unit struct `l` is defined here + --> $DIR/auxiliary/static_priv_by_default.rs:49:1 + | +LL | struct l; + | ^^^^^^^^^ error[E0603]: enum `m` is private --> $DIR/xcrate-private-by-default.rs:29:35 | LL | foo::(); - | ^ + | ^ this enum is private + | +note: the enum `m` is defined here + --> $DIR/auxiliary/static_priv_by_default.rs:50:1 + | +LL | enum m {} + | ^^^^^^ error[E0603]: type alias `n` is private --> $DIR/xcrate-private-by-default.rs:31:35 | LL | foo::(); - | ^ + | ^ this type alias is private + | +note: the type alias `n` is defined here + --> $DIR/auxiliary/static_priv_by_default.rs:51:1 + | +LL | type n = isize; + | ^^^^^^^^^^^^^^^ error[E0603]: module `foo` is private --> $DIR/xcrate-private-by-default.rs:35:29 | LL | static_priv_by_default::foo::a; - | ^^^ + | ^^^ this module is private + | +note: the module `foo` is defined here + --> $DIR/auxiliary/static_priv_by_default.rs:12:1 + | +LL | mod foo { + | ^^^^^^^ error[E0603]: module `foo` is private --> $DIR/xcrate-private-by-default.rs:37:29 | LL | static_priv_by_default::foo::b; - | ^^^ + | ^^^ this module is private + | +note: the module `foo` is defined here + --> $DIR/auxiliary/static_priv_by_default.rs:12:1 + | +LL | mod foo { + | ^^^^^^^ error[E0603]: module `foo` is private --> $DIR/xcrate-private-by-default.rs:39:29 | LL | static_priv_by_default::foo::c; - | ^^^ + | ^^^ this module is private + | +note: the module `foo` is defined here + --> $DIR/auxiliary/static_priv_by_default.rs:12:1 + | +LL | mod foo { + | ^^^^^^^ error[E0603]: module `foo` is private --> $DIR/xcrate-private-by-default.rs:41:35 | LL | foo::(); - | ^^^ + | ^^^ this module is private + | +note: the module `foo` is defined here + --> $DIR/auxiliary/static_priv_by_default.rs:12:1 + | +LL | mod foo { + | ^^^^^^^ error[E0603]: module `foo` is private --> $DIR/xcrate-private-by-default.rs:43:35 | LL | foo::(); - | ^^^ + | ^^^ this module is private + | +note: the module `foo` is defined here + --> $DIR/auxiliary/static_priv_by_default.rs:12:1 + | +LL | mod foo { + | ^^^^^^^ error: aborting due to 10 previous errors From c84efe9b6ca05f64d8b925acc2724971d186f8f6 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 12 Jan 2020 16:20:57 +0300 Subject: [PATCH 124/169] resolve: Say "import" when reporting private imports --- src/librustc_resolve/diagnostics.rs | 3 +++ src/test/ui/extern/extern-crate-visibility.rs | 4 ++-- src/test/ui/extern/extern-crate-visibility.stderr | 12 ++++++------ src/test/ui/import.stderr | 6 +++--- src/test/ui/imports/issue-55884-2.rs | 2 +- src/test/ui/imports/issue-55884-2.stderr | 6 +++--- src/test/ui/imports/reexports.stderr | 12 ++++++------ src/test/ui/privacy/privacy2.stderr | 6 +++--- src/test/ui/proc-macro/disappearing-resolution.rs | 2 +- .../ui/proc-macro/disappearing-resolution.stderr | 6 +++--- src/test/ui/shadowed/shadowed-use-visibility.rs | 4 ++-- src/test/ui/shadowed/shadowed-use-visibility.stderr | 12 ++++++------ 12 files changed, 39 insertions(+), 36 deletions(-) diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 20c8f78b1cf0e..a433ae8ed676a 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -921,6 +921,9 @@ impl<'a> Resolver<'a> { if is_constructor { descr += " constructor"; } + if binding.is_import() { + descr += " import"; + } let mut err = struct_span_err!(session, ident.span, E0603, "{} `{}` is private", descr, ident); diff --git a/src/test/ui/extern/extern-crate-visibility.rs b/src/test/ui/extern/extern-crate-visibility.rs index e0a5cd5e98f4b..cda1227cc8e92 100644 --- a/src/test/ui/extern/extern-crate-visibility.rs +++ b/src/test/ui/extern/extern-crate-visibility.rs @@ -3,10 +3,10 @@ mod foo { } // Check that private crates can be used from outside their modules, albeit with warnings -use foo::core::cell; //~ ERROR crate `core` is private +use foo::core::cell; //~ ERROR crate import `core` is private fn f() { - foo::core::cell::Cell::new(0); //~ ERROR crate `core` is private + foo::core::cell::Cell::new(0); //~ ERROR crate import `core` is private use foo::*; mod core {} // Check that private crates are not glob imported diff --git a/src/test/ui/extern/extern-crate-visibility.stderr b/src/test/ui/extern/extern-crate-visibility.stderr index 6d38b4d8d66d6..d0c073d67a4ee 100644 --- a/src/test/ui/extern/extern-crate-visibility.stderr +++ b/src/test/ui/extern/extern-crate-visibility.stderr @@ -1,22 +1,22 @@ -error[E0603]: crate `core` is private +error[E0603]: crate import `core` is private --> $DIR/extern-crate-visibility.rs:6:10 | LL | use foo::core::cell; - | ^^^^ this crate is private + | ^^^^ this crate import is private | -note: the crate `core` is defined here +note: the crate import `core` is defined here --> $DIR/extern-crate-visibility.rs:2:5 | LL | extern crate core; | ^^^^^^^^^^^^^^^^^^ -error[E0603]: crate `core` is private +error[E0603]: crate import `core` is private --> $DIR/extern-crate-visibility.rs:9:10 | LL | foo::core::cell::Cell::new(0); - | ^^^^ this crate is private + | ^^^^ this crate import is private | -note: the crate `core` is defined here +note: the crate import `core` is defined here --> $DIR/extern-crate-visibility.rs:2:5 | LL | extern crate core; diff --git a/src/test/ui/import.stderr b/src/test/ui/import.stderr index c66a4fa7151dc..5219ffacd15c0 100644 --- a/src/test/ui/import.stderr +++ b/src/test/ui/import.stderr @@ -13,13 +13,13 @@ error[E0432]: unresolved import `foo` LL | use foo; | ^^^ no `foo` in the root -error[E0603]: unresolved item `foo` is private +error[E0603]: unresolved item import `foo` is private --> $DIR/import.rs:15:10 | LL | zed::foo(); - | ^^^ this unresolved item is private + | ^^^ this unresolved item import is private | -note: the unresolved item `foo` is defined here +note: the unresolved item import `foo` is defined here --> $DIR/import.rs:10:9 | LL | use foo; diff --git a/src/test/ui/imports/issue-55884-2.rs b/src/test/ui/imports/issue-55884-2.rs index 1b4f652c9fc2f..75bb4206f97d6 100644 --- a/src/test/ui/imports/issue-55884-2.rs +++ b/src/test/ui/imports/issue-55884-2.rs @@ -9,6 +9,6 @@ mod parser { use ParseOptions; } -pub use parser::ParseOptions; //~ ERROR struct `ParseOptions` is private +pub use parser::ParseOptions; //~ ERROR struct import `ParseOptions` is private fn main() {} diff --git a/src/test/ui/imports/issue-55884-2.stderr b/src/test/ui/imports/issue-55884-2.stderr index 9e77283cd5946..f16d2adb3656e 100644 --- a/src/test/ui/imports/issue-55884-2.stderr +++ b/src/test/ui/imports/issue-55884-2.stderr @@ -1,10 +1,10 @@ -error[E0603]: struct `ParseOptions` is private +error[E0603]: struct import `ParseOptions` is private --> $DIR/issue-55884-2.rs:12:17 | LL | pub use parser::ParseOptions; - | ^^^^^^^^^^^^ this struct is private + | ^^^^^^^^^^^^ this struct import is private | -note: the struct `ParseOptions` is defined here +note: the struct import `ParseOptions` is defined here --> $DIR/issue-55884-2.rs:9:9 | LL | use ParseOptions; diff --git a/src/test/ui/imports/reexports.stderr b/src/test/ui/imports/reexports.stderr index 67c12e0c8d3ca..b173884080f80 100644 --- a/src/test/ui/imports/reexports.stderr +++ b/src/test/ui/imports/reexports.stderr @@ -10,25 +10,25 @@ note: consider marking `foo` as `pub` in the imported module LL | pub use super::foo; | ^^^^^^^^^^ -error[E0603]: module `foo` is private +error[E0603]: module import `foo` is private --> $DIR/reexports.rs:33:15 | LL | use b::a::foo::S; - | ^^^ this module is private + | ^^^ this module import is private | -note: the module `foo` is defined here +note: the module import `foo` is defined here --> $DIR/reexports.rs:21:17 | LL | pub use super::foo; // This is OK since the value `foo` is visible enough. | ^^^^^^^^^^ -error[E0603]: module `foo` is private +error[E0603]: module import `foo` is private --> $DIR/reexports.rs:34:15 | LL | use b::b::foo::S as T; - | ^^^ this module is private + | ^^^ this module import is private | -note: the module `foo` is defined here +note: the module import `foo` is defined here --> $DIR/reexports.rs:26:17 | LL | pub use super::*; // This is also OK since the value `foo` is visible enough. diff --git a/src/test/ui/privacy/privacy2.stderr b/src/test/ui/privacy/privacy2.stderr index d9f003ddae7ac..719dc27ccf4d6 100644 --- a/src/test/ui/privacy/privacy2.stderr +++ b/src/test/ui/privacy/privacy2.stderr @@ -4,13 +4,13 @@ error[E0432]: unresolved import `bar::foo` LL | use bar::foo; | ^^^^^^^^ no `foo` in `bar` -error[E0603]: function `foo` is private +error[E0603]: function import `foo` is private --> $DIR/privacy2.rs:23:20 | LL | use bar::glob::foo; - | ^^^ this function is private + | ^^^ this function import is private | -note: the function `foo` is defined here +note: the function import `foo` is defined here --> $DIR/privacy2.rs:10:13 | LL | use foo; diff --git a/src/test/ui/proc-macro/disappearing-resolution.rs b/src/test/ui/proc-macro/disappearing-resolution.rs index a01b8f302cae3..50f04b1eae150 100644 --- a/src/test/ui/proc-macro/disappearing-resolution.rs +++ b/src/test/ui/proc-macro/disappearing-resolution.rs @@ -8,7 +8,7 @@ extern crate test_macros; mod m { use test_macros::Empty; } -use m::Empty; //~ ERROR derive macro `Empty` is private +use m::Empty; //~ ERROR derive macro import `Empty` is private // To resolve `empty_helper` we need to resolve `Empty`. // During initial resolution `use m::Empty` introduces no entries, so we proceed to `macro_use`, diff --git a/src/test/ui/proc-macro/disappearing-resolution.stderr b/src/test/ui/proc-macro/disappearing-resolution.stderr index d81ab5ebf9bc6..3beaedf61d73a 100644 --- a/src/test/ui/proc-macro/disappearing-resolution.stderr +++ b/src/test/ui/proc-macro/disappearing-resolution.stderr @@ -4,13 +4,13 @@ error: cannot find attribute `empty_helper` in this scope LL | #[empty_helper] | ^^^^^^^^^^^^ -error[E0603]: derive macro `Empty` is private +error[E0603]: derive macro import `Empty` is private --> $DIR/disappearing-resolution.rs:11:8 | LL | use m::Empty; - | ^^^^^ this derive macro is private + | ^^^^^ this derive macro import is private | -note: the derive macro `Empty` is defined here +note: the derive macro import `Empty` is defined here --> $DIR/disappearing-resolution.rs:9:9 | LL | use test_macros::Empty; diff --git a/src/test/ui/shadowed/shadowed-use-visibility.rs b/src/test/ui/shadowed/shadowed-use-visibility.rs index 8185e82ee830e..6b801972f4179 100644 --- a/src/test/ui/shadowed/shadowed-use-visibility.rs +++ b/src/test/ui/shadowed/shadowed-use-visibility.rs @@ -6,11 +6,11 @@ mod foo { } mod bar { - use foo::bar::f as g; //~ ERROR module `bar` is private + use foo::bar::f as g; //~ ERROR module import `bar` is private use foo as f; pub use foo::*; } -use bar::f::f; //~ ERROR module `f` is private +use bar::f::f; //~ ERROR module import `f` is private fn main() {} diff --git a/src/test/ui/shadowed/shadowed-use-visibility.stderr b/src/test/ui/shadowed/shadowed-use-visibility.stderr index 77bf2abe34555..cd8ec13794c6f 100644 --- a/src/test/ui/shadowed/shadowed-use-visibility.stderr +++ b/src/test/ui/shadowed/shadowed-use-visibility.stderr @@ -1,22 +1,22 @@ -error[E0603]: module `bar` is private +error[E0603]: module import `bar` is private --> $DIR/shadowed-use-visibility.rs:9:14 | LL | use foo::bar::f as g; - | ^^^ this module is private + | ^^^ this module import is private | -note: the module `bar` is defined here +note: the module import `bar` is defined here --> $DIR/shadowed-use-visibility.rs:4:9 | LL | use foo as bar; | ^^^^^^^^^^ -error[E0603]: module `f` is private +error[E0603]: module import `f` is private --> $DIR/shadowed-use-visibility.rs:15:10 | LL | use bar::f::f; - | ^ this module is private + | ^ this module import is private | -note: the module `f` is defined here +note: the module import `f` is defined here --> $DIR/shadowed-use-visibility.rs:11:9 | LL | use foo as f; From 0b60f1f2ae54b0bdb1623606db5dd18da1e80517 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 16 Jan 2020 22:19:55 +0300 Subject: [PATCH 125/169] Ignore some tests on platforms without libstd spans --- src/test/ui/issues/issue-38857.rs | 5 +++++ src/test/ui/issues/issue-38857.stderr | 4 ++-- src/test/ui/stability-in-private-module.rs | 5 +++++ src/test/ui/stability-in-private-module.stderr | 2 +- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/test/ui/issues/issue-38857.rs b/src/test/ui/issues/issue-38857.rs index 81d881c100bb6..c0695f8216512 100644 --- a/src/test/ui/issues/issue-38857.rs +++ b/src/test/ui/issues/issue-38857.rs @@ -1,3 +1,8 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl + fn main() { let a = std::sys::imp::process::process_common::StdioPipes { ..panic!() }; //~^ ERROR failed to resolve: could not find `imp` in `sys` [E0433] diff --git a/src/test/ui/issues/issue-38857.stderr b/src/test/ui/issues/issue-38857.stderr index dd7970e014fdb..ba0f1336ff09d 100644 --- a/src/test/ui/issues/issue-38857.stderr +++ b/src/test/ui/issues/issue-38857.stderr @@ -1,11 +1,11 @@ error[E0433]: failed to resolve: could not find `imp` in `sys` - --> $DIR/issue-38857.rs:2:23 + --> $DIR/issue-38857.rs:7:23 | LL | let a = std::sys::imp::process::process_common::StdioPipes { ..panic!() }; | ^^^ could not find `imp` in `sys` error[E0603]: module `sys` is private - --> $DIR/issue-38857.rs:2:18 + --> $DIR/issue-38857.rs:7:18 | LL | let a = std::sys::imp::process::process_common::StdioPipes { ..panic!() }; | ^^^ this module is private diff --git a/src/test/ui/stability-in-private-module.rs b/src/test/ui/stability-in-private-module.rs index f12e9198b0d7c..1815897f17a60 100644 --- a/src/test/ui/stability-in-private-module.rs +++ b/src/test/ui/stability-in-private-module.rs @@ -1,3 +1,8 @@ +// FIXME: missing sysroot spans (#53081) +// ignore-i586-unknown-linux-gnu +// ignore-i586-unknown-linux-musl +// ignore-i686-unknown-linux-musl + fn main() { let _ = std::thread::thread_info::current_thread(); //~^ERROR module `thread_info` is private diff --git a/src/test/ui/stability-in-private-module.stderr b/src/test/ui/stability-in-private-module.stderr index 537a400664aaa..3a974164f9473 100644 --- a/src/test/ui/stability-in-private-module.stderr +++ b/src/test/ui/stability-in-private-module.stderr @@ -1,5 +1,5 @@ error[E0603]: module `thread_info` is private - --> $DIR/stability-in-private-module.rs:2:26 + --> $DIR/stability-in-private-module.rs:7:26 | LL | let _ = std::thread::thread_info::current_thread(); | ^^^^^^^^^^^ this module is private From 029a9c625371e756d93024efd3deb7636a90f8f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 16 Jan 2020 11:32:50 -0800 Subject: [PATCH 126/169] review comments --- .../traits/error_reporting/suggestions.rs | 49 +++++++++---------- src/librustc_error_codes/error_codes/E0746.md | 2 +- 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/src/librustc/traits/error_reporting/suggestions.rs b/src/librustc/traits/error_reporting/suggestions.rs index c3af063d518f0..bf6891214ace1 100644 --- a/src/librustc/traits/error_reporting/suggestions.rs +++ b/src/librustc/traits/error_reporting/suggestions.rs @@ -605,34 +605,31 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let tables = self.in_progress_tables.map(|t| t.borrow()).unwrap(); - let mut all_returns_conform_to_trait = true; - let mut all_returns_have_same_type = true; - let mut last_ty = None; - if let Some(ty_ret_ty) = tables.node_type_opt(ret_ty.hir_id) { - let cause = ObligationCause::misc(ret_ty.span, ret_ty.hir_id); - let param_env = ty::ParamEnv::empty(); - if let ty::Dynamic(predicates, _) = &ty_ret_ty.kind { - for expr in &visitor.0 { - if let Some(returned_ty) = tables.node_type_opt(expr.hir_id) { - all_returns_have_same_type &= - Some(returned_ty) == last_ty || last_ty.is_none(); - last_ty = Some(returned_ty); - for predicate in predicates.iter() { - let pred = predicate.with_self_ty(self.tcx, returned_ty); - let obl = Obligation::new(cause.clone(), param_env, pred); - all_returns_conform_to_trait &= self.predicate_may_hold(&obl); - } + let mut ret_types = visitor.0.iter().filter_map(|expr| tables.node_type_opt(expr.hir_id)); + let (last_ty, all_returns_have_same_type) = + ret_types.clone().fold((None, true), |(last_ty, mut same), returned_ty| { + same &= last_ty.map_or(true, |ty| ty == returned_ty); + (Some(returned_ty), same) + }); + let all_returns_conform_to_trait = + if let Some(ty_ret_ty) = tables.node_type_opt(ret_ty.hir_id) { + match ty_ret_ty.kind { + ty::Dynamic(predicates, _) => { + let cause = ObligationCause::misc(ret_ty.span, ret_ty.hir_id); + let param_env = ty::ParamEnv::empty(); + ret_types.all(|returned_ty| { + predicates.iter().all(|predicate| { + let pred = predicate.with_self_ty(self.tcx, returned_ty); + let obl = Obligation::new(cause.clone(), param_env, pred); + self.predicate_may_hold(&obl) + }) + }) } + _ => true, } - } - } else { - // We still want to verify whether all the return types conform to each other. - for expr in &visitor.0 { - let returned_ty = tables.node_type_opt(expr.hir_id); - all_returns_have_same_type &= last_ty == returned_ty || last_ty.is_none(); - last_ty = returned_ty; - } - } + } else { + true + }; let (snippet, last_ty) = if let (true, hir::TyKind::TraitObject(..), Ok(snippet), true, Some(last_ty)) = ( diff --git a/src/librustc_error_codes/error_codes/E0746.md b/src/librustc_error_codes/error_codes/E0746.md index 041061f3380c1..16b2722f0eac2 100644 --- a/src/librustc_error_codes/error_codes/E0746.md +++ b/src/librustc_error_codes/error_codes/E0746.md @@ -13,7 +13,7 @@ impl T for S { } // Having the trait `T` as return type is invalid because -// bare trait objects do not have a statically known size: +// unboxed trait objects do not have a statically known size: fn foo() -> dyn T { S(42) } From 25a8f9473f29e732838b6d88394dd80fe645b7f6 Mon Sep 17 00:00:00 2001 From: jumbatm <30644300+jumbatm@users.noreply.github.com> Date: Sat, 23 Nov 2019 14:52:40 +1000 Subject: [PATCH 127/169] Don't warn about snake case for field puns that don't introduce a new name. --- src/librustc_lint/nonstandard_style.rs | 15 ++++++++- ...62-no-snake-case-warning-for-field-puns.rs | 29 +++++++++++++++++ ...o-snake-case-warning-for-field-puns.stderr | 32 +++++++++++++++++++ 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.rs create mode 100644 src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.stderr diff --git a/src/librustc_lint/nonstandard_style.rs b/src/librustc_lint/nonstandard_style.rs index a2b7884241ff7..394da4a5bb0c1 100644 --- a/src/librustc_lint/nonstandard_style.rs +++ b/src/librustc_lint/nonstandard_style.rs @@ -350,7 +350,20 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase { } fn check_pat(&mut self, cx: &LateContext<'_, '_>, p: &hir::Pat<'_>) { - if let &PatKind::Binding(_, _, ident, _) = &p.kind { + if let &PatKind::Binding(_, hid, ident, _) = &p.kind { + if let hir::Node::Pat(parent_pat) = cx.tcx.hir().get(cx.tcx.hir().get_parent_node(hid)) + { + if let PatKind::Struct(_, field_pats, _) = &parent_pat.kind { + for field in field_pats.iter() { + if field.ident != ident { + // Only check if a new name has been introduced, to avoid warning + // on both the struct definition and this pattern. + self.check_snake_case(cx, "variable", &ident); + } + } + return; + } + } self.check_snake_case(cx, "variable", &ident); } } diff --git a/src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.rs b/src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.rs new file mode 100644 index 0000000000000..c2b81959f2cb8 --- /dev/null +++ b/src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.rs @@ -0,0 +1,29 @@ +#![deny(non_snake_case)] +#![allow(unused_variables)] +#![allow(dead_code)] + +enum Foo { + Bad { + lowerCamelCaseName: bool, + //~^ ERROR structure field `lowerCamelCaseName` should have a snake case name + }, + Good { + snake_case_name: bool, + }, +} + +fn main() { + let b = Foo::Bad { lowerCamelCaseName: true }; + + match b { + Foo::Bad { lowerCamelCaseName } => {} + Foo::Good { snake_case_name: lowerCamelCaseBinding } => { } + //~^ ERROR variable `lowerCamelCaseBinding` should have a snake case name + } + + if let Foo::Good { snake_case_name: anotherLowerCamelCaseBinding } = b { } + //~^ ERROR variable `anotherLowerCamelCaseBinding` should have a snake case name + + if let Foo::Bad { lowerCamelCaseName: yetAnotherLowerCamelCaseBinding } = b { } + //~^ ERROR variable `yetAnotherLowerCamelCaseBinding` should have a snake case name +} diff --git a/src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.stderr b/src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.stderr new file mode 100644 index 0000000000000..68956f21e8f1b --- /dev/null +++ b/src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.stderr @@ -0,0 +1,32 @@ +error: structure field `lowerCamelCaseName` should have a snake case name + --> $DIR/issue-66362-no-snake-case-warning-for-field-puns.rs:7:9 + | +LL | lowerCamelCaseName: bool, + | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `lower_camel_case_name` + | +note: lint level defined here + --> $DIR/issue-66362-no-snake-case-warning-for-field-puns.rs:1:9 + | +LL | #![deny(non_snake_case)] + | ^^^^^^^^^^^^^^ + +error: variable `lowerCamelCaseBinding` should have a snake case name + --> $DIR/issue-66362-no-snake-case-warning-for-field-puns.rs:20:38 + | +LL | Foo::Good { snake_case_name: lowerCamelCaseBinding } => { } + | ^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `lower_camel_case_binding` + +error: variable `anotherLowerCamelCaseBinding` should have a snake case name + --> $DIR/issue-66362-no-snake-case-warning-for-field-puns.rs:24:41 + | +LL | if let Foo::Good { snake_case_name: anotherLowerCamelCaseBinding } = b { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `another_lower_camel_case_binding` + +error: variable `yetAnotherLowerCamelCaseBinding` should have a snake case name + --> $DIR/issue-66362-no-snake-case-warning-for-field-puns.rs:27:43 + | +LL | if let Foo::Bad { lowerCamelCaseName: yetAnotherLowerCamelCaseBinding } = b { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `yet_another_lower_camel_case_binding` + +error: aborting due to 4 previous errors + From 73124df6eba9d81affb3ef597fdaeb4fce82f7af Mon Sep 17 00:00:00 2001 From: Richard Dodd Date: Thu, 16 Jan 2020 20:11:16 +0000 Subject: [PATCH 128/169] Rust ./x.py fmt --- src/libcore/tests/fmt/builders.rs | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/libcore/tests/fmt/builders.rs b/src/libcore/tests/fmt/builders.rs index d8ec6764bc620..129c121e8ceac 100644 --- a/src/libcore/tests/fmt/builders.rs +++ b/src/libcore/tests/fmt/builders.rs @@ -100,18 +100,17 @@ mod debug_struct { impl fmt::Debug for Foo { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_struct("Foo") - .finish_non_exhaustive() + fmt.debug_struct("Foo").finish_non_exhaustive() } } - assert_eq!("Foo { .. }", format!("{:?}", Foo)); assert_eq!( -"Foo { + "Foo { .. }", - format!("{:#?}", Foo)); + format!("{:#?}", Foo) + ); } #[test] @@ -129,12 +128,13 @@ mod debug_struct { assert_eq!("Foo { bar: true, baz: 10/20, .. }", format!("{:?}", Foo)); assert_eq!( -"Foo { + "Foo { bar: true, baz: 10/20, .. }", - format!("{:#?}", Foo)); + format!("{:#?}", Foo) + ); } #[test] @@ -161,10 +161,12 @@ mod debug_struct { } } - assert_eq!("Bar { foo: Foo { bar: true, baz: 10/20, .. }, hello: \"world\", .. }", - format!("{:?}", Bar)); assert_eq!( -"Bar { + "Bar { foo: Foo { bar: true, baz: 10/20, .. }, hello: \"world\", .. }", + format!("{:?}", Bar) + ); + assert_eq!( + "Bar { foo: Foo { bar: true, baz: 10/20, @@ -173,9 +175,9 @@ mod debug_struct { hello: \"world\", .. }", - format!("{:#?}", Bar)); + format!("{:#?}", Bar) + ); } - } mod debug_tuple { From 3094c3792bb0bffbaaa0688d02c970054c353d1f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 16 Jan 2020 21:36:39 +0100 Subject: [PATCH 129/169] Improve code readability --- src/librustdoc/clean/mod.rs | 36 ++++++++++-------------------------- 1 file changed, 10 insertions(+), 26 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index ae15b458fbaea..0e9f363bec3f3 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2121,8 +2121,8 @@ impl Clean> for doctree::Impl<'_> { Some(DefKind::TyAlias) => Some(cx.tcx.type_of(did).clean(cx)), _ => None, }); - if let Some(type_alias) = type_alias { - ret.push(Item { + let make_item = |trait_: Option, for_: Type, items: Vec| { + Item { name: None, attrs: self.attrs.clean(cx), source: self.whence.clean(cx), @@ -2134,35 +2134,19 @@ impl Clean> for doctree::Impl<'_> { unsafety: self.unsafety, generics: self.generics.clean(cx), provided_trait_methods: provided.clone(), - trait_: trait_.clone(), - for_: type_alias, - items: items.clone(), + trait_, + for_, + items, polarity: Some(cx.tcx.impl_polarity(def_id).clean(cx)), synthetic: false, blanket_impl: None, }), - }); + } + }; + if let Some(type_alias) = type_alias { + ret.push(make_item(trait_.clone(), type_alias, items.clone())); } - ret.push(Item { - name: None, - attrs: self.attrs.clean(cx), - source: self.whence.clean(cx), - def_id, - visibility: self.vis.clean(cx), - stability: cx.stability(self.id).clean(cx), - deprecation: cx.deprecation(self.id).clean(cx), - inner: ImplItem(Impl { - unsafety: self.unsafety, - generics: self.generics.clean(cx), - provided_trait_methods: provided, - trait_, - for_, - items, - polarity: Some(cx.tcx.impl_polarity(def_id).clean(cx)), - synthetic: false, - blanket_impl: None, - }), - }); + ret.push(make_item(trait_, for_, items)); ret } } From 7fbd30b1ae0ce9293302bbf4bfb814f1dc791107 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Thu, 16 Jan 2020 23:15:52 +0100 Subject: [PATCH 130/169] don't clone types that are copy found via clippy --- src/librustc/infer/error_reporting/mod.rs | 2 +- src/librustc_ast_lowering/expr.rs | 6 +++--- src/librustc_builtin_macros/deriving/generic/mod.rs | 2 +- src/librustc_errors/annotate_snippet_emitter_writer.rs | 2 +- src/librustc_incremental/persist/save.rs | 2 +- src/librustc_lint/context.rs | 2 +- src/librustc_metadata/rmeta/decoder.rs | 2 +- src/librustc_metadata/rmeta/encoder.rs | 2 +- src/librustc_mir/borrow_check/borrow_set.rs | 4 ++-- src/librustc_mir_build/build/mod.rs | 2 +- src/librustc_passes/stability.rs | 2 +- src/librustc_traits/chalk_context/mod.rs | 2 +- src/librustc_typeck/check/closure.rs | 2 +- src/librustdoc/clean/auto_trait.rs | 2 +- src/libtest/lib.rs | 4 +--- 15 files changed, 18 insertions(+), 20 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index c52d4335ea184..febf4f21a6755 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -2008,7 +2008,7 @@ impl<'tcx> ObligationCause<'tcx> { TypeError::IntrinsicCast => { Error0308("cannot coerce intrinsics to function pointers") } - TypeError::ObjectUnsafeCoercion(did) => Error0038(did.clone()), + TypeError::ObjectUnsafeCoercion(did) => Error0038(*did), _ => Error0308("mismatched types"), }, } diff --git a/src/librustc_ast_lowering/expr.rs b/src/librustc_ast_lowering/expr.rs index 9a229e709a5e5..2866a1624de5b 100644 --- a/src/librustc_ast_lowering/expr.rs +++ b/src/librustc_ast_lowering/expr.rs @@ -909,18 +909,18 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_expr_asm(&mut self, asm: &InlineAsm) -> hir::ExprKind<'hir> { let inner = hir::InlineAsmInner { - inputs: asm.inputs.iter().map(|&(ref c, _)| c.clone()).collect(), + inputs: asm.inputs.iter().map(|&(c, _)| c).collect(), outputs: asm .outputs .iter() .map(|out| hir::InlineAsmOutput { - constraint: out.constraint.clone(), + constraint: out.constraint, is_rw: out.is_rw, is_indirect: out.is_indirect, span: out.expr.span, }) .collect(), - asm: asm.asm.clone(), + asm: asm.asm, asm_str_style: asm.asm_str_style, clobbers: asm.clobbers.clone().into(), volatile: asm.volatile, diff --git a/src/librustc_builtin_macros/deriving/generic/mod.rs b/src/librustc_builtin_macros/deriving/generic/mod.rs index 7092483843f70..9226f45816506 100644 --- a/src/librustc_builtin_macros/deriving/generic/mod.rs +++ b/src/librustc_builtin_macros/deriving/generic/mod.rs @@ -1608,7 +1608,7 @@ impl<'a> TraitDef<'a> { } else { ast::BindingMode::ByRef(mutbl) }; - cx.pat(path.span, PatKind::Ident(binding_mode, (*path).clone(), None)) + cx.pat(path.span, PatKind::Ident(binding_mode, *path, None)) }) .collect() } diff --git a/src/librustc_errors/annotate_snippet_emitter_writer.rs b/src/librustc_errors/annotate_snippet_emitter_writer.rs index 7413cef6d32d4..009ab6ac5b12f 100644 --- a/src/librustc_errors/annotate_snippet_emitter_writer.rs +++ b/src/librustc_errors/annotate_snippet_emitter_writer.rs @@ -196,7 +196,7 @@ impl AnnotateSnippetEmitterWriter { ) { let converter = DiagnosticConverter { source_map: self.source_map.clone(), - level: level.clone(), + level: *level, message, code: code.clone(), msp: msp.clone(), diff --git a/src/librustc_incremental/persist/save.rs b/src/librustc_incremental/persist/save.rs index 588e639f28946..87f39dedd0273 100644 --- a/src/librustc_incremental/persist/save.rs +++ b/src/librustc_incremental/persist/save.rs @@ -236,7 +236,7 @@ fn encode_work_product_index( let serialized_products: Vec<_> = work_products .iter() .map(|(id, work_product)| SerializedWorkProduct { - id: id.clone(), + id: *id, work_product: work_product.clone(), }) .collect(); diff --git a/src/librustc_lint/context.rs b/src/librustc_lint/context.rs index 2b514c301f2a3..42ec8787cb287 100644 --- a/src/librustc_lint/context.rs +++ b/src/librustc_lint/context.rs @@ -245,7 +245,7 @@ impl LintStore { pub fn register_renamed(&mut self, old_name: &str, new_name: &str) { let target = match self.by_name.get(new_name) { - Some(&Id(lint_id)) => lint_id.clone(), + Some(&Id(lint_id)) => lint_id, _ => bug!("invalid lint renaming of {} to {}", old_name, new_name), }; self.by_name.insert(old_name.to_string(), Renamed(new_name.to_string(), target)); diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs index eb3dcfa72278e..6280121f65566 100644 --- a/src/librustc_metadata/rmeta/decoder.rs +++ b/src/librustc_metadata/rmeta/decoder.rs @@ -840,7 +840,7 @@ impl<'a, 'tcx> CrateMetadata { fn get_stability(&self, id: DefIndex) -> Option { match self.is_proc_macro(id) { - true => self.root.proc_macro_stability.clone(), + true => self.root.proc_macro_stability, false => self.root.per_def.stability.get(self, id).map(|stab| stab.decode(self)), } } diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index 7f8791d0c34dc..8ad92ce75a851 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -504,7 +504,7 @@ impl<'tcx> EncodeContext<'tcx> { }, proc_macro_data, proc_macro_stability: if is_proc_macro { - tcx.lookup_stability(DefId::local(CRATE_DEF_INDEX)).map(|stab| stab.clone()) + tcx.lookup_stability(DefId::local(CRATE_DEF_INDEX)).map(|stab| *stab) } else { None }, diff --git a/src/librustc_mir/borrow_check/borrow_set.rs b/src/librustc_mir/borrow_check/borrow_set.rs index f2a44986cc4d4..9d5cf3ec4bec0 100644 --- a/src/librustc_mir/borrow_check/borrow_set.rs +++ b/src/librustc_mir/borrow_check/borrow_set.rs @@ -200,8 +200,8 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'tcx> { region, reserve_location: location, activation_location: TwoPhaseActivation::NotTwoPhase, - borrowed_place: borrowed_place.clone(), - assigned_place: assigned_place.clone(), + borrowed_place: *borrowed_place, + assigned_place: *assigned_place, }; let idx = self.idx_vec.push(borrow); self.location_map.insert(location, idx); diff --git a/src/librustc_mir_build/build/mod.rs b/src/librustc_mir_build/build/mod.rs index 6214453e64f78..44ff493b5b4f0 100644 --- a/src/librustc_mir_build/build/mod.rs +++ b/src/librustc_mir_build/build/mod.rs @@ -65,7 +65,7 @@ fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> BodyAndCache<'_> { } else if cx.body_owner_kind.is_fn_or_closure() { // fetch the fully liberated fn signature (that is, all bound // types/lifetimes replaced) - let fn_sig = cx.tables().liberated_fn_sigs()[id].clone(); + let fn_sig = cx.tables().liberated_fn_sigs()[id]; let fn_def_id = tcx.hir().local_def_id(id); let ty = tcx.type_of(fn_def_id); diff --git a/src/librustc_passes/stability.rs b/src/librustc_passes/stability.rs index af37d218d68f0..5ec7e73f873e0 100644 --- a/src/librustc_passes/stability.rs +++ b/src/librustc_passes/stability.rs @@ -91,7 +91,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { // deprecated_since and its reason. if let Some(parent_stab) = self.parent_stab { if parent_stab.rustc_depr.is_some() && stab.rustc_depr.is_none() { - stab.rustc_depr = parent_stab.rustc_depr.clone() + stab.rustc_depr = parent_stab.rustc_depr } } diff --git a/src/librustc_traits/chalk_context/mod.rs b/src/librustc_traits/chalk_context/mod.rs index 4b10b08ddd94c..0b18352df3307 100644 --- a/src/librustc_traits/chalk_context/mod.rs +++ b/src/librustc_traits/chalk_context/mod.rs @@ -400,7 +400,7 @@ impl context::UnificationOps, ChalkArenas<'tcx>> &mut self, value: &Canonical<'tcx, InEnvironment<'tcx, Goal<'tcx>>>, ) -> (Canonical<'tcx, InEnvironment<'tcx, Goal<'tcx>>>, UniverseMap) { - (value.clone(), UniverseMap) + (*value, UniverseMap) } fn invert_goal( diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 6bb7f4995b6ec..084e6c8d083c5 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -175,7 +175,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } ty::Infer(ty::TyVar(vid)) => self.deduce_expectations_from_obligations(vid), ty::FnPtr(sig) => { - let expected_sig = ExpectedSig { cause_span: None, sig: sig.skip_binder().clone() }; + let expected_sig = ExpectedSig { cause_span: None, sig: *sig.skip_binder() }; (Some(expected_sig), Some(ty::ClosureKind::Fn)) } _ => (None, None), diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 56013ee3a816f..f37f6921cebaf 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -239,7 +239,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { // constraint, and add it to our list. Since we make sure to never re-add // deleted items, this process will always finish. while !vid_map.is_empty() { - let target = vid_map.keys().next().expect("Keys somehow empty").clone(); + let target = *vid_map.keys().next().expect("Keys somehow empty"); let deps = vid_map.remove(&target).expect("Entry somehow missing"); for smaller in deps.smaller.iter() { diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 45669d120c7c2..4c4d795824318 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -485,9 +485,7 @@ pub fn run_test( } StaticBenchFn(benchfn) => { // Benchmarks aren't expected to panic, so we run them all in-process. - crate::bench::benchmark(desc, monitor_ch, opts.nocapture, |harness| { - (benchfn.clone())(harness) - }); + crate::bench::benchmark(desc, monitor_ch, opts.nocapture, benchfn); } DynTestFn(f) => { match strategy { From 4dbae1e8baf5c42b42aa2ab4d1104ec019b75b83 Mon Sep 17 00:00:00 2001 From: Stein Somers Date: Fri, 17 Jan 2020 01:05:49 +0100 Subject: [PATCH 131/169] Allow added string.insert benchmarks to compile --- src/liballoc/benches/string.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liballoc/benches/string.rs b/src/liballoc/benches/string.rs index 599c8b1682851..5c95160ba2d14 100644 --- a/src/liballoc/benches/string.rs +++ b/src/liballoc/benches/string.rs @@ -1,5 +1,5 @@ use std::iter::repeat; -use test::Bencher; +use test::{black_box, Bencher}; #[bench] fn bench_with_capacity(b: &mut Bencher) { From 6246f7e1f90f1b72d5b9b530df2ee81beeb09f20 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Thu, 16 Jan 2020 16:29:32 -0800 Subject: [PATCH 132/169] Don't propagate __RUST_TEST_INVOKE to subprocess When -Z panic_abort_tests is enabled, we use an environment variable to tell the subprocess which test to invoke. If that subprocess then invokes another Rust test binary, chaos ensues. --- src/libtest/lib.rs | 3 ++- src/test/ui/test-panic-abort.rs | 11 +++++++++++ src/test/ui/test-panic-abort.run.stdout | 7 ++++--- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 45669d120c7c2..7782f62d6ed35 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -153,12 +153,13 @@ pub fn test_main_static_abort(tests: &[&TestDescAndFn]) { // If we're being run in SpawnedSecondary mode, run the test here. run_test // will then exit the process. if let Ok(name) = env::var(SECONDARY_TEST_INVOKER_VAR) { + env::remove_var(SECONDARY_TEST_INVOKER_VAR); let test = tests .iter() .filter(|test| test.desc.name.as_slice() == name) .map(make_owned_test) .next() - .expect("couldn't find a test with the provided name"); + .expect(&format!("couldn't find a test with the provided name '{}'", name)); let TestDescAndFn { desc, testfn } = test; let testfn = match testfn { StaticTestFn(f) => f, diff --git a/src/test/ui/test-panic-abort.rs b/src/test/ui/test-panic-abort.rs index b0679ea1d3df2..b7bf5a150ea8b 100644 --- a/src/test/ui/test-panic-abort.rs +++ b/src/test/ui/test-panic-abort.rs @@ -11,6 +11,7 @@ #![cfg(test)] use std::io::Write; +use std::env; #[test] fn it_works() { @@ -35,3 +36,13 @@ fn it_fails() { fn it_exits() { std::process::exit(123); } + +#[test] +fn no_residual_environment() { + for (key, _) in env::vars() { + // Look for keys like __RUST_TEST_INVOKE. + if key.contains("TEST_INVOKE") { + panic!("shouldn't have '{}' in environment", key); + } + } +} diff --git a/src/test/ui/test-panic-abort.run.stdout b/src/test/ui/test-panic-abort.run.stdout index 46adcfbc2eb4a..2f4bc32ed6a1f 100644 --- a/src/test/ui/test-panic-abort.run.stdout +++ b/src/test/ui/test-panic-abort.run.stdout @@ -1,9 +1,10 @@ -running 4 tests +running 5 tests test it_exits ... FAILED test it_fails ... FAILED test it_panics ... ok test it_works ... ok +test no_residual_environment ... ok failures: @@ -17,7 +18,7 @@ testing123 testing321 thread 'main' panicked at 'assertion failed: `(left == right)` left: `2`, - right: `5`', $DIR/test-panic-abort.rs:31:5 + right: `5`', $DIR/test-panic-abort.rs:32:5 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace @@ -25,5 +26,5 @@ failures: it_exits it_fails -test result: FAILED. 2 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out +test result: FAILED. 3 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out From 10a9ea4c2622544d52ecef47fea0404a7ce0ace4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 15 Jan 2020 09:57:06 -0800 Subject: [PATCH 133/169] Do not ICE on malformed suggestion spans --- src/librustc_errors/emitter.rs | 9 ++++++++- src/librustc_errors/lib.rs | 13 +++++++++++++ src/librustc_span/source_map.rs | 11 +++++++---- .../ui/consts/miri_unleashed/mutable_const2.stderr | 2 +- 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 526b4e2971bef..e37496f729952 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -1475,6 +1475,11 @@ impl EmitterWriter { Some(ref sm) => sm, None => return Ok(()), }; + if !suggestion.has_valid_spans(&**sm) { + // Suggestions coming from macros can have malformed spans. This is a heavy handed + // approach to avoid ICEs by ignoring the suggestion outright. + return Ok(()); + } let mut buffer = StyledBuffer::new(); @@ -1505,7 +1510,9 @@ impl EmitterWriter { let show_underline = !(parts.len() == 1 && parts[0].snippet.trim() == complete.trim()) && complete.lines().count() == 1; - let lines = sm.span_to_lines(parts[0].span).unwrap(); + let lines = sm + .span_to_lines(parts[0].span) + .expect("span_to_lines failed when emitting suggestion"); assert!(!lines.lines.is_empty()); diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index e24e8719133a9..889c84d6da132 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -10,6 +10,7 @@ pub use emitter::ColorConfig; +use log::debug; use Level::*; use emitter::{is_case_difference, Emitter, EmitterWriter}; @@ -143,6 +144,18 @@ pub struct SubstitutionPart { } impl CodeSuggestion { + /// Suggestions coming from macros can have malformed spans. This is a heavy handed approach + /// to avoid ICEs by ignoring the suggestion outright. + pub fn has_valid_spans(&self, cm: &SourceMap) -> bool { + !self.substitutions.iter().any(|subst| { + let invalid = subst.parts.iter().any(|item| cm.is_valid_span(item.span).is_err()); + if invalid { + debug!("malformed span in suggestion: {:?}", subst); + } + invalid + }) + } + /// Returns the assembled code suggestions, whether they should be shown with an underline /// and whether the substitution only differs in capitalization. pub fn splice_lines(&self, cm: &SourceMap) -> Vec<(String, Vec, bool)> { diff --git a/src/librustc_span/source_map.rs b/src/librustc_span/source_map.rs index fb5fcf4a8303b..9c7c0f0c8b0ec 100644 --- a/src/librustc_span/source_map.rs +++ b/src/librustc_span/source_map.rs @@ -473,20 +473,23 @@ impl SourceMap { lo.line != hi.line } - pub fn span_to_lines(&self, sp: Span) -> FileLinesResult { - debug!("span_to_lines(sp={:?})", sp); - + pub fn is_valid_span(&self, sp: Span) -> Result<(Loc, Loc), SpanLinesError> { let lo = self.lookup_char_pos(sp.lo()); debug!("span_to_lines: lo={:?}", lo); let hi = self.lookup_char_pos(sp.hi()); debug!("span_to_lines: hi={:?}", hi); - if lo.file.start_pos != hi.file.start_pos { return Err(SpanLinesError::DistinctSources(DistinctSources { begin: (lo.file.name.clone(), lo.file.start_pos), end: (hi.file.name.clone(), hi.file.start_pos), })); } + Ok((lo, hi)) + } + + pub fn span_to_lines(&self, sp: Span) -> FileLinesResult { + debug!("span_to_lines(sp={:?})", sp); + let (lo, hi) = self.is_valid_span(sp)?; assert!(hi.line >= lo.line); let mut lines = Vec::with_capacity(hi.line - lo.line + 1); diff --git a/src/test/ui/consts/miri_unleashed/mutable_const2.stderr b/src/test/ui/consts/miri_unleashed/mutable_const2.stderr index 655c31763ef44..cc124058cfcb8 100644 --- a/src/test/ui/consts/miri_unleashed/mutable_const2.stderr +++ b/src/test/ui/consts/miri_unleashed/mutable_const2.stderr @@ -10,7 +10,7 @@ error: internal compiler error: mutable allocation in constant LL | const MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:346:17 +thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:359:17 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace error: internal compiler error: unexpected panic From 19fdc6e091af973a378d53c13bb1ea42862171ad Mon Sep 17 00:00:00 2001 From: Phoebe Bell Date: Tue, 19 Nov 2019 18:28:32 -0800 Subject: [PATCH 134/169] Document unsafe blocks in core::{cell, str, sync} --- src/libcore/cell.rs | 12 +++++++++-- src/libcore/str/lossy.rs | 6 ++++-- src/libcore/str/mod.rs | 44 ++++++++++++++++++++++++++++++-------- src/libcore/str/pattern.rs | 13 +++++++++-- src/libcore/sync/atomic.rs | 33 ++++++++++++++++++++++++++-- 5 files changed, 91 insertions(+), 17 deletions(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 4fcd0d9737d56..c530432f802db 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -187,8 +187,6 @@ //! ``` //! -// ignore-tidy-undocumented-unsafe - #![stable(feature = "rust1", since = "1.0.0")] use crate::cmp::Ordering; @@ -368,6 +366,7 @@ impl Cell { if ptr::eq(self, other) { return; } + // SAFETY: not threadsafe, but it's OK since we know `Cell` isn't threadsafe unsafe { ptr::swap(self.value.get(), other.value.get()); } @@ -387,6 +386,7 @@ impl Cell { /// ``` #[stable(feature = "move_cell", since = "1.17.0")] pub fn replace(&self, val: T) -> T { + // SAFETY: not threadsafe, but it's OK since we know `Cell` isn't threadsafe mem::replace(unsafe { &mut *self.value.get() }, val) } @@ -423,6 +423,7 @@ impl Cell { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn get(&self) -> T { + // SAFETY: not threadsafe, but it's OK since we know `Cell` isn't threadsafe unsafe { *self.value.get() } } @@ -491,6 +492,7 @@ impl Cell { #[inline] #[stable(feature = "cell_get_mut", since = "1.11.0")] pub fn get_mut(&mut self) -> &mut T { + // SAFETY: not threadsafe, but it's OK since we know `Cell` isn't threadsafe unsafe { &mut *self.value.get() } } @@ -510,6 +512,7 @@ impl Cell { #[inline] #[stable(feature = "as_cell", since = "1.37.0")] pub fn from_mut(t: &mut T) -> &Cell { + // SAFETY: `&mut` ensures unique access unsafe { &*(t as *mut T as *const Cell) } } } @@ -553,6 +556,7 @@ impl Cell<[T]> { /// ``` #[stable(feature = "as_cell", since = "1.37.0")] pub fn as_slice_of_cells(&self) -> &[Cell] { + // SAFETY: `Cell` has the same memory layout as `T` unsafe { &*(self as *const Cell<[T]> as *const [Cell]) } } } @@ -816,6 +820,8 @@ impl RefCell { #[inline] pub fn try_borrow(&self) -> Result, BorrowError> { match BorrowRef::new(&self.borrow) { + // SAFETY: `BorrowRef` ensures that there is only immutable access + // to the value while borrowed Some(b) => Ok(Ref { value: unsafe { &*self.value.get() }, borrow: b }), None => Err(BorrowError { _private: () }), } @@ -891,6 +897,7 @@ impl RefCell { #[inline] pub fn try_borrow_mut(&self) -> Result, BorrowMutError> { match BorrowRefMut::new(&self.borrow) { + // SAFETY: `BorrowRef` gurantees unique access Some(b) => Ok(RefMut { value: unsafe { &mut *self.value.get() }, borrow: b }), None => Err(BorrowMutError { _private: () }), } @@ -940,6 +947,7 @@ impl RefCell { #[inline] #[stable(feature = "cell_get_mut", since = "1.11.0")] pub fn get_mut(&mut self) -> &mut T { + // SAFETY: `&mut` guarantees unique access unsafe { &mut *self.value.get() } } diff --git a/src/libcore/str/lossy.rs b/src/libcore/str/lossy.rs index 8a1fb9de54667..9d2e38734ef02 100644 --- a/src/libcore/str/lossy.rs +++ b/src/libcore/str/lossy.rs @@ -3,8 +3,6 @@ use crate::fmt::{self, Write}; use crate::mem; use crate::str as core_str; -// ignore-tidy-undocumented-unsafe - /// Lossy UTF-8 string. #[unstable(feature = "str_internals", issue = "none")] pub struct Utf8Lossy { @@ -17,6 +15,7 @@ impl Utf8Lossy { } pub fn from_bytes(bytes: &[u8]) -> &Utf8Lossy { + // SAFETY: both use the same memory layout, and UTF-8 correctness isn't required unsafe { mem::transmute(bytes) } } @@ -60,6 +59,7 @@ impl<'a> Iterator for Utf8LossyChunksIter<'a> { while i < self.source.len() { let i_ = i; + // SAFETY: 0 <= i < self.source.len() let byte = unsafe { *self.source.get_unchecked(i) }; i += 1; @@ -69,6 +69,7 @@ impl<'a> Iterator for Utf8LossyChunksIter<'a> { macro_rules! error { () => {{ + // SAFETY: we have checked up to `i` that source is valid UTF-8 unsafe { let r = Utf8LossyChunk { valid: core_str::from_utf8_unchecked(&self.source[0..i_]), @@ -130,6 +131,7 @@ impl<'a> Iterator for Utf8LossyChunksIter<'a> { } let r = Utf8LossyChunk { + // SAFETY: we have checked that the entire source is valid UTF-8 valid: unsafe { core_str::from_utf8_unchecked(self.source) }, broken: &[], }; diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index ab771b1164bad..3139d6188e27f 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1,5 +1,4 @@ // ignore-tidy-filelength -// ignore-tidy-undocumented-unsafe //! String manipulation. //! @@ -341,6 +340,7 @@ impl Utf8Error { #[stable(feature = "rust1", since = "1.0.0")] pub fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> { run_utf8_validation(v)?; + // SAFETY: just ran validation Ok(unsafe { from_utf8_unchecked(v) }) } @@ -379,6 +379,7 @@ pub fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> { #[stable(feature = "str_mut_extras", since = "1.20.0")] pub fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> { run_utf8_validation(v)?; + // SAFETY: just ran validation Ok(unsafe { from_utf8_unchecked_mut(v) }) } @@ -581,7 +582,7 @@ impl<'a> Iterator for Chars<'a> { #[inline] fn next(&mut self) -> Option { next_code_point(&mut self.iter).map(|ch| { - // str invariant says `ch` is a valid Unicode Scalar Value + // SAFETY: str invariant says `ch` is a valid Unicode Scalar Value unsafe { char::from_u32_unchecked(ch) } }) } @@ -628,7 +629,7 @@ impl<'a> DoubleEndedIterator for Chars<'a> { #[inline] fn next_back(&mut self) -> Option { next_code_point_reverse(&mut self.iter).map(|ch| { - // str invariant says `ch` is a valid Unicode Scalar Value + // SAFETY: str invariant says `ch` is a valid Unicode Scalar Value unsafe { char::from_u32_unchecked(ch) } }) } @@ -658,6 +659,7 @@ impl<'a> Chars<'a> { #[stable(feature = "iter_to_slice", since = "1.4.0")] #[inline] pub fn as_str(&self) -> &'a str { + // SAFETY: Chars is only made from a str, which guarantees the iter is valid utf8 unsafe { from_utf8_unchecked(self.iter.as_slice()) } } } @@ -1102,6 +1104,7 @@ impl<'a, P: Pattern<'a>> SplitInternal<'a, P> { fn get_end(&mut self) -> Option<&'a str> { if !self.finished && (self.allow_trailing_empty || self.end - self.start > 0) { self.finished = true; + // SAFETY: `self.start` and `self.end` always lie on unicode boundaries unsafe { let string = self.matcher.haystack().get_unchecked(self.start..self.end); Some(string) @@ -1119,6 +1122,7 @@ impl<'a, P: Pattern<'a>> SplitInternal<'a, P> { let haystack = self.matcher.haystack(); match self.matcher.next_match() { + // SAFETY: `Searcher` guarantees that `a` and `b` lie on unicode boundaries Some((a, b)) => unsafe { let elt = haystack.get_unchecked(self.start..a); self.start = b; @@ -1151,11 +1155,13 @@ impl<'a, P: Pattern<'a>> SplitInternal<'a, P> { let haystack = self.matcher.haystack(); match self.matcher.next_match_back() { + // SAFETY: `Searcher` guarantees that `a` and `b` lie on unicode boundaries Some((a, b)) => unsafe { let elt = haystack.get_unchecked(b..self.end); self.end = a; Some(elt) }, + // SAFETY: `self.start` and `self.end` always lie on unicode boundaries None => unsafe { self.finished = true; Some(haystack.get_unchecked(self.start..self.end)) @@ -1295,6 +1301,7 @@ where impl<'a, P: Pattern<'a>> MatchIndicesInternal<'a, P> { #[inline] fn next(&mut self) -> Option<(usize, &'a str)> { + // SAFETY: `Searcher` guaratees that `start` and `end` lie on unicode boundaries self.0 .next_match() .map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) }) @@ -1305,6 +1312,7 @@ impl<'a, P: Pattern<'a>> MatchIndicesInternal<'a, P> { where P::Searcher: ReverseSearcher<'a>, { + // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries self.0 .next_match_back() .map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) }) @@ -1348,6 +1356,7 @@ where impl<'a, P: Pattern<'a>> MatchesInternal<'a, P> { #[inline] fn next(&mut self) -> Option<&'a str> { + // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries self.0.next_match().map(|(a, b)| unsafe { // Indices are known to be on utf8 boundaries self.0.haystack().get_unchecked(a..b) @@ -1359,6 +1368,7 @@ impl<'a, P: Pattern<'a>> MatchesInternal<'a, P> { where P::Searcher: ReverseSearcher<'a>, { + // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries self.0.next_match_back().map(|(a, b)| unsafe { // Indices are known to be on utf8 boundaries self.0.haystack().get_unchecked(a..b) @@ -1579,6 +1589,9 @@ fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> { if align != usize::max_value() && align.wrapping_sub(index) % usize_bytes == 0 { let ptr = v.as_ptr(); while index < blocks_end { + // SAFETY: since `align - index` and `ascii_block_size` are multiples of + // `usize_bytes`, `ptr.add(index)` is always aligned with a `usize` so we + // may cast directly to a `const` pointer. unsafe { let block = ptr.add(index) as *const usize; // break if there is a nonascii byte @@ -1804,6 +1817,7 @@ mod traits { && slice.is_char_boundary(self.start) && slice.is_char_boundary(self.end) { + // SAFETY: just checked that `start` and `end` are on a char boundary Some(unsafe { self.get_unchecked(slice) }) } else { None @@ -1815,6 +1829,7 @@ mod traits { && slice.is_char_boundary(self.start) && slice.is_char_boundary(self.end) { + // SAFETY: just checked that `start` and `end` are on a char boundary Some(unsafe { self.get_unchecked_mut(slice) }) } else { None @@ -1845,6 +1860,7 @@ mod traits { && slice.is_char_boundary(self.start) && slice.is_char_boundary(self.end) { + // SAFETY: just checked that `start` and `end` are on a char boundary unsafe { self.get_unchecked_mut(slice) } } else { super::slice_error_fail(slice, self.start, self.end) @@ -1873,6 +1889,7 @@ mod traits { #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { if slice.is_char_boundary(self.end) { + // SAFETY: just checked that `end` is on a char boundary Some(unsafe { self.get_unchecked(slice) }) } else { None @@ -1881,6 +1898,7 @@ mod traits { #[inline] fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { if slice.is_char_boundary(self.end) { + // SAFETY: just checked that `end` is on a char boundary Some(unsafe { self.get_unchecked_mut(slice) }) } else { None @@ -1903,8 +1921,8 @@ mod traits { } #[inline] fn index_mut(self, slice: &mut str) -> &mut Self::Output { - // is_char_boundary checks that the index is in [0, .len()] if slice.is_char_boundary(self.end) { + // SAFETY: just checked that `end` is on a char boundary unsafe { self.get_unchecked_mut(slice) } } else { super::slice_error_fail(slice, 0, self.end) @@ -1934,6 +1952,7 @@ mod traits { #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { if slice.is_char_boundary(self.start) { + // SAFETY: just checked that `start` is on a char boundary Some(unsafe { self.get_unchecked(slice) }) } else { None @@ -1942,6 +1961,7 @@ mod traits { #[inline] fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { if slice.is_char_boundary(self.start) { + // SAFETY: just checked that `start` is on a char boundary Some(unsafe { self.get_unchecked_mut(slice) }) } else { None @@ -1966,8 +1986,8 @@ mod traits { } #[inline] fn index_mut(self, slice: &mut str) -> &mut Self::Output { - // is_char_boundary checks that the index is in [0, .len()] if slice.is_char_boundary(self.start) { + // SAFETY: just checked that `start` is on a char boundary unsafe { self.get_unchecked_mut(slice) } } else { super::slice_error_fail(slice, self.start, slice.len()) @@ -2238,7 +2258,6 @@ impl str { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "str_as_bytes", since = "1.32.0")] #[inline(always)] - // SAFETY: const sound because we transmute two types with the same layout #[allow(unused_attributes)] #[allow_internal_unstable(const_fn_union)] pub const fn as_bytes(&self) -> &[u8] { @@ -2247,6 +2266,7 @@ impl str { str: &'a str, slice: &'a [u8], } + // SAFETY: const sound because we transmute two types with the same layout unsafe { Slices { str: self }.slice } } @@ -2573,6 +2593,7 @@ impl str { pub fn split_at(&self, mid: usize) -> (&str, &str) { // is_char_boundary checks that the index is in [0, .len()] if self.is_char_boundary(mid) { + // SAFETY: just checked that `mid` is on a char boundary unsafe { (self.get_unchecked(0..mid), self.get_unchecked(mid..self.len())) } } else { slice_error_fail(self, 0, mid) @@ -2617,6 +2638,7 @@ impl str { if self.is_char_boundary(mid) { let len = self.len(); let ptr = self.as_mut_ptr(); + // SAFETY: just checked that `mid` is on a char boundary unsafe { ( from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr, mid)), @@ -3805,8 +3827,8 @@ impl str { if let Some((_, b)) = matcher.next_reject_back() { j = b; } + // SAFETY: `Searcher` is known to return valid indices unsafe { - // Searcher is known to return valid indices self.get_unchecked(i..j) } } @@ -3844,8 +3866,8 @@ impl str { if let Some((a, _)) = matcher.next_reject() { i = a; } + // SAFETY: `Searcher` is known to return valid indices unsafe { - // Searcher is known to return valid indices self.get_unchecked(i..self.len()) } } @@ -3970,8 +3992,8 @@ impl str { if let Some((_, b)) = matcher.next_reject_back() { j = b; } + // SAFETY: `Searcher` is known to return valid indices unsafe { - // Searcher is known to return valid indices self.get_unchecked(0..j) } } @@ -4166,6 +4188,7 @@ impl str { /// ``` #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] pub fn make_ascii_uppercase(&mut self) { + // SAFETY: safe because we transmute two types with the same layout let me = unsafe { self.as_bytes_mut() }; me.make_ascii_uppercase() } @@ -4191,6 +4214,7 @@ impl str { /// ``` #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] pub fn make_ascii_lowercase(&mut self) { + // SAFETY: safe because we transmute two types with the same layout let me = unsafe { self.as_bytes_mut() }; me.make_ascii_lowercase() } @@ -4356,6 +4380,7 @@ impl Default for &str { #[stable(feature = "default_mut_str", since = "1.28.0")] impl Default for &mut str { /// Creates an empty mutable str + // SAFETY: `str` is guranteed to be UTF-8 fn default() -> Self { unsafe { from_utf8_unchecked_mut(&mut []) } } @@ -4412,6 +4437,7 @@ impl_fn_for_zst! { #[derive(Clone)] struct UnsafeBytesToStr impl<'a> Fn = |bytes: &'a [u8]| -> &'a str { + // SAFETY: not safe unsafe { from_utf8_unchecked(bytes) } }; } diff --git a/src/libcore/str/pattern.rs b/src/libcore/str/pattern.rs index 46d9499394a38..ef64d8b0fdf88 100644 --- a/src/libcore/str/pattern.rs +++ b/src/libcore/str/pattern.rs @@ -3,8 +3,6 @@ //! For more details, see the traits [`Pattern`], [`Searcher`], //! [`ReverseSearcher`], and [`DoubleEndedSearcher`]. -// ignore-tidy-undocumented-unsafe - #![unstable( feature = "pattern", reason = "API not fully fleshed out and ready to be stabilized", @@ -271,6 +269,14 @@ unsafe impl<'a> Searcher<'a> for CharSearcher<'a> { #[inline] fn next(&mut self) -> SearchStep { let old_finger = self.finger; + // SAFETY: 1-4 guarantee safety of `get_unchecked` + // 1. `self.finger` and `self.finger_back` are kept on unicode boundaries + // (this is invariant) + // 2. `self.finger >= 0` since it starts at 0 and only increases + // 3. `self.finger < self.finger_back` because otherwise the char `iter` + // would return `SearchStep::Done` + // 4. `self.finger` comes before the end of the haystack because `self.finger_back` + // starts at the end and only decreases let slice = unsafe { self.haystack.get_unchecked(old_finger..self.finger_back) }; let mut iter = slice.chars(); let old_len = iter.iter.len(); @@ -293,6 +299,7 @@ unsafe impl<'a> Searcher<'a> for CharSearcher<'a> { // get the haystack after the last character found let bytes = self.haystack.as_bytes().get(self.finger..self.finger_back)?; // the last byte of the utf8 encoded needle + // SAFETY: we have an invariant that `utf8_size < 5` let last_byte = unsafe { *self.utf8_encoded.get_unchecked(self.utf8_size - 1) }; if let Some(index) = memchr::memchr(last_byte, bytes) { // The new finger is the index of the byte we found, @@ -336,6 +343,7 @@ unsafe impl<'a> ReverseSearcher<'a> for CharSearcher<'a> { #[inline] fn next_back(&mut self) -> SearchStep { let old_finger = self.finger_back; + // SAFETY: see the comment for next() above let slice = unsafe { self.haystack.get_unchecked(self.finger..old_finger) }; let mut iter = slice.chars(); let old_len = iter.iter.len(); @@ -363,6 +371,7 @@ unsafe impl<'a> ReverseSearcher<'a> for CharSearcher<'a> { return None; }; // the last byte of the utf8 encoded needle + // SAFETY: we have an invariant that `utf8_size < 5` let last_byte = unsafe { *self.utf8_encoded.get_unchecked(self.utf8_size - 1) }; if let Some(index) = memchr::memrchr(last_byte, bytes) { // we searched a slice that was offset by self.finger, diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index fae95ca5cdb36..889f182561b63 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -112,8 +112,6 @@ //! println!("live threads: {}", old_thread_count + 1); //! ``` -// ignore-tidy-undocumented-unsafe - #![stable(feature = "rust1", since = "1.0.0")] #![cfg_attr(not(target_has_atomic_load_store = "8"), allow(dead_code))] #![cfg_attr(not(target_has_atomic_load_store = "8"), allow(unused_imports))] @@ -350,6 +348,7 @@ impl AtomicBool { #[inline] #[stable(feature = "atomic_access", since = "1.15.0")] pub fn get_mut(&mut self) -> &mut bool { + // SAFETY: the mutable reference guarantees unique ownership unsafe { &mut *(self.v.get() as *mut bool) } } @@ -400,6 +399,7 @@ impl AtomicBool { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn load(&self, order: Ordering) -> bool { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_load(self.v.get(), order) != 0 } } @@ -432,6 +432,7 @@ impl AtomicBool { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn store(&self, val: bool, order: Ordering) { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_store(self.v.get(), val as u8, order); } @@ -463,6 +464,7 @@ impl AtomicBool { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "8")] pub fn swap(&self, val: bool, order: Ordering) -> bool { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_swap(self.v.get(), val as u8, order) != 0 } } @@ -558,6 +560,7 @@ impl AtomicBool { success: Ordering, failure: Ordering, ) -> Result { + // SAFETY: data races are prevented by atomic intrinsics match unsafe { atomic_compare_exchange(self.v.get(), current as u8, new as u8, success, failure) } { @@ -615,6 +618,7 @@ impl AtomicBool { success: Ordering, failure: Ordering, ) -> Result { + // SAFETY: data races are prevented by atomic intrinsics match unsafe { atomic_compare_exchange_weak(self.v.get(), current as u8, new as u8, success, failure) } { @@ -661,6 +665,7 @@ impl AtomicBool { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "8")] pub fn fetch_and(&self, val: bool, order: Ordering) -> bool { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_and(self.v.get(), val as u8, order) != 0 } } @@ -756,6 +761,7 @@ impl AtomicBool { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "8")] pub fn fetch_or(&self, val: bool, order: Ordering) -> bool { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_or(self.v.get(), val as u8, order) != 0 } } @@ -797,6 +803,7 @@ impl AtomicBool { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "8")] pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_xor(self.v.get(), val as u8, order) != 0 } } @@ -872,6 +879,7 @@ impl AtomicPtr { #[inline] #[stable(feature = "atomic_access", since = "1.15.0")] pub fn get_mut(&mut self) -> &mut *mut T { + // SAFETY: the mutable reference guarantees unique ownership unsafe { &mut *self.p.get() } } @@ -923,6 +931,7 @@ impl AtomicPtr { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn load(&self, order: Ordering) -> *mut T { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_load(self.p.get() as *mut usize, order) as *mut T } } @@ -957,6 +966,7 @@ impl AtomicPtr { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn store(&self, ptr: *mut T, order: Ordering) { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_store(self.p.get() as *mut usize, ptr as usize, order); } @@ -990,6 +1000,7 @@ impl AtomicPtr { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "ptr")] pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_swap(self.p.get() as *mut usize, ptr as usize, order) as *mut T } } @@ -1074,6 +1085,7 @@ impl AtomicPtr { success: Ordering, failure: Ordering, ) -> Result<*mut T, *mut T> { + // SAFETY: data races are prevented by atomic intrinsics unsafe { let res = atomic_compare_exchange( self.p.get() as *mut usize, @@ -1137,6 +1149,7 @@ impl AtomicPtr { success: Ordering, failure: Ordering, ) -> Result<*mut T, *mut T> { + // SAFETY: data races are prevented by atomic intrinsics unsafe { let res = atomic_compare_exchange_weak( self.p.get() as *mut usize, @@ -1290,6 +1303,7 @@ assert_eq!(some_var.load(Ordering::SeqCst), 5); #[inline] #[$stable_access] pub fn get_mut(&mut self) -> &mut $int_type { + // SAFETY: the mutable reference guarantees unique ownership unsafe { &mut *self.v.get() } } } @@ -1344,6 +1358,7 @@ assert_eq!(some_var.load(Ordering::Relaxed), 5); #[inline] #[$stable] pub fn load(&self, order: Ordering) -> $int_type { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_load(self.v.get(), order) } } } @@ -1378,6 +1393,7 @@ assert_eq!(some_var.load(Ordering::Relaxed), 10); #[inline] #[$stable] pub fn store(&self, val: $int_type, order: Ordering) { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_store(self.v.get(), val, order); } } } @@ -1408,6 +1424,7 @@ assert_eq!(some_var.swap(10, Ordering::Relaxed), 5); #[$stable] #[$cfg_cas] pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_swap(self.v.get(), val, order) } } } @@ -1510,6 +1527,7 @@ assert_eq!(some_var.load(Ordering::Relaxed), 10); new: $int_type, success: Ordering, failure: Ordering) -> Result<$int_type, $int_type> { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_compare_exchange(self.v.get(), current, new, success, failure) } } } @@ -1562,6 +1580,7 @@ loop { new: $int_type, success: Ordering, failure: Ordering) -> Result<$int_type, $int_type> { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_compare_exchange_weak(self.v.get(), current, new, success, failure) } @@ -1596,6 +1615,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 10); #[$stable] #[$cfg_cas] pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_add(self.v.get(), val, order) } } } @@ -1628,6 +1648,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 10); #[$stable] #[$cfg_cas] pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_sub(self.v.get(), val, order) } } } @@ -1663,6 +1684,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 0b100001); #[$stable] #[$cfg_cas] pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_and(self.v.get(), val, order) } } } @@ -1699,6 +1721,7 @@ assert_eq!(foo.load(Ordering::SeqCst), !(0x13 & 0x31)); #[$stable_nand] #[$cfg_cas] pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_nand(self.v.get(), val, order) } } } @@ -1734,6 +1757,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 0b111111); #[$stable] #[$cfg_cas] pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_or(self.v.get(), val, order) } } } @@ -1769,6 +1793,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 0b011110); #[$stable] #[$cfg_cas] pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type { + // SAFETY: data races are prevented by atomic intrinsics unsafe { atomic_xor(self.v.get(), val, order) } } } @@ -1880,6 +1905,7 @@ assert!(max_foo == 42); issue = "48655")] #[$cfg_cas] pub fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type { + // SAFETY: data races are prevented by atomic intrinsics unsafe { $max_fn(self.v.get(), val, order) } } } @@ -1932,6 +1958,7 @@ assert_eq!(min_foo, 12); issue = "48655")] #[$cfg_cas] pub fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type { + // SAFETY: data races are prevented by atomic intrinsics unsafe { $min_fn(self.v.get(), val, order) } } } @@ -2526,6 +2553,7 @@ pub fn fence(order: Ordering) { // https://github.com/WebAssembly/tool-conventions/issues/59. We should // follow that discussion and implement a solution when one comes about! #[cfg(not(target_arch = "wasm32"))] + // SAFETY: using an atomic fence is safe unsafe { match order { Acquire => intrinsics::atomic_fence_acq(), @@ -2613,6 +2641,7 @@ pub fn fence(order: Ordering) { #[inline] #[stable(feature = "compiler_fences", since = "1.21.0")] pub fn compiler_fence(order: Ordering) { + // SAFETY: doesn't compile to machine code unsafe { match order { Acquire => intrinsics::atomic_singlethreadfence_acq(), From a93e99cae7c1e6352304f65be93f28f1b5713231 Mon Sep 17 00:00:00 2001 From: Phoebe Bell Date: Tue, 19 Nov 2019 18:39:36 -0800 Subject: [PATCH 135/169] Fix typo "gurantees -> guarantees" --- src/libcore/cell.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index c530432f802db..f351735bef240 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -897,7 +897,7 @@ impl RefCell { #[inline] pub fn try_borrow_mut(&self) -> Result, BorrowMutError> { match BorrowRefMut::new(&self.borrow) { - // SAFETY: `BorrowRef` gurantees unique access + // SAFETY: `BorrowRef` guarantees unique access Some(b) => Ok(RefMut { value: unsafe { &mut *self.value.get() }, borrow: b }), None => Err(BorrowMutError { _private: () }), } From e0140ffeb0a7378f6568f5b8efebcfc58278f03a Mon Sep 17 00:00:00 2001 From: Phoebe Bell Date: Thu, 26 Dec 2019 11:57:57 -0800 Subject: [PATCH 136/169] Apply suggestions from code review Co-Authored-By: Ralf Jung --- src/libcore/str/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 3139d6188e27f..f89edf1910fac 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -659,7 +659,7 @@ impl<'a> Chars<'a> { #[stable(feature = "iter_to_slice", since = "1.4.0")] #[inline] pub fn as_str(&self) -> &'a str { - // SAFETY: Chars is only made from a str, which guarantees the iter is valid utf8 + // SAFETY: `Chars` is only made from a str, which guarantees the iter is valid utf8 unsafe { from_utf8_unchecked(self.iter.as_slice()) } } } From ca2fae8edbf0fce88e8e780d69745b26c856f4fc Mon Sep 17 00:00:00 2001 From: Phoebe Bell Date: Thu, 26 Dec 2019 12:56:34 -0800 Subject: [PATCH 137/169] Elaborate on SAFETY comments --- src/libcore/cell.rs | 25 +++++++++----- src/libcore/str/lossy.rs | 9 ++--- src/libcore/str/mod.rs | 67 +++++++++++++++++++------------------- src/libcore/sync/atomic.rs | 64 ++++++++++++++++++------------------ 4 files changed, 88 insertions(+), 77 deletions(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index f351735bef240..e7eecf7540ad7 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -366,7 +366,10 @@ impl Cell { if ptr::eq(self, other) { return; } - // SAFETY: not threadsafe, but it's OK since we know `Cell` isn't threadsafe + // SAFETY: This can be risky if called from separate threads, but `Cell` + // is `!Sync` so this won't happen. This also won't invalidate any + // pointers since `Cell` makes sure nothing else will be pointing into + // either of these `Cell`s. unsafe { ptr::swap(self.value.get(), other.value.get()); } @@ -386,7 +389,8 @@ impl Cell { /// ``` #[stable(feature = "move_cell", since = "1.17.0")] pub fn replace(&self, val: T) -> T { - // SAFETY: not threadsafe, but it's OK since we know `Cell` isn't threadsafe + // SAFETY: This can cause data races if called from a separate thread, + // but `Cell` is `!Sync` so this won't happen. mem::replace(unsafe { &mut *self.value.get() }, val) } @@ -423,7 +427,8 @@ impl Cell { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn get(&self) -> T { - // SAFETY: not threadsafe, but it's OK since we know `Cell` isn't threadsafe + // SAFETY: This can cause data races if called from a separate thread, + // but `Cell` is `!Sync` so this won't happen. unsafe { *self.value.get() } } @@ -492,7 +497,9 @@ impl Cell { #[inline] #[stable(feature = "cell_get_mut", since = "1.11.0")] pub fn get_mut(&mut self) -> &mut T { - // SAFETY: not threadsafe, but it's OK since we know `Cell` isn't threadsafe + // SAFETY: This can cause data races if called from a separate thread, + // but `Cell` is `!Sync` so this won't happen, and `&mut` guarantees + // unique access. unsafe { &mut *self.value.get() } } @@ -512,7 +519,7 @@ impl Cell { #[inline] #[stable(feature = "as_cell", since = "1.37.0")] pub fn from_mut(t: &mut T) -> &Cell { - // SAFETY: `&mut` ensures unique access + // SAFETY: `&mut` ensures unique access. unsafe { &*(t as *mut T as *const Cell) } } } @@ -556,7 +563,7 @@ impl Cell<[T]> { /// ``` #[stable(feature = "as_cell", since = "1.37.0")] pub fn as_slice_of_cells(&self) -> &[Cell] { - // SAFETY: `Cell` has the same memory layout as `T` + // SAFETY: `Cell` has the same memory layout as `T`. unsafe { &*(self as *const Cell<[T]> as *const [Cell]) } } } @@ -821,7 +828,7 @@ impl RefCell { pub fn try_borrow(&self) -> Result, BorrowError> { match BorrowRef::new(&self.borrow) { // SAFETY: `BorrowRef` ensures that there is only immutable access - // to the value while borrowed + // to the value while borrowed. Some(b) => Ok(Ref { value: unsafe { &*self.value.get() }, borrow: b }), None => Err(BorrowError { _private: () }), } @@ -897,7 +904,7 @@ impl RefCell { #[inline] pub fn try_borrow_mut(&self) -> Result, BorrowMutError> { match BorrowRefMut::new(&self.borrow) { - // SAFETY: `BorrowRef` guarantees unique access + // SAFETY: `BorrowRef` guarantees unique access. Some(b) => Ok(RefMut { value: unsafe { &mut *self.value.get() }, borrow: b }), None => Err(BorrowMutError { _private: () }), } @@ -947,7 +954,7 @@ impl RefCell { #[inline] #[stable(feature = "cell_get_mut", since = "1.11.0")] pub fn get_mut(&mut self) -> &mut T { - // SAFETY: `&mut` guarantees unique access + // SAFETY: `&mut` guarantees unique access. unsafe { &mut *self.value.get() } } diff --git a/src/libcore/str/lossy.rs b/src/libcore/str/lossy.rs index 9d2e38734ef02..88b2bc551b7d1 100644 --- a/src/libcore/str/lossy.rs +++ b/src/libcore/str/lossy.rs @@ -15,7 +15,7 @@ impl Utf8Lossy { } pub fn from_bytes(bytes: &[u8]) -> &Utf8Lossy { - // SAFETY: both use the same memory layout, and UTF-8 correctness isn't required + // SAFETY: Both use the same memory layout, and UTF-8 correctness isn't required. unsafe { mem::transmute(bytes) } } @@ -59,7 +59,8 @@ impl<'a> Iterator for Utf8LossyChunksIter<'a> { while i < self.source.len() { let i_ = i; - // SAFETY: 0 <= i < self.source.len() + // SAFETY: `i` starts at `0`, is less than `self.source.len()`, and + // only increases, so `0 <= i < self.source.len()`. let byte = unsafe { *self.source.get_unchecked(i) }; i += 1; @@ -69,7 +70,7 @@ impl<'a> Iterator for Utf8LossyChunksIter<'a> { macro_rules! error { () => {{ - // SAFETY: we have checked up to `i` that source is valid UTF-8 + // SAFETY: We have checked up to `i` that source is valid UTF-8. unsafe { let r = Utf8LossyChunk { valid: core_str::from_utf8_unchecked(&self.source[0..i_]), @@ -131,7 +132,7 @@ impl<'a> Iterator for Utf8LossyChunksIter<'a> { } let r = Utf8LossyChunk { - // SAFETY: we have checked that the entire source is valid UTF-8 + // SAFETY: We have checked that the entire source is valid UTF-8. valid: unsafe { core_str::from_utf8_unchecked(self.source) }, broken: &[], }; diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index f89edf1910fac..ec1713d1d4baa 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -340,7 +340,7 @@ impl Utf8Error { #[stable(feature = "rust1", since = "1.0.0")] pub fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> { run_utf8_validation(v)?; - // SAFETY: just ran validation + // SAFETY: Just ran validation. Ok(unsafe { from_utf8_unchecked(v) }) } @@ -379,7 +379,7 @@ pub fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> { #[stable(feature = "str_mut_extras", since = "1.20.0")] pub fn from_utf8_mut(v: &mut [u8]) -> Result<&mut str, Utf8Error> { run_utf8_validation(v)?; - // SAFETY: just ran validation + // SAFETY: Just ran validation. Ok(unsafe { from_utf8_unchecked_mut(v) }) } @@ -582,7 +582,7 @@ impl<'a> Iterator for Chars<'a> { #[inline] fn next(&mut self) -> Option { next_code_point(&mut self.iter).map(|ch| { - // SAFETY: str invariant says `ch` is a valid Unicode Scalar Value + // SAFETY: `str` invariant says `ch` is a valid Unicode Scalar Value. unsafe { char::from_u32_unchecked(ch) } }) } @@ -629,7 +629,7 @@ impl<'a> DoubleEndedIterator for Chars<'a> { #[inline] fn next_back(&mut self) -> Option { next_code_point_reverse(&mut self.iter).map(|ch| { - // SAFETY: str invariant says `ch` is a valid Unicode Scalar Value + // SAFETY: `str` invariant says `ch` is a valid Unicode Scalar Value. unsafe { char::from_u32_unchecked(ch) } }) } @@ -659,7 +659,7 @@ impl<'a> Chars<'a> { #[stable(feature = "iter_to_slice", since = "1.4.0")] #[inline] pub fn as_str(&self) -> &'a str { - // SAFETY: `Chars` is only made from a str, which guarantees the iter is valid utf8 + // SAFETY: `Chars` is only made from a str, which guarantees the iter is valid UTF-8. unsafe { from_utf8_unchecked(self.iter.as_slice()) } } } @@ -1104,7 +1104,7 @@ impl<'a, P: Pattern<'a>> SplitInternal<'a, P> { fn get_end(&mut self) -> Option<&'a str> { if !self.finished && (self.allow_trailing_empty || self.end - self.start > 0) { self.finished = true; - // SAFETY: `self.start` and `self.end` always lie on unicode boundaries + // SAFETY: `self.start` and `self.end` always lie on unicode boundaries. unsafe { let string = self.matcher.haystack().get_unchecked(self.start..self.end); Some(string) @@ -1122,7 +1122,7 @@ impl<'a, P: Pattern<'a>> SplitInternal<'a, P> { let haystack = self.matcher.haystack(); match self.matcher.next_match() { - // SAFETY: `Searcher` guarantees that `a` and `b` lie on unicode boundaries + // SAFETY: `Searcher` guarantees that `a` and `b` lie on unicode boundaries. Some((a, b)) => unsafe { let elt = haystack.get_unchecked(self.start..a); self.start = b; @@ -1155,13 +1155,13 @@ impl<'a, P: Pattern<'a>> SplitInternal<'a, P> { let haystack = self.matcher.haystack(); match self.matcher.next_match_back() { - // SAFETY: `Searcher` guarantees that `a` and `b` lie on unicode boundaries + // SAFETY: `Searcher` guarantees that `a` and `b` lie on unicode boundaries. Some((a, b)) => unsafe { let elt = haystack.get_unchecked(b..self.end); self.end = a; Some(elt) }, - // SAFETY: `self.start` and `self.end` always lie on unicode boundaries + // SAFETY: `self.start` and `self.end` always lie on unicode boundaries. None => unsafe { self.finished = true; Some(haystack.get_unchecked(self.start..self.end)) @@ -1301,7 +1301,7 @@ where impl<'a, P: Pattern<'a>> MatchIndicesInternal<'a, P> { #[inline] fn next(&mut self) -> Option<(usize, &'a str)> { - // SAFETY: `Searcher` guaratees that `start` and `end` lie on unicode boundaries + // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries. self.0 .next_match() .map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) }) @@ -1312,7 +1312,7 @@ impl<'a, P: Pattern<'a>> MatchIndicesInternal<'a, P> { where P::Searcher: ReverseSearcher<'a>, { - // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries + // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries. self.0 .next_match_back() .map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) }) @@ -1356,7 +1356,7 @@ where impl<'a, P: Pattern<'a>> MatchesInternal<'a, P> { #[inline] fn next(&mut self) -> Option<&'a str> { - // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries + // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries. self.0.next_match().map(|(a, b)| unsafe { // Indices are known to be on utf8 boundaries self.0.haystack().get_unchecked(a..b) @@ -1368,7 +1368,7 @@ impl<'a, P: Pattern<'a>> MatchesInternal<'a, P> { where P::Searcher: ReverseSearcher<'a>, { - // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries + // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries. self.0.next_match_back().map(|(a, b)| unsafe { // Indices are known to be on utf8 boundaries self.0.haystack().get_unchecked(a..b) @@ -1589,9 +1589,10 @@ fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> { if align != usize::max_value() && align.wrapping_sub(index) % usize_bytes == 0 { let ptr = v.as_ptr(); while index < blocks_end { - // SAFETY: since `align - index` and `ascii_block_size` are multiples of - // `usize_bytes`, `ptr.add(index)` is always aligned with a `usize` so we - // may cast directly to a `const` pointer. + // SAFETY: since `align - index` and `ascii_block_size` are + // multiples of `usize_bytes`, `block = ptr.add(index)` is + // always aligned with a `usize` so it's safe to dereference + // both `block` and `block.offset(1)`. unsafe { let block = ptr.add(index) as *const usize; // break if there is a nonascii byte @@ -1817,7 +1818,7 @@ mod traits { && slice.is_char_boundary(self.start) && slice.is_char_boundary(self.end) { - // SAFETY: just checked that `start` and `end` are on a char boundary + // SAFETY: just checked that `start` and `end` are on a char boundary. Some(unsafe { self.get_unchecked(slice) }) } else { None @@ -1829,7 +1830,7 @@ mod traits { && slice.is_char_boundary(self.start) && slice.is_char_boundary(self.end) { - // SAFETY: just checked that `start` and `end` are on a char boundary + // SAFETY: just checked that `start` and `end` are on a char boundary. Some(unsafe { self.get_unchecked_mut(slice) }) } else { None @@ -1860,7 +1861,7 @@ mod traits { && slice.is_char_boundary(self.start) && slice.is_char_boundary(self.end) { - // SAFETY: just checked that `start` and `end` are on a char boundary + // SAFETY: just checked that `start` and `end` are on a char boundary. unsafe { self.get_unchecked_mut(slice) } } else { super::slice_error_fail(slice, self.start, self.end) @@ -1889,7 +1890,7 @@ mod traits { #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { if slice.is_char_boundary(self.end) { - // SAFETY: just checked that `end` is on a char boundary + // SAFETY: just checked that `end` is on a char boundary. Some(unsafe { self.get_unchecked(slice) }) } else { None @@ -1898,7 +1899,7 @@ mod traits { #[inline] fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { if slice.is_char_boundary(self.end) { - // SAFETY: just checked that `end` is on a char boundary + // SAFETY: just checked that `end` is on a char boundary. Some(unsafe { self.get_unchecked_mut(slice) }) } else { None @@ -1922,7 +1923,7 @@ mod traits { #[inline] fn index_mut(self, slice: &mut str) -> &mut Self::Output { if slice.is_char_boundary(self.end) { - // SAFETY: just checked that `end` is on a char boundary + // SAFETY: just checked that `end` is on a char boundary. unsafe { self.get_unchecked_mut(slice) } } else { super::slice_error_fail(slice, 0, self.end) @@ -1952,7 +1953,7 @@ mod traits { #[inline] fn get(self, slice: &str) -> Option<&Self::Output> { if slice.is_char_boundary(self.start) { - // SAFETY: just checked that `start` is on a char boundary + // SAFETY: just checked that `start` is on a char boundary. Some(unsafe { self.get_unchecked(slice) }) } else { None @@ -1961,7 +1962,7 @@ mod traits { #[inline] fn get_mut(self, slice: &mut str) -> Option<&mut Self::Output> { if slice.is_char_boundary(self.start) { - // SAFETY: just checked that `start` is on a char boundary + // SAFETY: just checked that `start` is on a char boundary. Some(unsafe { self.get_unchecked_mut(slice) }) } else { None @@ -1987,7 +1988,7 @@ mod traits { #[inline] fn index_mut(self, slice: &mut str) -> &mut Self::Output { if slice.is_char_boundary(self.start) { - // SAFETY: just checked that `start` is on a char boundary + // SAFETY: just checked that `start` is on a char boundary. unsafe { self.get_unchecked_mut(slice) } } else { super::slice_error_fail(slice, self.start, slice.len()) @@ -2593,7 +2594,7 @@ impl str { pub fn split_at(&self, mid: usize) -> (&str, &str) { // is_char_boundary checks that the index is in [0, .len()] if self.is_char_boundary(mid) { - // SAFETY: just checked that `mid` is on a char boundary + // SAFETY: just checked that `mid` is on a char boundary. unsafe { (self.get_unchecked(0..mid), self.get_unchecked(mid..self.len())) } } else { slice_error_fail(self, 0, mid) @@ -2638,7 +2639,7 @@ impl str { if self.is_char_boundary(mid) { let len = self.len(); let ptr = self.as_mut_ptr(); - // SAFETY: just checked that `mid` is on a char boundary + // SAFETY: just checked that `mid` is on a char boundary. unsafe { ( from_utf8_unchecked_mut(slice::from_raw_parts_mut(ptr, mid)), @@ -3827,7 +3828,7 @@ impl str { if let Some((_, b)) = matcher.next_reject_back() { j = b; } - // SAFETY: `Searcher` is known to return valid indices + // SAFETY: `Searcher` is known to return valid indices. unsafe { self.get_unchecked(i..j) } @@ -3866,7 +3867,7 @@ impl str { if let Some((a, _)) = matcher.next_reject() { i = a; } - // SAFETY: `Searcher` is known to return valid indices + // SAFETY: `Searcher` is known to return valid indices. unsafe { self.get_unchecked(i..self.len()) } @@ -3992,7 +3993,7 @@ impl str { if let Some((_, b)) = matcher.next_reject_back() { j = b; } - // SAFETY: `Searcher` is known to return valid indices + // SAFETY: `Searcher` is known to return valid indices. unsafe { self.get_unchecked(0..j) } @@ -4188,7 +4189,7 @@ impl str { /// ``` #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] pub fn make_ascii_uppercase(&mut self) { - // SAFETY: safe because we transmute two types with the same layout + // SAFETY: safe because we transmute two types with the same layout. let me = unsafe { self.as_bytes_mut() }; me.make_ascii_uppercase() } @@ -4214,7 +4215,7 @@ impl str { /// ``` #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] pub fn make_ascii_lowercase(&mut self) { - // SAFETY: safe because we transmute two types with the same layout + // SAFETY: safe because we transmute two types with the same layout. let me = unsafe { self.as_bytes_mut() }; me.make_ascii_lowercase() } @@ -4380,7 +4381,7 @@ impl Default for &str { #[stable(feature = "default_mut_str", since = "1.28.0")] impl Default for &mut str { /// Creates an empty mutable str - // SAFETY: `str` is guranteed to be UTF-8 + // SAFETY: `str` is guranteed to be UTF-8. fn default() -> Self { unsafe { from_utf8_unchecked_mut(&mut []) } } diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index 889f182561b63..8d55dc55ef2d6 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -348,7 +348,7 @@ impl AtomicBool { #[inline] #[stable(feature = "atomic_access", since = "1.15.0")] pub fn get_mut(&mut self) -> &mut bool { - // SAFETY: the mutable reference guarantees unique ownership + // SAFETY: the mutable reference guarantees unique ownership. unsafe { &mut *(self.v.get() as *mut bool) } } @@ -399,7 +399,8 @@ impl AtomicBool { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn load(&self, order: Ordering) -> bool { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. unsafe { atomic_load(self.v.get(), order) != 0 } } @@ -432,7 +433,8 @@ impl AtomicBool { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn store(&self, val: bool, order: Ordering) { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: any data races are prevented by atomic intrinsics and the raw + // pointer passed in is valid because we got it from a reference. unsafe { atomic_store(self.v.get(), val as u8, order); } @@ -464,7 +466,7 @@ impl AtomicBool { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "8")] pub fn swap(&self, val: bool, order: Ordering) -> bool { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_swap(self.v.get(), val as u8, order) != 0 } } @@ -560,7 +562,7 @@ impl AtomicBool { success: Ordering, failure: Ordering, ) -> Result { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. match unsafe { atomic_compare_exchange(self.v.get(), current as u8, new as u8, success, failure) } { @@ -618,7 +620,7 @@ impl AtomicBool { success: Ordering, failure: Ordering, ) -> Result { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. match unsafe { atomic_compare_exchange_weak(self.v.get(), current as u8, new as u8, success, failure) } { @@ -665,7 +667,7 @@ impl AtomicBool { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "8")] pub fn fetch_and(&self, val: bool, order: Ordering) -> bool { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_and(self.v.get(), val as u8, order) != 0 } } @@ -761,7 +763,7 @@ impl AtomicBool { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "8")] pub fn fetch_or(&self, val: bool, order: Ordering) -> bool { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_or(self.v.get(), val as u8, order) != 0 } } @@ -803,7 +805,7 @@ impl AtomicBool { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "8")] pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_xor(self.v.get(), val as u8, order) != 0 } } @@ -879,7 +881,7 @@ impl AtomicPtr { #[inline] #[stable(feature = "atomic_access", since = "1.15.0")] pub fn get_mut(&mut self) -> &mut *mut T { - // SAFETY: the mutable reference guarantees unique ownership + // SAFETY: the mutable reference guarantees unique ownership. unsafe { &mut *self.p.get() } } @@ -931,7 +933,7 @@ impl AtomicPtr { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn load(&self, order: Ordering) -> *mut T { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_load(self.p.get() as *mut usize, order) as *mut T } } @@ -966,7 +968,7 @@ impl AtomicPtr { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn store(&self, ptr: *mut T, order: Ordering) { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_store(self.p.get() as *mut usize, ptr as usize, order); } @@ -1000,7 +1002,7 @@ impl AtomicPtr { #[stable(feature = "rust1", since = "1.0.0")] #[cfg(target_has_atomic = "ptr")] pub fn swap(&self, ptr: *mut T, order: Ordering) -> *mut T { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_swap(self.p.get() as *mut usize, ptr as usize, order) as *mut T } } @@ -1085,7 +1087,7 @@ impl AtomicPtr { success: Ordering, failure: Ordering, ) -> Result<*mut T, *mut T> { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { let res = atomic_compare_exchange( self.p.get() as *mut usize, @@ -1149,7 +1151,7 @@ impl AtomicPtr { success: Ordering, failure: Ordering, ) -> Result<*mut T, *mut T> { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { let res = atomic_compare_exchange_weak( self.p.get() as *mut usize, @@ -1303,7 +1305,7 @@ assert_eq!(some_var.load(Ordering::SeqCst), 5); #[inline] #[$stable_access] pub fn get_mut(&mut self) -> &mut $int_type { - // SAFETY: the mutable reference guarantees unique ownership + // SAFETY: the mutable reference guarantees unique ownership. unsafe { &mut *self.v.get() } } } @@ -1358,7 +1360,7 @@ assert_eq!(some_var.load(Ordering::Relaxed), 5); #[inline] #[$stable] pub fn load(&self, order: Ordering) -> $int_type { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_load(self.v.get(), order) } } } @@ -1393,7 +1395,7 @@ assert_eq!(some_var.load(Ordering::Relaxed), 10); #[inline] #[$stable] pub fn store(&self, val: $int_type, order: Ordering) { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_store(self.v.get(), val, order); } } } @@ -1424,7 +1426,7 @@ assert_eq!(some_var.swap(10, Ordering::Relaxed), 5); #[$stable] #[$cfg_cas] pub fn swap(&self, val: $int_type, order: Ordering) -> $int_type { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_swap(self.v.get(), val, order) } } } @@ -1527,7 +1529,7 @@ assert_eq!(some_var.load(Ordering::Relaxed), 10); new: $int_type, success: Ordering, failure: Ordering) -> Result<$int_type, $int_type> { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_compare_exchange(self.v.get(), current, new, success, failure) } } } @@ -1580,7 +1582,7 @@ loop { new: $int_type, success: Ordering, failure: Ordering) -> Result<$int_type, $int_type> { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_compare_exchange_weak(self.v.get(), current, new, success, failure) } @@ -1615,7 +1617,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 10); #[$stable] #[$cfg_cas] pub fn fetch_add(&self, val: $int_type, order: Ordering) -> $int_type { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_add(self.v.get(), val, order) } } } @@ -1648,7 +1650,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 10); #[$stable] #[$cfg_cas] pub fn fetch_sub(&self, val: $int_type, order: Ordering) -> $int_type { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_sub(self.v.get(), val, order) } } } @@ -1684,7 +1686,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 0b100001); #[$stable] #[$cfg_cas] pub fn fetch_and(&self, val: $int_type, order: Ordering) -> $int_type { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_and(self.v.get(), val, order) } } } @@ -1721,7 +1723,7 @@ assert_eq!(foo.load(Ordering::SeqCst), !(0x13 & 0x31)); #[$stable_nand] #[$cfg_cas] pub fn fetch_nand(&self, val: $int_type, order: Ordering) -> $int_type { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_nand(self.v.get(), val, order) } } } @@ -1757,7 +1759,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 0b111111); #[$stable] #[$cfg_cas] pub fn fetch_or(&self, val: $int_type, order: Ordering) -> $int_type { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_or(self.v.get(), val, order) } } } @@ -1793,7 +1795,7 @@ assert_eq!(foo.load(Ordering::SeqCst), 0b011110); #[$stable] #[$cfg_cas] pub fn fetch_xor(&self, val: $int_type, order: Ordering) -> $int_type { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { atomic_xor(self.v.get(), val, order) } } } @@ -1905,7 +1907,7 @@ assert!(max_foo == 42); issue = "48655")] #[$cfg_cas] pub fn fetch_max(&self, val: $int_type, order: Ordering) -> $int_type { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { $max_fn(self.v.get(), val, order) } } } @@ -1958,7 +1960,7 @@ assert_eq!(min_foo, 12); issue = "48655")] #[$cfg_cas] pub fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type { - // SAFETY: data races are prevented by atomic intrinsics + // SAFETY: data races are prevented by atomic intrinsics. unsafe { $min_fn(self.v.get(), val, order) } } } @@ -2553,7 +2555,7 @@ pub fn fence(order: Ordering) { // https://github.com/WebAssembly/tool-conventions/issues/59. We should // follow that discussion and implement a solution when one comes about! #[cfg(not(target_arch = "wasm32"))] - // SAFETY: using an atomic fence is safe + // SAFETY: using an atomic fence is safe. unsafe { match order { Acquire => intrinsics::atomic_fence_acq(), @@ -2641,7 +2643,7 @@ pub fn fence(order: Ordering) { #[inline] #[stable(feature = "compiler_fences", since = "1.21.0")] pub fn compiler_fence(order: Ordering) { - // SAFETY: doesn't compile to machine code + // SAFETY: using an atomic fence is safe. unsafe { match order { Acquire => intrinsics::atomic_singlethreadfence_acq(), From c103c284b93039149f0ec2a4f3d20ca89f34c0ad Mon Sep 17 00:00:00 2001 From: Phoebe Bell Date: Thu, 16 Jan 2020 18:38:04 -0800 Subject: [PATCH 138/169] Move comments for tidy --- src/libcore/str/mod.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index ec1713d1d4baa..3bfeee87cc013 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1301,9 +1301,9 @@ where impl<'a, P: Pattern<'a>> MatchIndicesInternal<'a, P> { #[inline] fn next(&mut self) -> Option<(usize, &'a str)> { - // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries. self.0 .next_match() + // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries. .map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) }) } @@ -1312,9 +1312,9 @@ impl<'a, P: Pattern<'a>> MatchIndicesInternal<'a, P> { where P::Searcher: ReverseSearcher<'a>, { - // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries. self.0 .next_match_back() + // SAFETY: `Searcher` guarantees that `start` and `end` lie on unicode boundaries. .map(|(start, end)| unsafe { (start, self.0.haystack().get_unchecked(start..end)) }) } } @@ -3901,8 +3901,8 @@ impl str { "The first search step from Searcher \ must include the first character" ); + // SAFETY: `Searcher` is known to return valid indices. unsafe { - // Searcher is known to return valid indices. Some(self.get_unchecked(len..)) } } else { @@ -3942,8 +3942,8 @@ impl str { "The first search step from ReverseSearcher \ must include the last character" ); + // SAFETY: `Searcher` is known to return valid indices. unsafe { - // Searcher is known to return valid indices. Some(self.get_unchecked(..start)) } } else { @@ -4381,8 +4381,8 @@ impl Default for &str { #[stable(feature = "default_mut_str", since = "1.28.0")] impl Default for &mut str { /// Creates an empty mutable str - // SAFETY: `str` is guranteed to be UTF-8. fn default() -> Self { + // SAFETY: The empty string is valid UTF-8. unsafe { from_utf8_unchecked_mut(&mut []) } } } From 0f2ee495e9a9d677466ce0c1827ba20919a5ca1f Mon Sep 17 00:00:00 2001 From: Phoebe Bell Date: Thu, 16 Jan 2020 18:50:53 -0800 Subject: [PATCH 139/169] Fix formatting: ./x.py fmt --- src/libcore/str/mod.rs | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 3bfeee87cc013..5a7cddd4041d5 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -3829,9 +3829,7 @@ impl str { j = b; } // SAFETY: `Searcher` is known to return valid indices. - unsafe { - self.get_unchecked(i..j) - } + unsafe { self.get_unchecked(i..j) } } /// Returns a string slice with all prefixes that match a pattern @@ -3868,9 +3866,7 @@ impl str { i = a; } // SAFETY: `Searcher` is known to return valid indices. - unsafe { - self.get_unchecked(i..self.len()) - } + unsafe { self.get_unchecked(i..self.len()) } } /// Returns a string slice with the prefix removed. @@ -3902,9 +3898,7 @@ impl str { must include the first character" ); // SAFETY: `Searcher` is known to return valid indices. - unsafe { - Some(self.get_unchecked(len..)) - } + unsafe { Some(self.get_unchecked(len..)) } } else { None } @@ -3943,9 +3937,7 @@ impl str { must include the last character" ); // SAFETY: `Searcher` is known to return valid indices. - unsafe { - Some(self.get_unchecked(..start)) - } + unsafe { Some(self.get_unchecked(..start)) } } else { None } @@ -3994,9 +3986,7 @@ impl str { j = b; } // SAFETY: `Searcher` is known to return valid indices. - unsafe { - self.get_unchecked(0..j) - } + unsafe { self.get_unchecked(0..j) } } /// Returns a string slice with all prefixes that match a pattern From 03240e1359f68bdddcdb236f3a89f9907b907449 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 16 Jan 2020 18:27:18 -0800 Subject: [PATCH 140/169] review comments --- src/librustc_errors/emitter.rs | 9 ++++---- src/librustc_errors/lib.rs | 21 ++++++++----------- .../miri_unleashed/mutable_const2.stderr | 2 +- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index e37496f729952..b0e0cb611afaf 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -1475,7 +1475,11 @@ impl EmitterWriter { Some(ref sm) => sm, None => return Ok(()), }; - if !suggestion.has_valid_spans(&**sm) { + + // Render the replacements for each suggestion + let suggestions = suggestion.splice_lines(&**sm); + + if suggestions.is_empty() { // Suggestions coming from macros can have malformed spans. This is a heavy handed // approach to avoid ICEs by ignoring the suggestion outright. return Ok(()); @@ -1497,9 +1501,6 @@ impl EmitterWriter { Some(Style::HeaderMsg), ); - // Render the replacements for each suggestion - let suggestions = suggestion.splice_lines(&**sm); - let mut row_num = 2; let mut notice_capitalization = false; for (complete, parts, only_capitalization) in suggestions.iter().take(MAX_SUGGESTIONS) { diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 889c84d6da132..827e9b831f32d 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -144,18 +144,6 @@ pub struct SubstitutionPart { } impl CodeSuggestion { - /// Suggestions coming from macros can have malformed spans. This is a heavy handed approach - /// to avoid ICEs by ignoring the suggestion outright. - pub fn has_valid_spans(&self, cm: &SourceMap) -> bool { - !self.substitutions.iter().any(|subst| { - let invalid = subst.parts.iter().any(|item| cm.is_valid_span(item.span).is_err()); - if invalid { - debug!("malformed span in suggestion: {:?}", subst); - } - invalid - }) - } - /// Returns the assembled code suggestions, whether they should be shown with an underline /// and whether the substitution only differs in capitalization. pub fn splice_lines(&self, cm: &SourceMap) -> Vec<(String, Vec, bool)> { @@ -187,6 +175,15 @@ impl CodeSuggestion { self.substitutions .iter() + .filter(|subst| { + // Suggestions coming from macros can have malformed spans. This is a heavy + // handed approach to avoid ICEs by ignoring the suggestion outright. + let invalid = subst.parts.iter().any(|item| cm.is_valid_span(item.span).is_err()); + if invalid { + debug!("splice_lines: suggestion contains an invalid span: {:?}", subst); + } + !invalid + }) .cloned() .map(|mut substitution| { // Assumption: all spans are in the same file, and all spans diff --git a/src/test/ui/consts/miri_unleashed/mutable_const2.stderr b/src/test/ui/consts/miri_unleashed/mutable_const2.stderr index cc124058cfcb8..0d7fb845a40ee 100644 --- a/src/test/ui/consts/miri_unleashed/mutable_const2.stderr +++ b/src/test/ui/consts/miri_unleashed/mutable_const2.stderr @@ -10,7 +10,7 @@ error: internal compiler error: mutable allocation in constant LL | const MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:359:17 +thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:356:17 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace error: internal compiler error: unexpected panic From 022a7de26f5cb386ec853eec3b7f44dcd516a6d1 Mon Sep 17 00:00:00 2001 From: Phoebe Bell Date: Thu, 16 Jan 2020 19:26:02 -0800 Subject: [PATCH 141/169] Add SAFETY comment for atomic example --- src/libcore/sync/atomic.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libcore/sync/atomic.rs b/src/libcore/sync/atomic.rs index 8d55dc55ef2d6..9d449bb991507 100644 --- a/src/libcore/sync/atomic.rs +++ b/src/libcore/sync/atomic.rs @@ -1989,7 +1989,9 @@ extern { } let mut atomic = ", stringify!($atomic_type), "::new(1); -unsafe { +", +// SAFETY: Safe as long as `my_atomic_op` is atomic. +"unsafe { my_atomic_op(atomic.as_mut_ptr()); } # } From b1d0c118ff726fc8c5ff2a5a19840a9e36e8940e Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Thu, 16 Jan 2020 08:24:34 -0500 Subject: [PATCH 142/169] [self-profiler] Add example to `-Z help` to turn on query key recording Also add the `default` option so that it's easy to add query key recording to the default. --- src/librustc_data_structures/profiling.rs | 2 ++ src/librustc_session/options.rs | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/librustc_data_structures/profiling.rs b/src/librustc_data_structures/profiling.rs index 004db0a79a880..44cef727f034b 100644 --- a/src/librustc_data_structures/profiling.rs +++ b/src/librustc_data_structures/profiling.rs @@ -136,9 +136,11 @@ bitflags::bitflags! { } } +// keep this in sync with the `-Z self-profile-events` help message in librustc_session/options.rs const EVENT_FILTERS_BY_NAME: &[(&str, EventFilter)] = &[ ("none", EventFilter::NONE), ("all", EventFilter::ALL), + ("default", EventFilter::DEFAULT), ("generic-activity", EventFilter::GENERIC_ACTIVITIES), ("query-provider", EventFilter::QUERY_PROVIDERS), ("query-cache-hit", EventFilter::QUERY_CACHE_HITS), diff --git a/src/librustc_session/options.rs b/src/librustc_session/options.rs index 4b5736adc17c3..2a0ed27b63b08 100644 --- a/src/librustc_session/options.rs +++ b/src/librustc_session/options.rs @@ -923,8 +923,12 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, self_profile: SwitchWithOptPath = (SwitchWithOptPath::Disabled, parse_switch_with_opt_path, [UNTRACKED], "run the self profiler and output the raw event data"), + // keep this in sync with the event filter names in librustc_data_structures/profiling.rs self_profile_events: Option> = (None, parse_opt_comma_list, [UNTRACKED], - "specifies which kinds of events get recorded by the self profiler"), + "specifies which kinds of events get recorded by the self profiler; + for example: `-Z self-profile-events=default,query-keys` + all options: none, all, default, generic-activity, query-provider, query-cache-hit + query-blocked, incr-cache-load, query-keys"), emit_stack_sizes: bool = (false, parse_bool, [UNTRACKED], "emits a section containing stack size metadata"), plt: Option = (None, parse_opt_bool, [TRACKED], From 343eee6082a90016b315b82b048e5a6774472afe Mon Sep 17 00:00:00 2001 From: Markus Westerlind Date: Tue, 7 Jan 2020 21:45:49 +0100 Subject: [PATCH 143/169] perf: Filter out and process fixed constraints first in region expansion Should reduce the number of elements as well as branches in the extremely hot loop and process_constraint in benchmarks such as unicode_normalization --- .../infer/lexical_region_resolve/mod.rs | 49 +++++++++++++------ 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index 0bc49a2901505..f4c1965a04179 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -295,30 +295,49 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } fn expansion(&self, var_values: &mut LexicalRegionResolutions<'tcx>) { - let mut process_constraint = |constraint: &Constraint<'tcx>| { - let (a_region, b_vid, b_data, retain) = match *constraint { + let mut changed = false; + let mut constraints = Vec::new(); + for constraint in self.data.constraints.keys() { + let (a_region, b_vid, b_data) = match *constraint { Constraint::RegSubVar(a_region, b_vid) => { let b_data = var_values.value_mut(b_vid); - (a_region, b_vid, b_data, false) + (a_region, b_vid, b_data) } Constraint::VarSubVar(a_vid, b_vid) => match *var_values.value(a_vid) { - VarValue::ErrorValue => return (false, false), + VarValue::ErrorValue => continue, VarValue::Value(a_region) => { let b_data = var_values.value_mut(b_vid); - let retain = match *b_data { - VarValue::Value(ReStatic) | VarValue::ErrorValue => false, - _ => true, - }; - (a_region, b_vid, b_data, retain) + match *b_data { + VarValue::Value(ReStatic) | VarValue::ErrorValue => (), + _ => constraints.push((a_vid, b_vid)), + } + (a_region, b_vid, b_data) } }, Constraint::RegSubReg(..) | Constraint::VarSubReg(..) => { // These constraints are checked after expansion // is done, in `collect_errors`. - return (false, false); + continue; } }; + let edge_changed = self.expand_node(a_region, b_vid, b_data); + if edge_changed { + changed = true + } + } + let mut process_constraint = |a_vid, b_vid| { + let (a_region, b_data, retain) = match *var_values.value(a_vid) { + VarValue::ErrorValue => return (false, false), + VarValue::Value(a_region) => { + let b_data = var_values.value_mut(b_vid); + let retain = match *b_data { + VarValue::Value(ReStatic) | VarValue::ErrorValue => false, + _ => true, + }; + (a_region, b_data, retain) + } + }; let changed = self.expand_node(a_region, b_vid, b_data); (changed, retain) }; @@ -326,15 +345,13 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { // Using bitsets to track the remaining elements is faster than using a // `Vec` by itself (which requires removing elements, which requires // element shuffling, which is slow). - let constraints: Vec<_> = self.data.constraints.keys().collect(); let mut live_indices: BitSet = BitSet::new_filled(constraints.len()); let mut killed_indices: BitSet = BitSet::new_empty(constraints.len()); - let mut changed = true; while changed { changed = false; for index in live_indices.iter() { - let constraint = constraints[index]; - let (edge_changed, retain) = process_constraint(constraint); + let (a_vid, b_vid) = constraints[index]; + let (edge_changed, retain) = process_constraint(a_vid, b_vid); changed |= edge_changed; if !retain { let changed = killed_indices.insert(index); @@ -790,8 +807,8 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { self.var_infos[node_idx].origin.span(), &format!( "collect_error_for_expanding_node() could not find \ - error for var {:?} in universe {:?}, lower_bounds={:#?}, \ - upper_bounds={:#?}", + error for var {:?} in universe {:?}, lower_bounds={:#?}, \ + upper_bounds={:#?}", node_idx, node_universe, lower_bounds, upper_bounds ), ); From 917eb187905591c5470cca3e742c17b0fbb495a2 Mon Sep 17 00:00:00 2001 From: Markus Westerlind Date: Wed, 8 Jan 2020 10:35:51 +0100 Subject: [PATCH 144/169] perf: Only search the potentially changed constraints in lexical_region_resolve --- .../infer/lexical_region_resolve/mod.rs | 79 +++++++------------ 1 file changed, 29 insertions(+), 50 deletions(-) diff --git a/src/librustc/infer/lexical_region_resolve/mod.rs b/src/librustc/infer/lexical_region_resolve/mod.rs index f4c1965a04179..18c25ef0dd9e1 100644 --- a/src/librustc/infer/lexical_region_resolve/mod.rs +++ b/src/librustc/infer/lexical_region_resolve/mod.rs @@ -19,7 +19,6 @@ use rustc_data_structures::graph::implementation::{ Direction, Graph, NodeIndex, INCOMING, OUTGOING, }; use rustc_hir::def_id::DefId; -use rustc_index::bit_set::BitSet; use rustc_index::vec::{Idx, IndexVec}; use rustc_span::Span; use std::fmt; @@ -295,23 +294,19 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } fn expansion(&self, var_values: &mut LexicalRegionResolutions<'tcx>) { - let mut changed = false; - let mut constraints = Vec::new(); + let mut constraints = IndexVec::from_elem_n(Vec::new(), var_values.values.len()); + let mut changes = Vec::new(); for constraint in self.data.constraints.keys() { - let (a_region, b_vid, b_data) = match *constraint { + let (a_vid, a_region, b_vid, b_data) = match *constraint { Constraint::RegSubVar(a_region, b_vid) => { let b_data = var_values.value_mut(b_vid); - (a_region, b_vid, b_data) + (None, a_region, b_vid, b_data) } Constraint::VarSubVar(a_vid, b_vid) => match *var_values.value(a_vid) { VarValue::ErrorValue => continue, VarValue::Value(a_region) => { let b_data = var_values.value_mut(b_vid); - match *b_data { - VarValue::Value(ReStatic) | VarValue::ErrorValue => (), - _ => constraints.push((a_vid, b_vid)), - } - (a_region, b_vid, b_data) + (Some(a_vid), a_region, b_vid, b_data) } }, Constraint::RegSubReg(..) | Constraint::VarSubReg(..) => { @@ -320,54 +315,38 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { continue; } }; - let edge_changed = self.expand_node(a_region, b_vid, b_data); - if edge_changed { - changed = true + if self.expand_node(a_region, b_vid, b_data) { + changes.push(b_vid); + } + if let Some(a_vid) = a_vid { + match *b_data { + VarValue::Value(ReStatic) | VarValue::ErrorValue => (), + _ => { + constraints[a_vid].push((a_vid, b_vid)); + constraints[b_vid].push((a_vid, b_vid)); + } + } } } - let mut process_constraint = |a_vid, b_vid| { - let (a_region, b_data, retain) = match *var_values.value(a_vid) { - VarValue::ErrorValue => return (false, false), - VarValue::Value(a_region) => { - let b_data = var_values.value_mut(b_vid); - let retain = match *b_data { - VarValue::Value(ReStatic) | VarValue::ErrorValue => false, - _ => true, - }; - (a_region, b_data, retain) + while let Some(vid) = changes.pop() { + constraints[vid].retain(|&(a_vid, b_vid)| { + let a_region = match *var_values.value(a_vid) { + VarValue::ErrorValue => return false, + VarValue::Value(a_region) => a_region, + }; + let b_data = var_values.value_mut(b_vid); + if self.expand_node(a_region, b_vid, b_data) { + changes.push(b_vid); } - }; - let changed = self.expand_node(a_region, b_vid, b_data); - (changed, retain) - }; - - // Using bitsets to track the remaining elements is faster than using a - // `Vec` by itself (which requires removing elements, which requires - // element shuffling, which is slow). - let mut live_indices: BitSet = BitSet::new_filled(constraints.len()); - let mut killed_indices: BitSet = BitSet::new_empty(constraints.len()); - while changed { - changed = false; - for index in live_indices.iter() { - let (a_vid, b_vid) = constraints[index]; - let (edge_changed, retain) = process_constraint(a_vid, b_vid); - changed |= edge_changed; - if !retain { - let changed = killed_indices.insert(index); - debug_assert!(changed); + match *b_data { + VarValue::Value(ReStatic) | VarValue::ErrorValue => false, + _ => true, } - } - live_indices.subtract(&killed_indices); - - // We could clear `killed_indices` here, but we don't need to and - // it's cheaper not to. + }); } } - // This function is very hot in some workloads. There's a single callsite - // so always inlining is ok even though it's large. - #[inline(always)] fn expand_node( &self, a_region: Region<'tcx>, From cdc828e7f92c5835db4188f27cbdb7170d32c94e Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 17 Jan 2020 17:09:05 +0100 Subject: [PATCH 145/169] Stop treating `FalseEdges` and `FalseUnwind` as having semantic value for const eval --- .../transform/qualify_min_const_fn.rs | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index 7034556740849..d927553c72e8b 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -309,7 +309,11 @@ fn check_terminator( ) -> McfResult { let span = terminator.source_info.span; match &terminator.kind { - TerminatorKind::Goto { .. } | TerminatorKind::Return | TerminatorKind::Resume => Ok(()), + TerminatorKind::FalseEdges { .. } + | TerminatorKind::FalseUnwind { .. } + | TerminatorKind::Goto { .. } + | TerminatorKind::Return + | TerminatorKind::Resume => Ok(()), TerminatorKind::Drop { location, .. } => check_place(tcx, location, span, def_id, body), TerminatorKind::DropAndReplace { location, value, .. } => { @@ -317,13 +321,10 @@ fn check_terminator( check_operand(tcx, value, span, def_id, body) } - TerminatorKind::FalseEdges { .. } | TerminatorKind::SwitchInt { .. } - if !feature_allowed(tcx, def_id, sym::const_if_match) => - { + TerminatorKind::SwitchInt { .. } if !feature_allowed(tcx, def_id, sym::const_if_match) => { Err((span, "loops and conditional expressions are not stable in const fn".into())) } - TerminatorKind::FalseEdges { .. } => Ok(()), TerminatorKind::SwitchInt { discr, switch_ty: _, values: _, targets: _ } => { check_operand(tcx, discr, span, def_id, body) } @@ -367,13 +368,5 @@ fn check_terminator( TerminatorKind::Assert { cond, expected: _, msg: _, target: _, cleanup: _ } => { check_operand(tcx, cond, span, def_id, body) } - - TerminatorKind::FalseUnwind { .. } if feature_allowed(tcx, def_id, sym::const_loop) => { - Ok(()) - } - - TerminatorKind::FalseUnwind { .. } => { - Err((span, "loops are not allowed in const fn".into())) - } } } From a91f77ca26f65e566b93a0f086a894e60ec7c257 Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 17 Jan 2020 14:21:14 +0000 Subject: [PATCH 146/169] Add regression test for integer literals in generic arguments in where clauses --- ...eger-literal-generic-arg-in-where-clause.rs | 18 ++++++++++++++++++ ...-literal-generic-arg-in-where-clause.stderr | 8 ++++++++ 2 files changed, 26 insertions(+) create mode 100644 src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.rs create mode 100644 src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.stderr diff --git a/src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.rs b/src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.rs new file mode 100644 index 0000000000000..30fbfda112c55 --- /dev/null +++ b/src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.rs @@ -0,0 +1,18 @@ +// check-pass + +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash + +fn takes_closure_of_array_3(f: F) where F: Fn([i32; 3]) { + f([1, 2, 3]); +} + +fn takes_closure_of_array_3_apit(f: impl Fn([i32; 3])) { + f([1, 2, 3]); +} + +fn returns_closure_of_array_3() -> impl Fn([i32; 3]) { + |_| {} +} + +fn main() {} diff --git a/src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.stderr b/src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.stderr new file mode 100644 index 0000000000000..7f37f3e2791ec --- /dev/null +++ b/src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.stderr @@ -0,0 +1,8 @@ +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/integer-literal-generic-arg-in-where-clause.rs:3:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + From 9c6c2f16f00ed6f24866d2d4927b49d79b453a23 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 16 Jan 2020 14:35:37 +0100 Subject: [PATCH 147/169] Clean up E0198 explanation --- src/librustc_error_codes/error_codes/E0198.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0198.md b/src/librustc_error_codes/error_codes/E0198.md index 6504d60dbd1d5..687214a205096 100644 --- a/src/librustc_error_codes/error_codes/E0198.md +++ b/src/librustc_error_codes/error_codes/E0198.md @@ -1,17 +1,18 @@ -A negative implementation is one that excludes a type from implementing a -particular trait. Not being able to use a trait is always a safe operation, -so negative implementations are always safe and never need to be marked as -unsafe. +A negative implementation was marked as unsafe. -```compile_fail -#![feature(optin_builtin_traits)] +Erroneous code example: +```compile_fail struct Foo; -// unsafe is unnecessary -unsafe impl !Clone for Foo { } +unsafe impl !Clone for Foo { } // error! ``` +A negative implementation is one that excludes a type from implementing a +particular trait. Not being able to use a trait is always a safe operation, +so negative implementations are always safe and never need to be marked as +unsafe. + This will compile: ```ignore (ignore auto_trait future compatibility warning) From 298e8ad5dc79ecb9b5b6140499e950d6ac5f09b1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 17 Jan 2020 19:49:03 +0100 Subject: [PATCH 148/169] Extend url in heading test a bit --- src/test/rustdoc/remove-url-from-headings.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/rustdoc/remove-url-from-headings.rs b/src/test/rustdoc/remove-url-from-headings.rs index 50e45a7f53a1e..9761c1ddbe23f 100644 --- a/src/test/rustdoc/remove-url-from-headings.rs +++ b/src/test/rustdoc/remove-url-from-headings.rs @@ -7,7 +7,7 @@ /// fooo /// -/// # Implementing [stuff](http://a.a) somewhere +/// # Implementing [stuff](http://a.a "title") somewhere /// /// hello /// From 482dc77dee59dd44448973758980806bd63aa5a3 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 17 Jan 2020 19:51:07 +0100 Subject: [PATCH 149/169] formatting --- src/librustdoc/clean/mod.rs | 40 ++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 0e9f363bec3f3..20a5a6c54984d 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2121,27 +2121,25 @@ impl Clean> for doctree::Impl<'_> { Some(DefKind::TyAlias) => Some(cx.tcx.type_of(did).clean(cx)), _ => None, }); - let make_item = |trait_: Option, for_: Type, items: Vec| { - Item { - name: None, - attrs: self.attrs.clean(cx), - source: self.whence.clean(cx), - def_id, - visibility: self.vis.clean(cx), - stability: cx.stability(self.id).clean(cx), - deprecation: cx.deprecation(self.id).clean(cx), - inner: ImplItem(Impl { - unsafety: self.unsafety, - generics: self.generics.clean(cx), - provided_trait_methods: provided.clone(), - trait_, - for_, - items, - polarity: Some(cx.tcx.impl_polarity(def_id).clean(cx)), - synthetic: false, - blanket_impl: None, - }), - } + let make_item = |trait_: Option, for_: Type, items: Vec| Item { + name: None, + attrs: self.attrs.clean(cx), + source: self.whence.clean(cx), + def_id, + visibility: self.vis.clean(cx), + stability: cx.stability(self.id).clean(cx), + deprecation: cx.deprecation(self.id).clean(cx), + inner: ImplItem(Impl { + unsafety: self.unsafety, + generics: self.generics.clean(cx), + provided_trait_methods: provided.clone(), + trait_, + for_, + items, + polarity: Some(cx.tcx.impl_polarity(def_id).clean(cx)), + synthetic: false, + blanket_impl: None, + }), }; if let Some(type_alias) = type_alias { ret.push(make_item(trait_.clone(), type_alias, items.clone())); From e8a4b9319cbf5b3f56b3cdd8ad11e86ff7168345 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 17 Jan 2020 19:54:07 +0100 Subject: [PATCH 150/169] Clean up E0199 explanation --- src/librustc_error_codes/error_codes/E0199.md | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0199.md b/src/librustc_error_codes/error_codes/E0199.md index d0c12dc6f1755..88130e8e5e596 100644 --- a/src/librustc_error_codes/error_codes/E0199.md +++ b/src/librustc_error_codes/error_codes/E0199.md @@ -1,14 +1,23 @@ +A trait implementation was marked as unsafe while the trait is safe. + +Erroneous code example: + +```compile_fail,E0199 +struct Foo; + +trait Bar { } + +unsafe impl Bar for Foo { } // error! +``` + Safe traits should not have unsafe implementations, therefore marking an implementation for a safe trait unsafe will cause a compiler error. Removing -the unsafe marker on the trait noted in the error will resolve this problem. +the unsafe marker on the trait noted in the error will resolve this problem: -```compile_fail,E0199 +``` struct Foo; trait Bar { } -// this won't compile because Bar is safe -unsafe impl Bar for Foo { } -// this will compile -impl Bar for Foo { } +impl Bar for Foo { } // ok! ``` From d461e6d6cbd0c716f8b7e951285507451611df59 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 13 Jan 2020 20:30:20 -0800 Subject: [PATCH 151/169] Use named fields for `ast::ItemKind::Impl` --- src/librustc/hir/map/mod.rs | 2 +- src/librustc_ast_lowering/item.rs | 21 ++++++++-------- src/librustc_ast_passes/ast_validation.rs | 24 +++++++++++++++---- src/librustc_ast_passes/feature_gate.rs | 2 +- .../deriving/generic/mod.rs | 16 ++++++------- src/librustc_builtin_macros/deriving/mod.rs | 16 ++++++------- src/librustc_lint/builtin.rs | 2 +- src/librustc_lint/internal.rs | 2 +- src/librustc_parse/parser/item.rs | 20 ++++++++-------- src/librustc_resolve/build_reduced_graph.rs | 2 +- src/librustc_resolve/def_collector.rs | 2 +- src/librustc_resolve/late.rs | 16 ++++++------- src/librustc_save_analysis/dump_visitor.rs | 4 ++-- src/librustc_save_analysis/lib.rs | 12 +++++----- src/librustc_save_analysis/sig.rs | 14 +++++------ src/libsyntax/ast.rs | 23 ++++++++++-------- src/libsyntax/mut_visit.rs | 14 ++++++++--- src/libsyntax/print/pprust.rs | 16 ++++++------- src/libsyntax/visit.rs | 16 +++++++++---- 19 files changed, 130 insertions(+), 94 deletions(-) diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 46c5ee272d235..8b4f0c6bde2b5 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -821,7 +821,7 @@ impl<'hir> Map<'hir> { | ItemKind::Struct(..) | ItemKind::Union(..) | ItemKind::Trait(..) - | ItemKind::Impl(..) => true, + | ItemKind::Impl { .. } => true, _ => false, }, Node::ForeignItem(fi) => match fi.kind { diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs index beb53a19ac4ff..648c4f7e46aad 100644 --- a/src/librustc_ast_lowering/item.rs +++ b/src/librustc_ast_lowering/item.rs @@ -67,14 +67,15 @@ impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> { if let Some(hir_id) = item_hir_id { self.lctx.with_parent_item_lifetime_defs(hir_id, |this| { let this = &mut ItemLowerer { lctx: this }; - if let ItemKind::Impl(.., ref opt_trait_ref, _, _) = item.kind { - if opt_trait_ref.as_ref().map(|tr| tr.constness.is_some()).unwrap_or(false) { + if let ItemKind::Impl { ref of_trait, .. } = item.kind { + if of_trait.as_ref().map(|tr| tr.constness.is_some()).unwrap_or(false) { + this.with_trait_impl_ref(of_trait, |this| visit::walk_item(this, item)); this.lctx .diagnostic() .span_err(item.span, "const trait impls are not yet implemented"); } - this.with_trait_impl_ref(opt_trait_ref, |this| visit::walk_item(this, item)); + this.with_trait_impl_ref(of_trait, |this| visit::walk_item(this, item)); } else { visit::walk_item(this, item); } @@ -173,7 +174,7 @@ impl<'hir> LoweringContext<'_, 'hir> { vec } ItemKind::MacroDef(..) => SmallVec::new(), - ItemKind::Fn(..) | ItemKind::Impl(.., None, _, _) => smallvec![i.id], + ItemKind::Fn(..) | ItemKind::Impl { of_trait: None, .. } => smallvec![i.id], ItemKind::Static(ref ty, ..) => { let mut ids = smallvec![i.id]; if self.sess.features_untracked().impl_trait_in_bindings { @@ -361,15 +362,15 @@ impl<'hir> LoweringContext<'_, 'hir> { self.lower_generics(generics, ImplTraitContext::disallowed()), ) } - ItemKind::Impl( + ItemKind::Impl { unsafety, polarity, defaultness, - ref ast_generics, - ref trait_ref, - ref ty, - ref impl_items, - ) => { + generics: ref ast_generics, + of_trait: ref trait_ref, + self_ty: ref ty, + items: ref impl_items, + } => { let def_id = self.resolver.definitions().local_def_id(id); // Lower the "impl header" first. This ordering is important diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs index c915b7ba21692..23701459025ae 100644 --- a/src/librustc_ast_passes/ast_validation.rs +++ b/src/librustc_ast_passes/ast_validation.rs @@ -612,9 +612,17 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } match item.kind { - ItemKind::Impl(unsafety, polarity, _, _, Some(..), ref ty, ref impl_items) => { + ItemKind::Impl { + unsafety, + polarity, + defaultness: _, + generics: _, + of_trait: Some(_), + ref self_ty, + ref items, + } => { self.invalid_visibility(&item.vis, None); - if let TyKind::Err = ty.kind { + if let TyKind::Err = self_ty.kind { self.err_handler() .struct_span_err(item.span, "`impl Trait for .. {}` is an obsolete syntax") .help("use `auto trait Trait {}` instead") @@ -629,7 +637,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { ) .emit(); } - for impl_item in impl_items { + for impl_item in items { self.invalid_visibility(&impl_item.vis, None); if let AssocItemKind::Fn(ref sig, _) = impl_item.kind { self.check_trait_fn_not_const(sig.header.constness); @@ -637,7 +645,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } } - ItemKind::Impl(unsafety, polarity, defaultness, _, None, _, _) => { + ItemKind::Impl { + unsafety, + polarity, + defaultness, + generics: _, + of_trait: None, + self_ty: _, + items: _, + } => { self.invalid_visibility( &item.vis, Some("place qualifiers on individual impl items instead"), diff --git a/src/librustc_ast_passes/feature_gate.rs b/src/librustc_ast_passes/feature_gate.rs index 1e4b1ae077762..71cd66ddef409 100644 --- a/src/librustc_ast_passes/feature_gate.rs +++ b/src/librustc_ast_passes/feature_gate.rs @@ -339,7 +339,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } } - ast::ItemKind::Impl(_, polarity, defaultness, ..) => { + ast::ItemKind::Impl { polarity, defaultness, .. } => { if polarity == ast::ImplPolarity::Negative { gate_feature_post!( &self, diff --git a/src/librustc_builtin_macros/deriving/generic/mod.rs b/src/librustc_builtin_macros/deriving/generic/mod.rs index 9226f45816506..d346dbc8b4ee7 100644 --- a/src/librustc_builtin_macros/deriving/generic/mod.rs +++ b/src/librustc_builtin_macros/deriving/generic/mod.rs @@ -705,15 +705,15 @@ impl<'a> TraitDef<'a> { self.span, Ident::invalid(), a, - ast::ItemKind::Impl( + ast::ItemKind::Impl { unsafety, - ast::ImplPolarity::Positive, - ast::Defaultness::Final, - trait_generics, - opt_trait_ref, - self_type, - methods.into_iter().chain(associated_types).collect(), - ), + polarity: ast::ImplPolarity::Positive, + defaultness: ast::Defaultness::Final, + generics: trait_generics, + of_trait: opt_trait_ref, + self_ty: self_type, + items: methods.into_iter().chain(associated_types).collect(), + }, ) } diff --git a/src/librustc_builtin_macros/deriving/mod.rs b/src/librustc_builtin_macros/deriving/mod.rs index 4d83a6635ab17..9aa7623dc9f77 100644 --- a/src/librustc_builtin_macros/deriving/mod.rs +++ b/src/librustc_builtin_macros/deriving/mod.rs @@ -156,15 +156,15 @@ fn inject_impl_of_structural_trait( span, ast::Ident::invalid(), attrs, - ItemKind::Impl( - ast::Unsafety::Normal, - ast::ImplPolarity::Positive, - ast::Defaultness::Final, + ItemKind::Impl { + unsafety: ast::Unsafety::Normal, + polarity: ast::ImplPolarity::Positive, + defaultness: ast::Defaultness::Final, generics, - Some(trait_ref), - self_type, - Vec::new(), - ), + of_trait: Some(trait_ref), + self_ty: self_type, + items: Vec::new(), + }, ); push(Annotatable::Item(newitem)); diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 6314c2b99539a..a15f69d7d51eb 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -251,7 +251,7 @@ impl EarlyLintPass for UnsafeCode { self.report_unsafe(cx, it.span, "declaration of an `unsafe` trait") } - ast::ItemKind::Impl(ast::Unsafety::Unsafe, ..) => { + ast::ItemKind::Impl { unsafety: ast::Unsafety::Unsafe, .. } => { self.report_unsafe(cx, it.span, "implementation of an `unsafe` trait") } diff --git a/src/librustc_lint/internal.rs b/src/librustc_lint/internal.rs index 5a5aedc2e9715..91aeccbb5e334 100644 --- a/src/librustc_lint/internal.rs +++ b/src/librustc_lint/internal.rs @@ -221,7 +221,7 @@ declare_lint_pass!(LintPassImpl => [LINT_PASS_IMPL_WITHOUT_MACRO]); impl EarlyLintPass for LintPassImpl { fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { - if let ItemKind::Impl(_, _, _, _, Some(lint_pass), _, _) = &item.kind { + if let ItemKind::Impl { of_trait: Some(lint_pass), .. } = &item.kind { if let Some(last) = lint_pass.path.segments.last() { if last.ident.name == sym::LintPass { let expn_data = lint_pass.path.span.ctxt().outer_expn_data(); diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index d4756dff49a9d..1921a6c850689 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -634,15 +634,15 @@ impl<'a> Parser<'a> { let constness = constness.map(|c| c.node); let trait_ref = TraitRef { path, constness, ref_id: ty_first.id }; - ItemKind::Impl( + ItemKind::Impl { unsafety, polarity, defaultness, generics, - Some(trait_ref), - ty_second, - impl_items, - ) + of_trait: Some(trait_ref), + self_ty: ty_second, + items: impl_items, + } } None => { // Reject `impl const Type {}` here @@ -653,15 +653,15 @@ impl<'a> Parser<'a> { } // impl Type - ItemKind::Impl( + ItemKind::Impl { unsafety, polarity, defaultness, generics, - None, - ty_first, - impl_items, - ) + of_trait: None, + self_ty: ty_first, + items: impl_items, + } } }; diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index e8ed64a18702d..40a89ef067458 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -815,7 +815,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { } // These items do not add names to modules. - ItemKind::Impl(..) | ItemKind::ForeignMod(..) | ItemKind::GlobalAsm(..) => {} + ItemKind::Impl { .. } | ItemKind::ForeignMod(..) | ItemKind::GlobalAsm(..) => {} ItemKind::MacroDef(..) | ItemKind::Mac(_) => unreachable!(), } diff --git a/src/librustc_resolve/def_collector.rs b/src/librustc_resolve/def_collector.rs index f564ea644bdc1..696ba0e994c7d 100644 --- a/src/librustc_resolve/def_collector.rs +++ b/src/librustc_resolve/def_collector.rs @@ -104,7 +104,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { // Pick the def data. This need not be unique, but the more // information we encapsulate into, the better let def_data = match &i.kind { - ItemKind::Impl(..) => DefPathData::Impl, + ItemKind::Impl { .. } => DefPathData::Impl, ItemKind::Mod(..) if i.ident.name == kw::Invalid => { return visit::walk_item(self, i); } diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index defca4944bcd8..08cd9c4d1d53a 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -797,14 +797,14 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { self.resolve_adt(item, generics); } - ItemKind::Impl(.., ref generics, ref opt_trait_ref, ref self_type, ref impl_items) => { - self.resolve_implementation( - generics, - opt_trait_ref, - &self_type, - item.id, - impl_items, - ) + ItemKind::Impl { + ref generics, + ref of_trait, + ref self_ty, + items: ref impl_items, + .. + } => { + self.resolve_implementation(generics, of_trait, &self_ty, item.id, impl_items); } ItemKind::Trait(.., ref generics, ref bounds, ref trait_items) => { diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 2f2ba560fa20a..d252fc542c325 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -1300,8 +1300,8 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> { self.process_struct(item, def, ty_params) } Enum(ref def, ref ty_params) => self.process_enum(item, def, ty_params), - Impl(.., ref ty_params, ref trait_ref, ref typ, ref impl_items) => { - self.process_impl(item, ty_params, trait_ref, &typ, impl_items) + Impl { ref generics, ref of_trait, ref self_ty, ref items, .. } => { + self.process_impl(item, generics, of_trait, &self_ty, items) } Trait(_, _, ref generics, ref trait_refs, ref methods) => { self.process_trait(item, generics, trait_refs, methods) diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index c3221d925bc3b..5412533fce7d8 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -305,8 +305,8 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { attributes: lower_attributes(item.attrs.clone(), self), })) } - ast::ItemKind::Impl(.., ref trait_ref, ref typ, ref impls) => { - if let ast::TyKind::Path(None, ref path) = typ.kind { + ast::ItemKind::Impl { ref of_trait, ref self_ty, ref items, .. } => { + if let ast::TyKind::Path(None, ref path) = self_ty.kind { // Common case impl for a struct or something basic. if generated_code(path.span) { return None; @@ -317,14 +317,14 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { let impl_id = self.next_impl_id(); let span = self.span_from_span(sub_span); - let type_data = self.lookup_def_id(typ.id); + let type_data = self.lookup_def_id(self_ty.id); type_data.map(|type_data| { Data::RelationData( Relation { kind: RelationKind::Impl { id: impl_id }, span: span.clone(), from: id_from_def_id(type_data), - to: trait_ref + to: of_trait .as_ref() .and_then(|t| self.lookup_def_id(t.ref_id)) .map(id_from_def_id) @@ -332,14 +332,14 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { }, Impl { id: impl_id, - kind: match *trait_ref { + kind: match *of_trait { Some(_) => ImplKind::Direct, None => ImplKind::Inherent, }, span: span, value: String::new(), parent: None, - children: impls + children: items .iter() .map(|i| id_from_node_id(i.id, self)) .collect(), diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs index e7b86cfba4f7d..779d3f55018d5 100644 --- a/src/librustc_save_analysis/sig.rs +++ b/src/librustc_save_analysis/sig.rs @@ -482,15 +482,15 @@ impl Sig for ast::Item { Ok(sig) } - ast::ItemKind::Impl( + ast::ItemKind::Impl { unsafety, polarity, defaultness, ref generics, - ref opt_trait, - ref ty, - _, - ) => { + ref of_trait, + ref self_ty, + items: _, + } => { let mut text = String::new(); if let ast::Defaultness::Default = defaultness { text.push_str("default "); @@ -505,7 +505,7 @@ impl Sig for ast::Item { text.push(' '); - let trait_sig = if let Some(ref t) = *opt_trait { + let trait_sig = if let Some(ref t) = *of_trait { if polarity == ast::ImplPolarity::Negative { text.push('!'); } @@ -517,7 +517,7 @@ impl Sig for ast::Item { text_sig(String::new()) }; - let ty_sig = ty.make(offset + text.len(), id, scx)?; + let ty_sig = self_ty.make(offset + text.len(), id, scx)?; text.push_str(&ty_sig.text); text.push_str(" {}"); diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 331eb109ec0b4..a5a4eb1583bed 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -2614,15 +2614,18 @@ pub enum ItemKind { /// An implementation. /// /// E.g., `impl Foo { .. }` or `impl Trait for Foo { .. }`. - Impl( - Unsafety, - ImplPolarity, - Defaultness, - Generics, - Option, // (optional) trait this impl implements - P, // self - Vec, - ), + Impl { + unsafety: Unsafety, + polarity: ImplPolarity, + defaultness: Defaultness, + generics: Generics, + + /// The trait being implemented, if any. + of_trait: Option, + + self_ty: P, + items: Vec, + }, /// A macro invocation. /// /// E.g., `foo!(..)`. @@ -2649,7 +2652,7 @@ impl ItemKind { ItemKind::Union(..) => "union", ItemKind::Trait(..) => "trait", ItemKind::TraitAlias(..) => "trait alias", - ItemKind::Mac(..) | ItemKind::MacroDef(..) | ItemKind::Impl(..) => "item", + ItemKind::Mac(..) | ItemKind::MacroDef(..) | ItemKind::Impl { .. } => "item", } } } diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index 58d4e46111b83..750d054e8a0f2 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -918,10 +918,18 @@ pub fn noop_visit_item_kind(kind: &mut ItemKind, vis: &mut T) { vis.visit_variant_data(variant_data); vis.visit_generics(generics); } - ItemKind::Impl(_unsafety, _polarity, _defaultness, generics, trait_ref, ty, items) => { + ItemKind::Impl { + unsafety: _, + polarity: _, + defaultness: _, + generics, + of_trait, + self_ty, + items, + } => { vis.visit_generics(generics); - visit_opt(trait_ref, |trait_ref| vis.visit_trait_ref(trait_ref)); - vis.visit_ty(ty); + visit_opt(of_trait, |trait_ref| vis.visit_trait_ref(trait_ref)); + vis.visit_ty(self_ty); items.flat_map_in_place(|item| vis.flat_map_impl_item(item)); } ItemKind::Trait(_is_auto, _unsafety, generics, bounds, items) => { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 11c8cb8ef7500..bc67980c454c0 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1226,15 +1226,15 @@ impl<'a> State<'a> { self.head(visibility_qualified(&item.vis, "union")); self.print_struct(struct_def, generics, item.ident, item.span, true); } - ast::ItemKind::Impl( + ast::ItemKind::Impl { unsafety, polarity, defaultness, ref generics, - ref opt_trait, - ref ty, - ref impl_items, - ) => { + ref of_trait, + ref self_ty, + ref items, + } => { self.head(""); self.print_visibility(&item.vis); self.print_defaultness(defaultness); @@ -1250,19 +1250,19 @@ impl<'a> State<'a> { self.s.word("!"); } - if let Some(ref t) = *opt_trait { + if let Some(ref t) = *of_trait { self.print_trait_ref(t); self.s.space(); self.word_space("for"); } - self.print_type(ty); + self.print_type(self_ty); self.print_where_clause(&generics.where_clause); self.s.space(); self.bopen(); self.print_inner_attributes(&item.attrs); - for impl_item in impl_items { + for impl_item in items { self.print_assoc_item(impl_item); } self.bclose(item.span); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 3c2ebacbc4e34..d03a9dfc16758 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -308,11 +308,19 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) { visitor.visit_generics(generics); visitor.visit_enum_def(enum_definition, generics, item.id, item.span) } - ItemKind::Impl(_, _, _, ref generics, ref opt_trait_reference, ref typ, ref impl_items) => { + ItemKind::Impl { + unsafety: _, + polarity: _, + defaultness: _, + ref generics, + ref of_trait, + ref self_ty, + ref items, + } => { visitor.visit_generics(generics); - walk_list!(visitor, visit_trait_ref, opt_trait_reference); - visitor.visit_ty(typ); - walk_list!(visitor, visit_impl_item, impl_items); + walk_list!(visitor, visit_trait_ref, of_trait); + visitor.visit_ty(self_ty); + walk_list!(visitor, visit_impl_item, items); } ItemKind::Struct(ref struct_definition, ref generics) | ItemKind::Union(ref struct_definition, ref generics) => { From 4743995ed3f7a60e5e0b66eb6a095483883d8c90 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Fri, 17 Jan 2020 16:14:29 -0800 Subject: [PATCH 152/169] Use named fields for `hir::ItemKind::Impl` --- src/librustc/hir/check_attr.rs | 4 +- src/librustc/hir/map/mod.rs | 6 +-- src/librustc/infer/error_reporting/mod.rs | 2 +- .../traits/error_reporting/suggestions.rs | 5 +-- src/librustc/traits/util.rs | 2 +- src/librustc/traits/wf.rs | 8 ++-- src/librustc_ast_lowering/item.rs | 14 +++--- src/librustc_hir/hir.rs | 25 ++++++----- src/librustc_hir/intravisit.rs | 16 +++++-- src/librustc_hir/print.rs | 16 +++---- .../persist/dirty_clean.rs | 2 +- src/librustc_lint/builtin.rs | 4 +- src/librustc_metadata/rmeta/encoder.rs | 14 +++--- src/librustc_mir/monomorphize/collector.rs | 6 +-- src/librustc_passes/dead.rs | 8 ++-- src/librustc_passes/reachable.rs | 10 ++--- src/librustc_passes/stability.rs | 10 ++--- src/librustc_privacy/lib.rs | 44 +++++++++---------- src/librustc_resolve/lifetimes.rs | 10 ++--- src/librustc_save_analysis/lib.rs | 4 +- src/librustc_traits/lowering/environment.rs | 4 +- src/librustc_ty/ty.rs | 8 ++-- src/librustc_typeck/check/mod.rs | 10 +---- src/librustc_typeck/check/wfcheck.rs | 6 +-- src/librustc_typeck/coherence/builtin.rs | 9 ++-- .../coherence/inherent_impls.rs | 2 +- src/librustc_typeck/coherence/orphan.rs | 4 +- src/librustc_typeck/coherence/unsafety.rs | 2 +- src/librustc_typeck/collect.rs | 36 +++++++-------- src/librustc_typeck/impl_wf_check.rs | 6 +-- src/librustdoc/clean/inline.rs | 8 ++-- src/librustdoc/test.rs | 4 +- src/librustdoc/visit_ast.rs | 18 ++++---- 33 files changed, 166 insertions(+), 161 deletions(-) diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index 5a99e7965538b..5a4d7ceea2734 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -112,7 +112,7 @@ impl Target { ItemKind::Union(..) => Target::Union, ItemKind::Trait(..) => Target::Trait, ItemKind::TraitAlias(..) => Target::TraitAlias, - ItemKind::Impl(..) => Target::Impl, + ItemKind::Impl { .. } => Target::Impl, } } @@ -144,7 +144,7 @@ impl Target { let parent_hir_id = tcx.hir().get_parent_item(impl_item.hir_id); let containing_item = tcx.hir().expect_item(parent_hir_id); let containing_impl_is_for_trait = match &containing_item.kind { - hir::ItemKind::Impl(_, _, _, _, tr, _, _) => tr.is_some(), + hir::ItemKind::Impl { ref of_trait, .. } => of_trait.is_some(), _ => bug!("parent of an ImplItem must be an Impl"), }; if containing_impl_is_for_trait { diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 8b4f0c6bde2b5..6d7f53133a666 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -341,7 +341,7 @@ impl<'hir> Map<'hir> { | ItemKind::Use(..) | ItemKind::ForeignMod(..) | ItemKind::GlobalAsm(..) - | ItemKind::Impl(..) => return None, + | ItemKind::Impl { .. } => return None, }, Node::ForeignItem(item) => match item.kind { ForeignItemKind::Fn(..) => DefKind::Fn, @@ -604,7 +604,7 @@ impl<'hir> Map<'hir> { | ItemKind::Union(_, ref generics) | ItemKind::Trait(_, _, ref generics, ..) | ItemKind::TraitAlias(ref generics, _) - | ItemKind::Impl(_, _, _, ref generics, ..) => Some(generics), + | ItemKind::Impl { ref generics, .. } => Some(generics), _ => None, }, _ => None, @@ -1332,7 +1332,7 @@ fn hir_id_to_string(map: &Map<'_>, id: HirId, include_id: bool) -> String { ItemKind::Union(..) => "union", ItemKind::Trait(..) => "trait", ItemKind::TraitAlias(..) => "trait alias", - ItemKind::Impl(..) => "impl", + ItemKind::Impl { .. } => "impl", }; format!("{} {}{}", item_str, path_str(), id_str) } diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index febf4f21a6755..a2009461fa568 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -254,7 +254,7 @@ fn emit_msg_span( fn item_scope_tag(item: &hir::Item<'_>) -> &'static str { match item.kind { - hir::ItemKind::Impl(..) => "impl", + hir::ItemKind::Impl { .. } => "impl", hir::ItemKind::Struct(..) => "struct", hir::ItemKind::Union(..) => "union", hir::ItemKind::Enum(..) => "enum", diff --git a/src/librustc/traits/error_reporting/suggestions.rs b/src/librustc/traits/error_reporting/suggestions.rs index bf6891214ace1..c09fd3079731c 100644 --- a/src/librustc/traits/error_reporting/suggestions.rs +++ b/src/librustc/traits/error_reporting/suggestions.rs @@ -88,8 +88,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { .. }) | hir::Node::Item(hir::Item { - kind: hir::ItemKind::Impl(_, _, _, generics, ..), - .. + kind: hir::ItemKind::Impl { generics, .. }, .. }) if projection.is_some() => { // Missing associated type bound. suggest_restriction(&generics, "the associated type", err); @@ -115,7 +114,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { .. }) | hir::Node::Item(hir::Item { - kind: hir::ItemKind::Impl(_, _, _, generics, ..), + kind: hir::ItemKind::Impl { generics, .. }, span, .. }) diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index 65fd809657bd0..f058a4d2df24a 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -651,7 +651,7 @@ pub fn impl_is_default(tcx: TyCtxt<'_>, node_item_def_id: DefId) -> bool { match tcx.hir().as_local_hir_id(node_item_def_id) { Some(hir_id) => { let item = tcx.hir().expect_item(hir_id); - if let hir::ItemKind::Impl(_, _, defaultness, ..) = item.kind { + if let hir::ItemKind::Impl { defaultness, .. } = item.kind { defaultness.is_default() } else { false diff --git a/src/librustc/traits/wf.rs b/src/librustc/traits/wf.rs index 2301395f557f1..869ba5315c1ae 100644 --- a/src/librustc/traits/wf.rs +++ b/src/librustc/traits/wf.rs @@ -229,9 +229,9 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { // | // = note: expected type `u32` // found type `()` - if let Some(hir::ItemKind::Impl(.., impl_items)) = item.map(|i| &i.kind) { + if let Some(hir::ItemKind::Impl { items, .. }) = item.map(|i| &i.kind) { let trait_assoc_item = tcx.associated_item(proj.projection_def_id()); - if let Some(impl_item) = impl_items + if let Some(impl_item) = items .iter() .filter(|item| item.ident == trait_assoc_item.ident) .next() @@ -279,14 +279,14 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { // | ^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `bool` if let ( ty::Projection(ty::ProjectionTy { item_def_id, .. }), - Some(hir::ItemKind::Impl(.., impl_items)), + Some(hir::ItemKind::Impl { items, .. }), ) = (&proj.skip_binder().self_ty().kind, item.map(|i| &i.kind)) { if let Some((impl_item, trait_assoc_item)) = trait_assoc_items .filter(|i| i.def_id == *item_def_id) .next() .and_then(|trait_assoc_item| { - impl_items + items .iter() .filter(|i| i.ident == trait_assoc_item.ident) .next() diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs index 648c4f7e46aad..6da2d457f3c3b 100644 --- a/src/librustc_ast_lowering/item.rs +++ b/src/librustc_ast_lowering/item.rs @@ -119,7 +119,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let old_len = self.in_scope_lifetimes.len(); let parent_generics = match self.items.get(&parent_hir_id).unwrap().kind { - hir::ItemKind::Impl(_, _, _, ref generics, ..) + hir::ItemKind::Impl { ref generics, .. } | hir::ItemKind::Trait(_, _, ref generics, ..) => &generics.params[..], _ => &[], }; @@ -418,15 +418,15 @@ impl<'hir> LoweringContext<'_, 'hir> { ) }); - hir::ItemKind::Impl( + hir::ItemKind::Impl { unsafety, polarity, - self.lower_defaultness(defaultness, true /* [1] */), + defaultness: self.lower_defaultness(defaultness, true /* [1] */), generics, - trait_ref, - lowered_ty, - new_impl_items, - ) + of_trait: trait_ref, + self_ty: lowered_ty, + items: new_impl_items, + } } ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref items) => { let bounds = self.lower_param_bounds(bounds, ImplTraitContext::disallowed()); diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs index 5c1d600c837c4..1fef871b5140e 100644 --- a/src/librustc_hir/hir.rs +++ b/src/librustc_hir/hir.rs @@ -2436,15 +2436,18 @@ pub enum ItemKind<'hir> { TraitAlias(Generics<'hir>, GenericBounds<'hir>), /// An implementation, e.g., `impl Trait for Foo { .. }`. - Impl( - Unsafety, - ImplPolarity, - Defaultness, - Generics<'hir>, - Option>, // (optional) trait this impl implements - &'hir Ty<'hir>, // self - &'hir [ImplItemRef<'hir>], - ), + Impl { + unsafety: Unsafety, + polarity: ImplPolarity, + defaultness: Defaultness, + generics: Generics<'hir>, + + /// The trait being implemented, if any. + of_trait: Option>, + + self_ty: &'hir Ty<'hir>, + items: &'hir [ImplItemRef<'hir>], + }, } impl ItemKind<'_> { @@ -2465,7 +2468,7 @@ impl ItemKind<'_> { ItemKind::Union(..) => "union", ItemKind::Trait(..) => "trait", ItemKind::TraitAlias(..) => "trait alias", - ItemKind::Impl(..) => "impl", + ItemKind::Impl { .. } => "impl", } } @@ -2478,7 +2481,7 @@ impl ItemKind<'_> { | ItemKind::Struct(_, ref generics) | ItemKind::Union(_, ref generics) | ItemKind::Trait(_, _, ref generics, _, _) - | ItemKind::Impl(_, _, _, ref generics, _, _, _) => generics, + | ItemKind::Impl { ref generics, .. } => generics, _ => return None, }) } diff --git a/src/librustc_hir/intravisit.rs b/src/librustc_hir/intravisit.rs index 3dbc5253a9abf..1a73e41db9da5 100644 --- a/src/librustc_hir/intravisit.rs +++ b/src/librustc_hir/intravisit.rs @@ -566,12 +566,20 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) { // `visit_enum_def()` takes care of visiting the `Item`'s `HirId`. visitor.visit_enum_def(enum_definition, generics, item.hir_id, item.span) } - ItemKind::Impl(.., ref generics, ref opt_trait_reference, ref typ, impl_item_refs) => { + ItemKind::Impl { + unsafety: _, + defaultness: _, + polarity: _, + ref generics, + ref of_trait, + ref self_ty, + items, + } => { visitor.visit_id(item.hir_id); visitor.visit_generics(generics); - walk_list!(visitor, visit_trait_ref, opt_trait_reference); - visitor.visit_ty(typ); - walk_list!(visitor, visit_impl_item_ref, impl_item_refs); + walk_list!(visitor, visit_trait_ref, of_trait); + visitor.visit_ty(self_ty); + walk_list!(visitor, visit_impl_item_ref, items); } ItemKind::Struct(ref struct_definition, ref generics) | ItemKind::Union(ref struct_definition, ref generics) => { diff --git a/src/librustc_hir/print.rs b/src/librustc_hir/print.rs index 759f423070aa0..6c7d419395317 100644 --- a/src/librustc_hir/print.rs +++ b/src/librustc_hir/print.rs @@ -627,15 +627,15 @@ impl<'a> State<'a> { self.head(visibility_qualified(&item.vis, "union")); self.print_struct(struct_def, generics, item.ident.name, item.span, true); } - hir::ItemKind::Impl( + hir::ItemKind::Impl { unsafety, polarity, defaultness, ref generics, - ref opt_trait, - ref ty, - impl_items, - ) => { + ref of_trait, + ref self_ty, + items, + } => { self.head(""); self.print_visibility(&item.vis); self.print_defaultness(defaultness); @@ -651,19 +651,19 @@ impl<'a> State<'a> { self.s.word("!"); } - if let Some(ref t) = opt_trait { + if let Some(ref t) = of_trait { self.print_trait_ref(t); self.s.space(); self.word_space("for"); } - self.print_type(&ty); + self.print_type(&self_ty); self.print_where_clause(&generics.where_clause); self.s.space(); self.bopen(); self.print_inner_attributes(&item.attrs); - for impl_item in impl_items { + for impl_item in items { self.ann.nested(self, Nested::ImplItem(impl_item.id)); } self.bclose(item.span); diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs index ddfed53fa3349..c5e74868bda4a 100644 --- a/src/librustc_incremental/persist/dirty_clean.rs +++ b/src/librustc_incremental/persist/dirty_clean.rs @@ -315,7 +315,7 @@ impl DirtyCleanVisitor<'tcx> { //HirItem::Trait(..) => ("ItemTrait", LABELS_TRAIT), // An implementation, eg `impl Trait for Foo { .. }` - HirItem::Impl(..) => ("ItemKind::Impl", LABELS_IMPL), + HirItem::Impl { .. } => ("ItemKind::Impl", LABELS_IMPL), _ => self.tcx.sess.span_fatal( attr.span, diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index a15f69d7d51eb..c8d3d5f9c83d8 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -431,7 +431,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { "a trait" } hir::ItemKind::TyAlias(..) => "a type alias", - hir::ItemKind::Impl(.., Some(ref trait_ref), _, impl_item_refs) => { + hir::ItemKind::Impl { of_trait: Some(ref trait_ref), items, .. } => { // If the trait is private, add the impl items to `private_traits` so they don't get // reported for missing docs. let real_trait = trait_ref.path.res.def_id(); @@ -439,7 +439,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { match cx.tcx.hir().find(hir_id) { Some(Node::Item(item)) => { if let hir::VisibilityKind::Inherited = item.vis.node { - for impl_item_ref in impl_item_refs { + for impl_item_ref in items { self.private_traits.insert(impl_item_ref.id.hir_id); } } diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index 8ad92ce75a851..9d2bea28c8c2e 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -1073,7 +1073,7 @@ impl EncodeContext<'tcx> { ctor: None, }), adt_def.repr) } - hir::ItemKind::Impl(_, _, defaultness, ..) => { + hir::ItemKind::Impl { defaultness, .. } => { let trait_ref = self.tcx.impl_trait_ref(def_id); let polarity = self.tcx.impl_polarity(def_id); let parent = if let Some(trait_ref) = trait_ref { @@ -1149,7 +1149,7 @@ impl EncodeContext<'tcx> { }) ) } - hir::ItemKind::Impl(..) | hir::ItemKind::Trait(..) => { + hir::ItemKind::Impl { .. } | hir::ItemKind::Trait(..) => { let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id); record!(self.per_def.children[def_id] <- associated_item_def_ids.iter().map(|&def_id| { @@ -1172,13 +1172,13 @@ impl EncodeContext<'tcx> { | hir::ItemKind::Enum(..) | hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) - | hir::ItemKind::Impl(..) => self.encode_item_type(def_id), + | hir::ItemKind::Impl { .. } => self.encode_item_type(def_id), _ => {} } if let hir::ItemKind::Fn(..) = item.kind { record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id)); } - if let hir::ItemKind::Impl(..) = item.kind { + if let hir::ItemKind::Impl { .. } = item.kind { if let Some(trait_ref) = self.tcx.impl_trait_ref(def_id) { record!(self.per_def.impl_trait_ref[def_id] <- trait_ref); } @@ -1199,7 +1199,7 @@ impl EncodeContext<'tcx> { | hir::ItemKind::Enum(..) | hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) - | hir::ItemKind::Impl(..) + | hir::ItemKind::Impl { .. } | hir::ItemKind::OpaqueTy(..) | hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..) => { @@ -1645,7 +1645,7 @@ impl EncodeContext<'tcx> { hir::ItemKind::Union(..) => { self.encode_fields(def_id); } - hir::ItemKind::Impl(..) => { + hir::ItemKind::Impl { .. } => { for &trait_item_def_id in self.tcx.associated_item_def_ids(def_id).iter() { self.encode_info_for_impl_item(trait_item_def_id); } @@ -1666,7 +1666,7 @@ struct ImplVisitor<'tcx> { impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplVisitor<'tcx> { fn visit_item(&mut self, item: &hir::Item<'_>) { - if let hir::ItemKind::Impl(..) = item.kind { + if let hir::ItemKind::Impl { .. } = item.kind { let impl_id = self.tcx.hir().local_def_id(item.hir_id); if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_id) { self.impls.entry(trait_ref.def_id).or_default().push(impl_id.index); diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 85377180bea46..f4611c32e0a32 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -954,7 +954,7 @@ impl ItemLikeVisitor<'v> for RootCollector<'_, 'v> { // Nothing to do, just keep recursing. } - hir::ItemKind::Impl(..) => { + hir::ItemKind::Impl { .. } => { if self.mode == MonoItemCollectionMode::Eager { create_mono_items_for_default_impls(self.tcx, item, self.output); } @@ -1098,7 +1098,7 @@ fn create_mono_items_for_default_impls<'tcx>( output: &mut Vec>, ) { match item.kind { - hir::ItemKind::Impl(_, _, _, ref generics, .., ref impl_item_refs) => { + hir::ItemKind::Impl { ref generics, ref items, .. } => { for param in generics.params { match param.kind { hir::GenericParamKind::Lifetime { .. } => {} @@ -1119,7 +1119,7 @@ fn create_mono_items_for_default_impls<'tcx>( let param_env = ty::ParamEnv::reveal_all(); let trait_ref = tcx.normalize_erasing_regions(param_env, trait_ref); let overridden_methods: FxHashSet<_> = - impl_item_refs.iter().map(|iiref| iiref.ident.modern()).collect(); + items.iter().map(|iiref| iiref.ident.modern()).collect(); for method in tcx.provided_trait_methods(trait_ref.def_id) { if overridden_methods.contains(&method.ident.modern()) { continue; diff --git a/src/librustc_passes/dead.rs b/src/librustc_passes/dead.rs index f2778b2aa6bcd..2ff9d744f2c4d 100644 --- a/src/librustc_passes/dead.rs +++ b/src/librustc_passes/dead.rs @@ -405,10 +405,10 @@ impl<'v, 'k, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'k, 'tcx> { } } } - hir::ItemKind::Impl(.., ref opt_trait, _, impl_item_refs) => { - for impl_item_ref in impl_item_refs { + hir::ItemKind::Impl { ref of_trait, items, .. } => { + for impl_item_ref in items { let impl_item = self.krate.impl_item(impl_item_ref.id); - if opt_trait.is_some() + if of_trait.is_some() || has_allow_dead_code_or_lang_attr( self.tcx, impl_item.hir_id, @@ -586,7 +586,7 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> { | hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) | hir::ItemKind::Trait(..) - | hir::ItemKind::Impl(..) => { + | hir::ItemKind::Impl { .. } => { // FIXME(66095): Because item.span is annotated with things // like expansion data, and ident.span isn't, we use the // def_span method if it's part of a macro invocation diff --git a/src/librustc_passes/reachable.rs b/src/librustc_passes/reachable.rs index 5ce677f52cea6..667898046ac36 100644 --- a/src/librustc_passes/reachable.rs +++ b/src/librustc_passes/reachable.rs @@ -35,7 +35,7 @@ fn item_might_be_inlined(tcx: TyCtxt<'tcx>, item: &hir::Item<'_>, attrs: Codegen hir::ItemKind::Fn(ref sig, ..) if sig.header.is_const() => { return true; } - hir::ItemKind::Impl(..) | hir::ItemKind::Fn(..) => { + hir::ItemKind::Impl { .. } | hir::ItemKind::Fn(..) => { let generics = tcx.generics_of(tcx.hir().local_def_id(item.hir_id)); generics.requires_monomorphization(tcx) } @@ -181,7 +181,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { // does too. let impl_hir_id = self.tcx.hir().as_local_hir_id(impl_did).unwrap(); match self.tcx.hir().expect_item(impl_hir_id).kind { - hir::ItemKind::Impl(..) => { + hir::ItemKind::Impl { .. } => { let generics = self.tcx.generics_of(impl_did); generics.requires_monomorphization(self.tcx) } @@ -266,7 +266,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { | hir::ItemKind::Static(..) | hir::ItemKind::Mod(..) | hir::ItemKind::ForeignMod(..) - | hir::ItemKind::Impl(..) + | hir::ItemKind::Impl { .. } | hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..) | hir::ItemKind::Struct(..) @@ -349,9 +349,9 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx } // We need only trait impls here, not inherent impls, and only non-exported ones - if let hir::ItemKind::Impl(.., Some(ref trait_ref), _, ref impl_item_refs) = item.kind { + if let hir::ItemKind::Impl { of_trait: Some(ref trait_ref), ref items, .. } = item.kind { if !self.access_levels.is_reachable(item.hir_id) { - self.worklist.extend(impl_item_refs.iter().map(|ii_ref| ii_ref.id.hir_id)); + self.worklist.extend(items.iter().map(|ii_ref| ii_ref.id.hir_id)); let trait_def_id = match trait_ref.path.res { Res::Def(DefKind::Trait, def_id) => def_id, diff --git a/src/librustc_passes/stability.rs b/src/librustc_passes/stability.rs index 5ec7e73f873e0..b649f36f2fc58 100644 --- a/src/librustc_passes/stability.rs +++ b/src/librustc_passes/stability.rs @@ -219,11 +219,11 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> { // they don't have their own stability. They still can be annotated as unstable // and propagate this unstability to children, but this annotation is completely // optional. They inherit stability from their parents when unannotated. - hir::ItemKind::Impl(.., None, _, _) | hir::ItemKind::ForeignMod(..) => { + hir::ItemKind::Impl { of_trait: None, .. } | hir::ItemKind::ForeignMod(..) => { self.in_trait_impl = false; kind = AnnotationKind::Container; } - hir::ItemKind::Impl(.., Some(_), _, _) => { + hir::ItemKind::Impl { of_trait: Some(_), .. } => { self.in_trait_impl = true; } hir::ItemKind::Struct(ref sd, _) => { @@ -308,7 +308,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'a, 'tcx> { // they don't have their own stability. They still can be annotated as unstable // and propagate this unstability to children, but this annotation is completely // optional. They inherit stability from their parents when unannotated. - hir::ItemKind::Impl(.., None, _, _) | hir::ItemKind::ForeignMod(..) => {} + hir::ItemKind::Impl { of_trait: None, .. } | hir::ItemKind::ForeignMod(..) => {} _ => self.check_missing_stability(i.hir_id, i.span, i.kind.descriptive_variant()), } @@ -463,9 +463,9 @@ impl Visitor<'tcx> for Checker<'tcx> { // For implementations of traits, check the stability of each item // individually as it's possible to have a stable trait with unstable // items. - hir::ItemKind::Impl(.., Some(ref t), _, impl_item_refs) => { + hir::ItemKind::Impl { of_trait: Some(ref t), items, .. } => { if let Res::Def(DefKind::Trait, trait_did) = t.path.res { - for impl_item_ref in impl_item_refs { + for impl_item_ref in items { let impl_item = self.tcx.hir().impl_item(impl_item_ref.id); let trait_item_def_id = self .tcx diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 70d4841ec244b..90a422a4dcf6c 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -255,8 +255,8 @@ fn def_id_visibility<'tcx>( Node::ImplItem(impl_item) => { match tcx.hir().get(tcx.hir().get_parent_item(hir_id)) { Node::Item(item) => match &item.kind { - hir::ItemKind::Impl(.., None, _, _) => &impl_item.vis, - hir::ItemKind::Impl(.., Some(trait_ref), _, _) => { + hir::ItemKind::Impl { of_trait: None, .. } => &impl_item.vis, + hir::ItemKind::Impl { of_trait: Some(trait_ref), .. } => { return def_id_visibility(tcx, trait_ref.path.res.def_id()); } kind => bug!("unexpected item kind: {:?}", kind), @@ -686,7 +686,7 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { let inherited_item_level = match item.kind { - hir::ItemKind::Impl(..) => { + hir::ItemKind::Impl { .. } => { Option::::of_impl(item.hir_id, self.tcx, &self.access_levels) } // Foreign modules inherit level from parents. @@ -730,9 +730,9 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { } } } - hir::ItemKind::Impl(.., ref trait_ref, _, impl_item_refs) => { - for impl_item_ref in impl_item_refs { - if trait_ref.is_some() || impl_item_ref.vis.node.is_pub() { + hir::ItemKind::Impl { ref of_trait, items, .. } => { + for impl_item_ref in items { + if of_trait.is_some() || impl_item_ref.vis.node.is_pub() { self.update(impl_item_ref.id.hir_id, item_level); } } @@ -827,11 +827,11 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { } } // Visit everything except for private impl items. - hir::ItemKind::Impl(.., impl_item_refs) => { + hir::ItemKind::Impl { items, .. } => { if item_level.is_some() { self.reach(item.hir_id, item_level).generics().predicates().ty().trait_ref(); - for impl_item_ref in impl_item_refs { + for impl_item_ref in items { let impl_item_level = self.get(impl_item_ref.id.hir_id); if impl_item_level.is_some() { self.reach(impl_item_ref.id.hir_id, impl_item_level) @@ -1510,7 +1510,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { // (i.e., we could just return here to not check them at // all, or some worse estimation of whether an impl is // publicly visible). - hir::ItemKind::Impl(.., ref g, ref trait_ref, ref self_, impl_item_refs) => { + hir::ItemKind::Impl { generics: ref g, ref of_trait, ref self_ty, items, .. } => { // `impl [... for] Private` is never visible. let self_contains_private; // `impl [... for] Public<...>`, but not `impl [... for] @@ -1525,7 +1525,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { at_outer_type: true, outer_type_is_public_path: false, }; - visitor.visit_ty(&self_); + visitor.visit_ty(&self_ty); self_contains_private = visitor.contains_private; self_is_public_path = visitor.outer_type_is_public_path; } @@ -1533,7 +1533,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { // Miscellaneous info about the impl: // `true` iff this is `impl Private for ...`. - let not_private_trait = trait_ref.as_ref().map_or( + let not_private_trait = of_trait.as_ref().map_or( true, // no trait counts as public trait |tr| { let did = tr.path.res.def_id(); @@ -1554,8 +1554,8 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { // directly because we might have `impl> ...`, // and we shouldn't warn about the generics if all the methods // are private (because `T` won't be visible externally). - let trait_or_some_public_method = trait_ref.is_some() - || impl_item_refs.iter().any(|impl_item_ref| { + let trait_or_some_public_method = of_trait.is_some() + || items.iter().any(|impl_item_ref| { let impl_item = self.tcx.hir().impl_item(impl_item_ref.id); match impl_item.kind { hir::ImplItemKind::Const(..) | hir::ImplItemKind::Method(..) => { @@ -1570,9 +1570,9 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { if !self_contains_private && not_private_trait && trait_or_some_public_method { intravisit::walk_generics(self, g); - match *trait_ref { + match of_trait { None => { - for impl_item_ref in impl_item_refs { + for impl_item_ref in items { // This is where we choose whether to walk down // further into the impl to check its items. We // should only walk into public items so that we @@ -1594,7 +1594,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { } } } - Some(ref tr) => { + Some(tr) => { // Any private types in a trait impl fall into three // categories. // 1. mentioned in the trait definition @@ -1611,7 +1611,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { intravisit::walk_path(self, &tr.path); // Those in 3. are warned with this call. - for impl_item_ref in impl_item_refs { + for impl_item_ref in items { let impl_item = self.tcx.hir().impl_item(impl_item_ref.id); if let hir::ImplItemKind::TyAlias(ref ty) = impl_item.kind { self.visit_ty(ty); @@ -1619,11 +1619,11 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { } } } - } else if trait_ref.is_none() && self_is_public_path { + } else if of_trait.is_none() && self_is_public_path { // `impl Public { ... }`. Any public static // methods will be visible as `Public::foo`. let mut found_pub_static = false; - for impl_item_ref in impl_item_refs { + for impl_item_ref in items { if self.item_is_public(&impl_item_ref.id.hir_id, &impl_item_ref.vis) { let impl_item = self.tcx.hir().impl_item(impl_item_ref.id); match impl_item_ref.kind { @@ -1997,12 +1997,12 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> // Subitems of inherent impls have their own publicity. // A trait impl is public when both its type and its trait are public // Subitems of trait impls have inherited publicity. - hir::ItemKind::Impl(.., ref trait_ref, _, impl_item_refs) => { + hir::ItemKind::Impl { ref of_trait, items, .. } => { let impl_vis = ty::Visibility::of_impl(item.hir_id, tcx, &Default::default()); self.check(item.hir_id, impl_vis).generics().predicates(); - for impl_item_ref in impl_item_refs { + for impl_item_ref in items { let impl_item = tcx.hir().impl_item(impl_item_ref.id); - let impl_item_vis = if trait_ref.is_none() { + let impl_item_vis = if of_trait.is_none() { min( ty::Visibility::from_hir(&impl_item.vis, item.hir_id, tcx), impl_vis, diff --git a/src/librustc_resolve/lifetimes.rs b/src/librustc_resolve/lifetimes.rs index d6143eec73c00..5fae8f3318743 100644 --- a/src/librustc_resolve/lifetimes.rs +++ b/src/librustc_resolve/lifetimes.rs @@ -416,11 +416,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { | hir::ItemKind::Union(_, ref generics) | hir::ItemKind::Trait(_, _, ref generics, ..) | hir::ItemKind::TraitAlias(ref generics, ..) - | hir::ItemKind::Impl(_, _, _, ref generics, ..) => { + | hir::ItemKind::Impl { ref generics, .. } => { // Impls permit `'_` to be used and it is equivalent to "some fresh lifetime name". // This is not true for other kinds of items.x let track_lifetime_uses = match item.kind { - hir::ItemKind::Impl(..) => true, + hir::ItemKind::Impl { .. } => true, _ => false, }; // These kinds of items have only early-bound lifetime parameters. @@ -1638,7 +1638,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } match parent.kind { hir::ItemKind::Trait(_, _, ref generics, ..) - | hir::ItemKind::Impl(_, _, _, ref generics, ..) => { + | hir::ItemKind::Impl { ref generics, .. } => { index += generics.params.len() as u32; } _ => {} @@ -2067,12 +2067,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Method(_, body), .. }) => { - if let hir::ItemKind::Impl(.., ref self_ty, ref impl_items) = + if let hir::ItemKind::Impl { ref self_ty, ref items, .. } = self.tcx.hir().expect_item(self.tcx.hir().get_parent_item(parent)).kind { impl_self = Some(self_ty); assoc_item_kind = - impl_items.iter().find(|ii| ii.id.hir_id == parent).map(|ii| ii.kind); + items.iter().find(|ii| ii.id.hir_id == parent).map(|ii| ii.kind); } Some(body) } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 5412533fce7d8..537fe198a0c39 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -405,9 +405,9 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { { Some(impl_id) => match self.tcx.hir().get_if_local(impl_id) { Some(Node::Item(item)) => match item.kind { - hir::ItemKind::Impl(.., ref ty, _) => { + hir::ItemKind::Impl { ref self_ty, .. } => { let mut qualname = String::from("<"); - qualname.push_str(&self.tcx.hir().hir_to_pretty_string(ty.hir_id)); + qualname.push_str(&self.tcx.hir().hir_to_pretty_string(self_ty.hir_id)); let trait_id = self.tcx.trait_id_of_impl(impl_id); let mut decl_id = None; diff --git a/src/librustc_traits/lowering/environment.rs b/src/librustc_traits/lowering/environment.rs index 315efe5cf71e7..7df27e67d5b1c 100644 --- a/src/librustc_traits/lowering/environment.rs +++ b/src/librustc_traits/lowering/environment.rs @@ -195,8 +195,8 @@ crate fn environment(tcx: TyCtxt<'_>, def_id: DefId) -> Environment<'_> { }, Node::Item(item) => match item.kind { - ItemKind::Impl(.., Some(..), _, _) => NodeKind::TraitImpl, - ItemKind::Impl(.., None, _, _) => NodeKind::InherentImpl, + ItemKind::Impl { of_trait: Some(_), .. } => NodeKind::TraitImpl, + ItemKind::Impl { of_trait: None, .. } => NodeKind::InherentImpl, ItemKind::Fn(..) => NodeKind::Fn, _ => NodeKind::Other, }, diff --git a/src/librustc_ty/ty.rs b/src/librustc_ty/ty.rs index fc8beb67e4ada..d47e54366b550 100644 --- a/src/librustc_ty/ty.rs +++ b/src/librustc_ty/ty.rs @@ -128,8 +128,8 @@ fn associated_item(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AssocItem { let parent_def_id = tcx.hir().local_def_id(parent_id); let parent_item = tcx.hir().expect_item(parent_id); match parent_item.kind { - hir::ItemKind::Impl(.., ref impl_item_refs) => { - if let Some(impl_item_ref) = impl_item_refs.iter().find(|i| i.id.hir_id == id) { + hir::ItemKind::Impl { ref items, .. } => { + if let Some(impl_item_ref) = items.iter().find(|i| i.id.hir_id == id) { let assoc_item = associated_item_from_impl_item_ref(tcx, parent_def_id, impl_item_ref); debug_assert_eq!(assoc_item.def_id, def_id); @@ -194,8 +194,8 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: DefId) -> &[DefId] { .map(|trait_item_ref| trait_item_ref.id) .map(|id| tcx.hir().local_def_id(id.hir_id)), ), - hir::ItemKind::Impl(.., ref impl_item_refs) => tcx.arena.alloc_from_iter( - impl_item_refs + hir::ItemKind::Impl { ref items, .. } => tcx.arena.alloc_from_iter( + items .iter() .map(|impl_item_ref| impl_item_ref.id) .map(|id| tcx.hir().local_def_id(id.hir_id)), diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index dff68b9986cc9..4affdc4a9d64e 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1709,17 +1709,11 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) { check_enum(tcx, it.span, &enum_definition.variants, it.hir_id); } hir::ItemKind::Fn(..) => {} // entirely within check_item_body - hir::ItemKind::Impl(.., ref impl_item_refs) => { + hir::ItemKind::Impl { ref items, .. } => { debug!("ItemKind::Impl {} with id {}", it.ident, it.hir_id); let impl_def_id = tcx.hir().local_def_id(it.hir_id); if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) { - check_impl_items_against_trait( - tcx, - it.span, - impl_def_id, - impl_trait_ref, - impl_item_refs, - ); + check_impl_items_against_trait(tcx, it.span, impl_def_id, impl_trait_ref, items); let trait_def_id = impl_trait_ref.def_id; check_on_unimplemented(tcx, trait_def_id, it); } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index a496a6e12ce1a..5e91e98a7dfa5 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -97,7 +97,7 @@ pub fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) { // // won't be allowed unless there's an *explicit* implementation of `Send` // for `T` - hir::ItemKind::Impl(_, _, defaultness, _, ref trait_ref, ref self_ty, _) => { + hir::ItemKind::Impl { defaultness, ref of_trait, ref self_ty, .. } => { let is_auto = tcx .impl_trait_ref(tcx.hir().local_def_id(item.hir_id)) .map_or(false, |trait_ref| tcx.trait_is_auto(trait_ref.def_id)); @@ -107,11 +107,11 @@ pub fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) { } match polarity { ty::ImplPolarity::Positive => { - check_impl(tcx, item, self_ty, trait_ref); + check_impl(tcx, item, self_ty, of_trait); } ty::ImplPolarity::Negative => { // FIXME(#27579): what amount of WF checking do we need for neg impls? - if trait_ref.is_some() && !is_auto { + if of_trait.is_some() && !is_auto { struct_span_err!( tcx.sess, item.span, diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index 8b3db15c02b4e..516dc16d46bd8 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/src/librustc_typeck/coherence/builtin.rs @@ -57,7 +57,7 @@ fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: DefId) { let impl_hir_id = tcx.hir().as_local_hir_id(impl_did).expect("foreign Drop impl on non-ADT"); let sp = match tcx.hir().expect_item(impl_hir_id).kind { - ItemKind::Impl(.., ty, _) => ty.span, + ItemKind::Impl { self_ty, .. } => self_ty.span, _ => bug!("expected Drop impl item"), }; @@ -94,7 +94,7 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: DefId) { Ok(()) => {} Err(CopyImplementationError::InfrigingFields(fields)) => { let item = tcx.hir().expect_item(impl_hir_id); - let span = if let ItemKind::Impl(.., Some(ref tr), _, _) = item.kind { + let span = if let ItemKind::Impl { of_trait: Some(ref tr), .. } = item.kind { tr.path.span } else { span @@ -113,7 +113,8 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: DefId) { } Err(CopyImplementationError::NotAnAdt) => { let item = tcx.hir().expect_item(impl_hir_id); - let span = if let ItemKind::Impl(.., ref ty, _) = item.kind { ty.span } else { span }; + let span = + if let ItemKind::Impl { self_ty, .. } = item.kind { self_ty.span } else { span }; struct_span_err!( tcx.sess, @@ -490,7 +491,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn return err_info; } else if diff_fields.len() > 1 { let item = tcx.hir().expect_item(impl_hir_id); - let span = if let ItemKind::Impl(.., Some(ref t), _, _) = item.kind { + let span = if let ItemKind::Impl { of_trait: Some(ref t), .. } = item.kind { t.path.span } else { tcx.hir().span(impl_hir_id) diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs index 673c1bd9fd831..d313e32fc20e0 100644 --- a/src/librustc_typeck/coherence/inherent_impls.rs +++ b/src/librustc_typeck/coherence/inherent_impls.rs @@ -47,7 +47,7 @@ struct InherentCollect<'tcx> { impl ItemLikeVisitor<'v> for InherentCollect<'tcx> { fn visit_item(&mut self, item: &hir::Item<'_>) { let ty = match item.kind { - hir::ItemKind::Impl(.., None, ref ty, _) => ty, + hir::ItemKind::Impl { of_trait: None, ref self_ty, .. } => self_ty, _ => return, }; diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index 1878f9385a891..9ba8fa4247f26 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -27,7 +27,7 @@ impl ItemLikeVisitor<'v> for OrphanChecker<'tcx> { fn visit_item(&mut self, item: &hir::Item<'_>) { let def_id = self.tcx.hir().local_def_id(item.hir_id); // "Trait" impl - if let hir::ItemKind::Impl(.., generics, Some(tr), impl_ty, _) = &item.kind { + if let hir::ItemKind::Impl { generics, of_trait: Some(ref tr), self_ty, .. } = &item.kind { debug!( "coherence2::orphan check: trait impl {}", self.tcx.hir().node_to_string(item.hir_id) @@ -72,7 +72,7 @@ impl ItemLikeVisitor<'v> for OrphanChecker<'tcx> { let msg = format!("{} is not defined in the current crate{}", ty, postfix); if *is_target_ty { // Point at `D` in `impl for C in D` - err.span_label(impl_ty.span, &msg); + err.span_label(self_ty.span, &msg); } else { // Point at `C` in `impl for C in D` err.span_label(tr.path.span, &msg); diff --git a/src/librustc_typeck/coherence/unsafety.rs b/src/librustc_typeck/coherence/unsafety.rs index 3f4035b0998d6..48b96886d3a71 100644 --- a/src/librustc_typeck/coherence/unsafety.rs +++ b/src/librustc_typeck/coherence/unsafety.rs @@ -88,7 +88,7 @@ impl UnsafetyChecker<'tcx> { impl ItemLikeVisitor<'v> for UnsafetyChecker<'tcx> { fn visit_item(&mut self, item: &'v hir::Item<'v>) { - if let hir::ItemKind::Impl(unsafety, polarity, _, ref generics, ..) = item.kind { + if let hir::ItemKind::Impl { unsafety, polarity, ref generics, .. } = item.kind { self.check_unsafety_coherence(item, Some(generics), unsafety, polarity); } } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index dca3289747e4c..a03b9f747372e 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -184,7 +184,7 @@ fn reject_placeholder_type_signatures_in_item(tcx: TyCtxt<'tcx>, item: &'tcx hir | hir::ItemKind::Enum(_, generics) | hir::ItemKind::TraitAlias(generics, _) | hir::ItemKind::Trait(_, _, generics, ..) - | hir::ItemKind::Impl(_, _, _, generics, ..) + | hir::ItemKind::Impl { generics, .. } | hir::ItemKind::Struct(_, generics) => (generics, true), hir::ItemKind::OpaqueTy(hir::OpaqueTy { generics, .. }) | hir::ItemKind::TyAlias(_, generics) => (generics, false), @@ -401,7 +401,7 @@ fn type_param_predicates( Node::Item(item) => { match item.kind { ItemKind::Fn(.., ref generics, _) - | ItemKind::Impl(_, _, _, ref generics, ..) + | ItemKind::Impl { ref generics, .. } | ItemKind::TyAlias(_, ref generics) | ItemKind::OpaqueTy(OpaqueTy { ref generics, impl_trait_fn: None, .. }) | ItemKind::Enum(_, ref generics) @@ -531,7 +531,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::HirId) { tcx.predicates_of(def_id); convert_enum_variant_types(tcx, def_id, &enum_definition.variants); } - hir::ItemKind::Impl(..) => { + hir::ItemKind::Impl { .. } => { tcx.generics_of(def_id); tcx.type_of(def_id); tcx.impl_trait_ref(def_id); @@ -1052,9 +1052,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics { Node::Item(item) => { match item.kind { - ItemKind::Fn(.., ref generics, _) | ItemKind::Impl(_, _, _, ref generics, ..) => { - generics - } + ItemKind::Fn(.., ref generics, _) | ItemKind::Impl { ref generics, .. } => generics, ItemKind::TyAlias(_, ref generics) | ItemKind::Enum(_, ref generics) @@ -1338,7 +1336,9 @@ fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { icx.to_ty(ty) } } - ItemKind::TyAlias(ref ty, _) | ItemKind::Impl(.., ref ty, _) => icx.to_ty(ty), + ItemKind::TyAlias(ref self_ty, _) | ItemKind::Impl { ref self_ty, .. } => { + icx.to_ty(self_ty) + } ItemKind::Fn(..) => { let substs = InternalSubsts::identity_for_item(tcx, def_id); tcx.mk_fn_def(def_id, substs) @@ -1956,12 +1956,10 @@ fn impl_trait_ref(tcx: TyCtxt<'_>, def_id: DefId) -> Option> { let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); match tcx.hir().expect_item(hir_id).kind { - hir::ItemKind::Impl(.., ref opt_trait_ref, _, _) => { - opt_trait_ref.as_ref().map(|ast_trait_ref| { - let selfty = tcx.type_of(def_id); - AstConv::instantiate_mono_trait_ref(&icx, ast_trait_ref, selfty) - }) - } + hir::ItemKind::Impl { ref of_trait, .. } => of_trait.as_ref().map(|ast_trait_ref| { + let selfty = tcx.type_of(def_id); + AstConv::instantiate_mono_trait_ref(&icx, ast_trait_ref, selfty) + }), _ => bug!(), } } @@ -1971,19 +1969,21 @@ fn impl_polarity(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ImplPolarity { let is_rustc_reservation = tcx.has_attr(def_id, sym::rustc_reservation_impl); let item = tcx.hir().expect_item(hir_id); match &item.kind { - hir::ItemKind::Impl(_, hir::ImplPolarity::Negative, ..) => { + hir::ItemKind::Impl { polarity: hir::ImplPolarity::Negative, .. } => { if is_rustc_reservation { tcx.sess.span_err(item.span, "reservation impls can't be negative"); } ty::ImplPolarity::Negative } - hir::ItemKind::Impl(_, hir::ImplPolarity::Positive, _, _, None, _, _) => { + hir::ItemKind::Impl { polarity: hir::ImplPolarity::Positive, of_trait: None, .. } => { if is_rustc_reservation { tcx.sess.span_err(item.span, "reservation impls can't be inherent"); } ty::ImplPolarity::Positive } - hir::ItemKind::Impl(_, hir::ImplPolarity::Positive, _, _, Some(_tr), _, _) => { + hir::ItemKind::Impl { + polarity: hir::ImplPolarity::Positive, of_trait: Some(_), .. + } => { if is_rustc_reservation { ty::ImplPolarity::Reservation } else { @@ -2142,7 +2142,7 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat Node::Item(item) => { match item.kind { - ItemKind::Impl(_, _, defaultness, ref generics, ..) => { + ItemKind::Impl { defaultness, ref generics, .. } => { if defaultness.is_default() { is_default_impl_trait = tcx.impl_trait_ref(def_id); } @@ -2359,7 +2359,7 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat // before uses of `U`. This avoids false ambiguity errors // in trait checking. See `setup_constraining_predicates` // for details. - if let Node::Item(&Item { kind: ItemKind::Impl(..), .. }) = node { + if let Node::Item(&Item { kind: ItemKind::Impl { .. }, .. }) = node { let self_ty = tcx.type_of(def_id); let trait_ref = tcx.impl_trait_ref(def_id); cgp::setup_constraining_predicates( diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs index fb87b285fa29f..9ee4e7c48190d 100644 --- a/src/librustc_typeck/impl_wf_check.rs +++ b/src/librustc_typeck/impl_wf_check.rs @@ -75,10 +75,10 @@ struct ImplWfCheck<'tcx> { impl ItemLikeVisitor<'tcx> for ImplWfCheck<'tcx> { fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { - if let hir::ItemKind::Impl(.., ref impl_item_refs) = item.kind { + if let hir::ItemKind::Impl { ref items, .. } = item.kind { let impl_def_id = self.tcx.hir().local_def_id(item.hir_id); - enforce_impl_params_are_constrained(self.tcx, impl_def_id, impl_item_refs); - enforce_impl_items_are_distinct(self.tcx, impl_item_refs); + enforce_impl_params_are_constrained(self.tcx, impl_def_id, items); + enforce_impl_items_are_distinct(self.tcx, items); } } diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index c7e0f1e9e704b..342eaad3a8f91 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -331,7 +331,7 @@ pub fn build_impl( let for_ = if let Some(hir_id) = tcx.hir().as_local_hir_id(did) { match tcx.hir().expect_item(hir_id).kind { - hir::ItemKind::Impl(.., ref t, _) => t.clean(cx), + hir::ItemKind::Impl { self_ty, .. } => self_ty.clean(cx), _ => panic!("did given to build_impl was not an impl"), } } else { @@ -351,9 +351,9 @@ pub fn build_impl( let predicates = tcx.explicit_predicates_of(did); let (trait_items, generics) = if let Some(hir_id) = tcx.hir().as_local_hir_id(did) { match tcx.hir().expect_item(hir_id).kind { - hir::ItemKind::Impl(.., ref gen, _, _, ref item_ids) => ( - item_ids.iter().map(|ii| tcx.hir().impl_item(ii.id).clean(cx)).collect::>(), - gen.clean(cx), + hir::ItemKind::Impl { ref generics, ref items, .. } => ( + items.iter().map(|item| tcx.hir().impl_item(item.id).clean(cx)).collect::>(), + generics.clean(cx), ), _ => panic!("did given to build_impl was not an impl"), } diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index f899e722a5615..05d4141568981 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -905,8 +905,8 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirCollector<'a, 'hir> { } fn visit_item(&mut self, item: &'hir hir::Item) { - let name = if let hir::ItemKind::Impl(.., ref ty, _) = item.kind { - self.map.hir_to_pretty_string(ty.hir_id) + let name = if let hir::ItemKind::Impl { ref self_ty, .. } = item.kind { + self.map.hir_to_pretty_string(self_ty.hir_id) } else { item.ident.to_string() }; diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 5fa9270959cca..fdff18779e795 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -558,27 +558,27 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { om.trait_aliases.push(t); } - hir::ItemKind::Impl( + hir::ItemKind::Impl { unsafety, polarity, defaultness, ref generics, - ref trait_, - for_, - ref item_ids, - ) => { + ref of_trait, + self_ty, + ref items, + } => { // Don't duplicate impls when inlining or if it's implementing a trait, we'll pick // them up regardless of where they're located. - if !self.inlining && trait_.is_none() { + if !self.inlining && of_trait.is_none() { let items = - item_ids.iter().map(|ii| self.cx.tcx.hir().impl_item(ii.id)).collect(); + items.iter().map(|item| self.cx.tcx.hir().impl_item(item.id)).collect(); let i = Impl { unsafety, polarity, defaultness, generics, - trait_, - for_, + trait_: of_trait, + for_: self_ty, items, attrs: &item.attrs, id: item.hir_id, From af6282f92a6d4dd9c556535fc40b4b04f531b8a5 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Sat, 18 Jan 2020 13:33:17 +0100 Subject: [PATCH 153/169] Fix table of syscalls in docs of std::time::Instant. --- src/libstd/time.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 0b6e728dceb1d..2e3e3b743a49f 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -65,7 +65,7 @@ pub use core::time::Duration; /// /// | Platform | System call | /// |:---------:|:--------------------------------------------------------------------:| -/// | Cloud ABI | [clock_time_get (Monotonic Clock)] | +/// | CloudABI | [clock_time_get (Monotonic Clock)] | /// | SGX | [`insecure_time` usercall]. More information on [timekeeping in SGX] | /// | UNIX | [clock_gettime (Monotonic Clock)] | /// | Darwin | [mach_absolute_time] | @@ -79,7 +79,7 @@ pub use core::time::Duration; /// [__wasi_clock_time_get (Monotonic Clock)]: https://github.com/CraneStation/wasmtime/blob/master/docs/WASI-api.md#clock_time_get /// [clock_gettime (Monotonic Clock)]: https://linux.die.net/man/3/clock_gettime /// [mach_absolute_time]: https://developer.apple.com/library/archive/documentation/Darwin/Conceptual/KernelProgramming/services/services.html -/// [clock_time_get (Monotonic Clock)]: https://github.com/NuxiNL/cloudabi/blob/master/cloudabi.txt +/// [clock_time_get (Monotonic Clock)]: https://nuxi.nl/cloudabi/#clock_time_get /// /// **Disclaimer:** These system calls might change over time. /// From 366f619a49162588770af9f23099ca9407d1992a Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Sat, 18 Jan 2020 13:33:17 +0100 Subject: [PATCH 154/169] Fix table of syscalls in docs of std::time::SystemTime. --- src/libstd/time.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 2e3e3b743a49f..5bc8fe5ae6d79 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -144,7 +144,7 @@ pub struct Instant(time::Instant); /// /// | Platform | System call | /// |:---------:|:--------------------------------------------------------------------:| -/// | Cloud ABI | [clock_time_get (Realtime Clock)] | +/// | CloudABI | [clock_time_get (Realtime Clock)] | /// | SGX | [`insecure_time` usercall]. More information on [timekeeping in SGX] | /// | UNIX | [clock_gettime (Realtime Clock)] | /// | DARWIN | [gettimeofday] | @@ -152,7 +152,7 @@ pub struct Instant(time::Instant); /// | WASI | [__wasi_clock_time_get (Realtime Clock)] | /// | Windows | [GetSystemTimeAsFileTime] | /// -/// [clock_time_get (Realtime Clock)]: https://github.com/NuxiNL/cloudabi/blob/master/cloudabi.txt +/// [clock_time_get (Realtime Clock)]: https://nuxi.nl/cloudabi/#clock_time_get /// [`insecure_time` usercall]: https://edp.fortanix.com/docs/api/fortanix_sgx_abi/struct.Usercalls.html#method.insecure_time /// [timekeeping in SGX]: https://edp.fortanix.com/docs/concepts/rust-std/#codestdtimecode /// [gettimeofday]: http://man7.org/linux/man-pages/man2/gettimeofday.2.html From 6b7f3e50df3b4235756df9354ea90cf821460a8b Mon Sep 17 00:00:00 2001 From: lcnr/Bastian Kauschke Date: Sat, 18 Jan 2020 14:43:08 +0100 Subject: [PATCH 155/169] improve type_name_of_val docs --- src/libcore/any.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/libcore/any.rs b/src/libcore/any.rs index 7935c9b1b392d..c5dcdfed12ae0 100644 --- a/src/libcore/any.rs +++ b/src/libcore/any.rs @@ -476,11 +476,15 @@ pub const fn type_name() -> &'static str { /// /// This is intended for diagnostic use. The exact contents and format of the /// string are not specified, other than being a best-effort description of the -/// type. For example, `type_name_of::>(None)` could return +/// type. For example, `type_name_of_val::>(None)` could return /// `"Option"` or `"std::option::Option"`, but not /// `"foobar"`. In addition, the output may change between versions of the /// compiler. /// +/// This function does not resolve trait objects, +/// meaning that `type_name_of_val(&7u32 as &dyn Debug)` +/// may return `"dyn Debug"`, but not `"u32"`. +/// /// The type name should not be considered a unique identifier of a type; /// multiple types may share the same type name. /// From 9746b05da995629780f559e68cde2a3d41b3b2bc Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 18 Jan 2020 13:12:30 +0100 Subject: [PATCH 156/169] clean up e0200 explanation --- src/librustc_error_codes/error_codes/E0200.md | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0200.md b/src/librustc_error_codes/error_codes/E0200.md index 865e91430ac44..7245bb59ce5ff 100644 --- a/src/librustc_error_codes/error_codes/E0200.md +++ b/src/librustc_error_codes/error_codes/E0200.md @@ -1,14 +1,23 @@ +An unsafe trait was implemented without an unsafe implementation. + +Erroneous code example: + +```compile_fail,E0200 +struct Foo; + +unsafe trait Bar { } + +impl Bar for Foo { } // error! +``` + Unsafe traits must have unsafe implementations. This error occurs when an implementation for an unsafe trait isn't marked as unsafe. This may be resolved by marking the unsafe implementation as unsafe. -```compile_fail,E0200 +``` struct Foo; unsafe trait Bar { } -// this won't compile because Bar is unsafe and impl isn't unsafe -impl Bar for Foo { } -// this will compile -unsafe impl Bar for Foo { } +unsafe impl Bar for Foo { } // ok! ``` From c41443a2b729054c48cd798e341f75f076b390a7 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 30 Dec 2019 00:16:16 +0100 Subject: [PATCH 157/169] stabilize slice_patterns --- src/librustc_ast_passes/feature_gate.rs | 21 --------------------- src/librustc_feature/accepted.rs | 2 ++ src/librustc_feature/active.rs | 3 --- 3 files changed, 2 insertions(+), 24 deletions(-) diff --git a/src/librustc_ast_passes/feature_gate.rs b/src/librustc_ast_passes/feature_gate.rs index 71cd66ddef409..461072873bb52 100644 --- a/src/librustc_ast_passes/feature_gate.rs +++ b/src/librustc_ast_passes/feature_gate.rs @@ -470,29 +470,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { visit::walk_expr(self, e) } - fn visit_arm(&mut self, arm: &'a ast::Arm) { - visit::walk_arm(self, arm) - } - fn visit_pat(&mut self, pattern: &'a ast::Pat) { match &pattern.kind { - PatKind::Slice(pats) => { - for pat in &*pats { - let span = pat.span; - let inner_pat = match &pat.kind { - PatKind::Ident(.., Some(pat)) => pat, - _ => pat, - }; - if inner_pat.is_rest() { - gate_feature_post!( - &self, - slice_patterns, - span, - "subslice patterns are unstable" - ); - } - } - } PatKind::Box(..) => { gate_feature_post!( &self, diff --git a/src/librustc_feature/accepted.rs b/src/librustc_feature/accepted.rs index d880fc84b3819..007cee4c76424 100644 --- a/src/librustc_feature/accepted.rs +++ b/src/librustc_feature/accepted.rs @@ -257,6 +257,8 @@ declare_features! ( /// Allows relaxing the coherence rules such that /// `impl ForeignTrait for ForeignType` is permitted. (accepted, re_rebalance_coherence, "1.41.0", Some(55437), None), + /// Allows using subslice patterns, `[a, .., b]` and `[a, xs @ .., b]`. + (accepted, slice_patterns, "1.42.0", Some(62254), None), // ------------------------------------------------------------------------- // feature-group-end: accepted features diff --git a/src/librustc_feature/active.rs b/src/librustc_feature/active.rs index 4c8c47a567113..6af9b6c087278 100644 --- a/src/librustc_feature/active.rs +++ b/src/librustc_feature/active.rs @@ -262,9 +262,6 @@ declare_features! ( /// Allows using non lexical lifetimes (RFC 2094). (active, nll, "1.0.0", Some(43234), None), - /// Allows using slice patterns. - (active, slice_patterns, "1.0.0", Some(62254), None), - /// Allows the definition of `const` functions with some advanced features. (active, const_fn, "1.2.0", Some(57563), None), From 0aebb0811548202b177ab411a7570e1fd3e43bc0 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 30 Dec 2019 00:31:35 +0100 Subject: [PATCH 158/169] slice_patterns: adjust error codes --- src/librustc_error_codes/error_codes/E0527.md | 2 -- src/librustc_error_codes/error_codes/E0528.md | 4 ---- src/librustc_error_codes/error_codes/E0730.md | 2 -- 3 files changed, 8 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0527.md b/src/librustc_error_codes/error_codes/E0527.md index 4bff39dc770e0..97ea312693881 100644 --- a/src/librustc_error_codes/error_codes/E0527.md +++ b/src/librustc_error_codes/error_codes/E0527.md @@ -17,8 +17,6 @@ Ensure that the pattern is consistent with the size of the matched array. Additional elements can be matched with `..`: ``` -#![feature(slice_patterns)] - let r = &[1, 2, 3, 4]; match r { &[a, b, ..] => { // ok! diff --git a/src/librustc_error_codes/error_codes/E0528.md b/src/librustc_error_codes/error_codes/E0528.md index 4b6ea2469919c..54c2c4d4e9d0f 100644 --- a/src/librustc_error_codes/error_codes/E0528.md +++ b/src/librustc_error_codes/error_codes/E0528.md @@ -4,8 +4,6 @@ matched array. Example of erroneous code: ```compile_fail,E0528 -#![feature(slice_patterns)] - let r = &[1, 2]; match r { &[a, b, c, rest @ ..] => { // error: pattern requires at least 3 @@ -19,8 +17,6 @@ Ensure that the matched array has at least as many elements as the pattern requires. You can match an arbitrary number of remaining elements with `..`: ``` -#![feature(slice_patterns)] - let r = &[1, 2, 3, 4, 5]; match r { &[a, b, c, rest @ ..] => { // ok! diff --git a/src/librustc_error_codes/error_codes/E0730.md b/src/librustc_error_codes/error_codes/E0730.md index 803a25148651c..bf1f72be32589 100644 --- a/src/librustc_error_codes/error_codes/E0730.md +++ b/src/librustc_error_codes/error_codes/E0730.md @@ -18,8 +18,6 @@ Ensure that the pattern is consistent with the size of the matched array. Additional elements can be matched with `..`: ``` -#![feature(slice_patterns)] - let r = &[1, 2, 3, 4]; match r { &[a, b, ..] => { // ok! From a70b24018936fe59f0a037adfa13f2255d8aa5d2 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Sat, 18 Jan 2020 18:35:36 +0100 Subject: [PATCH 159/169] Make iter::Empty implement Send and Sync for any T --- src/libcore/iter/sources.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libcore/iter/sources.rs b/src/libcore/iter/sources.rs index a65d47cc2c1f0..25dfc573e416a 100644 --- a/src/libcore/iter/sources.rs +++ b/src/libcore/iter/sources.rs @@ -208,6 +208,11 @@ pub fn repeat_with A>(repeater: F) -> RepeatWith { #[stable(feature = "iter_empty", since = "1.2.0")] pub struct Empty(marker::PhantomData); +#[stable(feature = "iter_empty_send_sync", since = "1.42.0")] +unsafe impl Send for Empty {} +#[stable(feature = "iter_empty_send_sync", since = "1.42.0")] +unsafe impl Sync for Empty {} + #[stable(feature = "core_impl_debug", since = "1.9.0")] impl fmt::Debug for Empty { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { From d7a18f89864a4360230e3cbbdcbf22d9864a86e0 Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Thu, 17 Jan 2019 00:07:22 +0100 Subject: [PATCH 160/169] Add a test for iter::empty::<*mut i32> being Sync and Send --- src/test/ui/threads-sendsync/sync-send-iterators-in-libcore.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/ui/threads-sendsync/sync-send-iterators-in-libcore.rs b/src/test/ui/threads-sendsync/sync-send-iterators-in-libcore.rs index 44beb9dc1e534..2f6d35f01be62 100644 --- a/src/test/ui/threads-sendsync/sync-send-iterators-in-libcore.rs +++ b/src/test/ui/threads-sendsync/sync-send-iterators-in-libcore.rs @@ -88,6 +88,7 @@ fn main() { is_sync_send!((1..)); is_sync_send!(repeat(1)); is_sync_send!(empty::()); + is_sync_send!(empty::<*mut i32>()); is_sync_send!(once(1)); // for option.rs From 3ccb0f9b8f990df7f2149655fb3bf7585ddc8cad Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 30 Dec 2019 00:32:02 +0100 Subject: [PATCH 161/169] slice_patterns: remove internal uses of gate --- src/libcore/lib.rs | 2 +- src/libcore/tests/lib.rs | 2 +- src/librustc/benches/lib.rs | 2 +- src/librustc/lib.rs | 2 +- src/librustc_ast_passes/lib.rs | 2 +- src/librustc_codegen_ssa/lib.rs | 2 +- src/librustc_metadata/lib.rs | 2 +- src/librustc_mir/lib.rs | 2 +- src/librustc_mir_build/lib.rs | 2 +- src/librustc_parse/lib.rs | 2 +- src/librustc_passes/lib.rs | 2 +- src/librustc_target/lib.rs | 2 +- src/librustc_ty/lib.rs | 2 +- src/librustc_typeck/lib.rs | 2 +- src/libstd/lib.rs | 2 +- src/libsyntax/lib.rs | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 15720ddcfc677..f77b4d7461e74 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -133,7 +133,7 @@ #![feature(associated_type_bounds)] #![feature(const_type_id)] #![feature(const_caller_location)] -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] #[prelude_import] #[allow(unused)] diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index 8c034938c2bb9..f0420247acfbd 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -19,7 +19,7 @@ #![feature(range_is_empty)] #![feature(raw)] #![feature(saturating_neg)] -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] #![feature(sort_internals)] #![feature(slice_partition_at_index)] #![feature(specialization)] diff --git a/src/librustc/benches/lib.rs b/src/librustc/benches/lib.rs index ffb12f11c5136..de82b262e4956 100644 --- a/src/librustc/benches/lib.rs +++ b/src/librustc/benches/lib.rs @@ -1,4 +1,4 @@ -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] #![feature(test)] extern crate test; diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index b894aabd90100..69ca40636948f 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -42,7 +42,7 @@ #![feature(optin_builtin_traits)] #![feature(option_expect_none)] #![feature(range_is_empty)] -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] #![feature(specialization)] #![feature(unboxed_closures)] #![feature(thread_local)] diff --git a/src/librustc_ast_passes/lib.rs b/src/librustc_ast_passes/lib.rs index eadbc485296e8..5de45f4e1f365 100644 --- a/src/librustc_ast_passes/lib.rs +++ b/src/librustc_ast_passes/lib.rs @@ -2,7 +2,7 @@ //! parsed by `rustc_parse` and then lowered, after the passes in this crate, //! by `rustc_ast_lowering`. -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] pub mod ast_validation; pub mod feature_gate; diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs index ee527ecb509b2..aba77231268e7 100644 --- a/src/librustc_codegen_ssa/lib.rs +++ b/src/librustc_codegen_ssa/lib.rs @@ -4,7 +4,7 @@ #![feature(box_syntax)] #![feature(core_intrinsics)] #![feature(libc)] -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] #![feature(stmt_expr_attributes)] #![feature(try_blocks)] #![feature(in_band_lifetimes)] diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index 0fec4bff1633d..cf925ab91875f 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -10,7 +10,7 @@ #![feature(proc_macro_internals)] #![feature(proc_macro_quote)] #![feature(rustc_private)] -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] #![feature(specialization)] #![feature(stmt_expr_attributes)] #![recursion_limit = "256"] diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 1c25b269b18fd..5e42ba3279027 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -7,7 +7,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(nll)] #![feature(in_band_lifetimes)] #![feature(inner_deref)] -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] #![feature(bool_to_option)] #![feature(box_patterns)] #![feature(box_syntax)] diff --git a/src/librustc_mir_build/lib.rs b/src/librustc_mir_build/lib.rs index 5a17f36e1da25..42292d635bc75 100644 --- a/src/librustc_mir_build/lib.rs +++ b/src/librustc_mir_build/lib.rs @@ -5,7 +5,7 @@ #![feature(box_patterns)] #![feature(box_syntax)] #![feature(crate_visibility_modifier)] -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] #![feature(bool_to_option)] #![recursion_limit = "256"] diff --git a/src/librustc_parse/lib.rs b/src/librustc_parse/lib.rs index 9227e968ecc4f..08f4f210152dd 100644 --- a/src/librustc_parse/lib.rs +++ b/src/librustc_parse/lib.rs @@ -2,7 +2,7 @@ #![feature(bool_to_option)] #![feature(crate_visibility_modifier)] -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] use syntax::ast; use syntax::print::pprust; diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs index 65eb07b989d83..d746f097928ea 100644 --- a/src/librustc_passes/lib.rs +++ b/src/librustc_passes/lib.rs @@ -7,7 +7,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(in_band_lifetimes)] #![feature(nll)] -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] #![recursion_limit = "256"] #[macro_use] diff --git a/src/librustc_target/lib.rs b/src/librustc_target/lib.rs index 17413e77f9007..84c6d720b8e00 100644 --- a/src/librustc_target/lib.rs +++ b/src/librustc_target/lib.rs @@ -11,7 +11,7 @@ #![feature(box_syntax)] #![feature(bool_to_option)] #![feature(nll)] -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] #[macro_use] extern crate log; diff --git a/src/librustc_ty/lib.rs b/src/librustc_ty/lib.rs index 2548d2cff9766..e5ec98743e0ae 100644 --- a/src/librustc_ty/lib.rs +++ b/src/librustc_ty/lib.rs @@ -8,7 +8,7 @@ #![feature(bool_to_option)] #![feature(in_band_lifetimes)] #![feature(nll)] -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] #![recursion_limit = "256"] #[macro_use] diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index b951883ac195a..95cd3c631ed22 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -64,7 +64,7 @@ This API is completely unstable and subject to change. #![feature(exhaustive_patterns)] #![feature(in_band_lifetimes)] #![feature(nll)] -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] #![feature(try_blocks)] #![feature(never_type)] #![recursion_limit = "256"] diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index f90647472c678..c8fae91fcf3a5 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -294,7 +294,7 @@ #![feature(shrink_to)] #![feature(slice_concat_ext)] #![feature(slice_internals)] -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] #![feature(specialization)] #![feature(staged_api)] #![feature(std_internals)] diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 0184a3214b5b4..b0c2aa3dbb28e 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -13,7 +13,7 @@ #![feature(label_break_value)] #![feature(nll)] #![feature(try_trait)] -#![feature(slice_patterns)] +#![cfg_attr(bootstrap, feature(slice_patterns))] #![feature(unicode_internals)] #![recursion_limit = "256"] From 3e3cac010b318c6a2aa89ffbbafaea169898ba3d Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 30 Dec 2019 00:33:10 +0100 Subject: [PATCH 162/169] slice_patterns: remove feature gate test --- .../feature-gate-slice-patterns.rs | 17 ------ .../feature-gate-slice-patterns.stderr | 57 ------------------- 2 files changed, 74 deletions(-) delete mode 100644 src/test/ui/feature-gates/feature-gate-slice-patterns.rs delete mode 100644 src/test/ui/feature-gates/feature-gate-slice-patterns.stderr diff --git a/src/test/ui/feature-gates/feature-gate-slice-patterns.rs b/src/test/ui/feature-gates/feature-gate-slice-patterns.rs deleted file mode 100644 index f2a1b135b69cb..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-slice-patterns.rs +++ /dev/null @@ -1,17 +0,0 @@ -// Test that slice pattern syntax with `..` is gated by `slice_patterns` feature gate - -fn main() { - let x = [1, 2, 3, 4, 5]; - match x { - [1, 2, ..] => {} //~ ERROR subslice patterns are unstable - [1, .., 5] => {} //~ ERROR subslice patterns are unstable - [.., 4, 5] => {} //~ ERROR subslice patterns are unstable - } - - let x = [ 1, 2, 3, 4, 5 ]; - match x { - [ xs @ .., 4, 5 ] => {} //~ ERROR subslice patterns are unstable - [ 1, xs @ .., 5 ] => {} //~ ERROR subslice patterns are unstable - [ 1, 2, xs @ .. ] => {} //~ ERROR subslice patterns are unstable - } -} diff --git a/src/test/ui/feature-gates/feature-gate-slice-patterns.stderr b/src/test/ui/feature-gates/feature-gate-slice-patterns.stderr deleted file mode 100644 index d4946a42b8f3d..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-slice-patterns.stderr +++ /dev/null @@ -1,57 +0,0 @@ -error[E0658]: subslice patterns are unstable - --> $DIR/feature-gate-slice-patterns.rs:6:16 - | -LL | [1, 2, ..] => {} - | ^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/62254 - = help: add `#![feature(slice_patterns)]` to the crate attributes to enable - -error[E0658]: subslice patterns are unstable - --> $DIR/feature-gate-slice-patterns.rs:7:13 - | -LL | [1, .., 5] => {} - | ^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/62254 - = help: add `#![feature(slice_patterns)]` to the crate attributes to enable - -error[E0658]: subslice patterns are unstable - --> $DIR/feature-gate-slice-patterns.rs:8:10 - | -LL | [.., 4, 5] => {} - | ^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/62254 - = help: add `#![feature(slice_patterns)]` to the crate attributes to enable - -error[E0658]: subslice patterns are unstable - --> $DIR/feature-gate-slice-patterns.rs:13:11 - | -LL | [ xs @ .., 4, 5 ] => {} - | ^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/62254 - = help: add `#![feature(slice_patterns)]` to the crate attributes to enable - -error[E0658]: subslice patterns are unstable - --> $DIR/feature-gate-slice-patterns.rs:14:14 - | -LL | [ 1, xs @ .., 5 ] => {} - | ^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/62254 - = help: add `#![feature(slice_patterns)]` to the crate attributes to enable - -error[E0658]: subslice patterns are unstable - --> $DIR/feature-gate-slice-patterns.rs:15:17 - | -LL | [ 1, 2, xs @ .. ] => {} - | ^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/62254 - = help: add `#![feature(slice_patterns)]` to the crate attributes to enable - -error: aborting due to 6 previous errors - -For more information about this error, try `rustc --explain E0658`. From a1eadca88f03de91f5eecd316419d32e2a302c2b Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 30 Dec 2019 01:23:42 +0100 Subject: [PATCH 163/169] slice_patterns: remove gates in tests --- src/test/mir-opt/uniform_array_move_out.rs | 1 - .../subslice-patterns-const-eval-match.rs | 2 +- .../subslice-patterns-const-eval.rs | 2 - .../array-slice-vec/subslice-patterns-pass.rs | 2 - .../ui/array-slice-vec/vec-matching-fixed.rs | 2 - .../ui/array-slice-vec/vec-matching-fold.rs | 2 - .../vec-matching-legal-tail-element-borrow.rs | 3 +- src/test/ui/array-slice-vec/vec-matching.rs | 2 - .../ui/array-slice-vec/vec-tail-matching.rs | 2 - .../ui/binding/empty-types-in-patterns.rs | 3 +- .../ui/binding/irrefutable-slice-patterns.rs | 3 +- .../ui/binding/match-byte-array-patterns.rs | 1 - src/test/ui/binding/match-vec-alternatives.rs | 1 - .../ui/binding/zero_sized_subslice_match.rs | 1 - .../borrowck-closures-slice-patterns-ok.rs | 1 - .../borrowck-closures-slice-patterns.rs | 2 - .../borrowck-closures-slice-patterns.stderr | 16 ++-- .../ui/borrowck/borrowck-describe-lvalue.rs | 2 - .../borrowck/borrowck-describe-lvalue.stderr | 64 ++++++------- .../borrowck-move-out-from-array-match.rs | 2 - .../borrowck-move-out-from-array-match.stderr | 20 ++--- ...ck-move-out-from-array-no-overlap-match.rs | 2 - ...ove-out-from-array-no-overlap-match.stderr | 18 ++-- ...borrowck-move-out-from-array-no-overlap.rs | 2 - .../borrowck-move-out-from-array-use-match.rs | 2 - ...rowck-move-out-from-array-use-match.stderr | 28 +++--- ...ove-out-from-array-use-no-overlap-match.rs | 2 - ...out-from-array-use-no-overlap-match.stderr | 18 ++-- ...owck-move-out-from-array-use-no-overlap.rs | 2 - .../borrowck-move-out-from-array-use.rs | 2 - .../borrowck-move-out-from-array-use.stderr | 28 +++--- .../borrowck/borrowck-move-out-from-array.rs | 2 - .../borrowck-move-out-from-array.stderr | 20 ++--- .../borrowck/borrowck-move-out-of-vec-tail.rs | 2 - .../borrowck-move-out-of-vec-tail.stderr | 2 +- ...e-pattern-element-loan-array-no-overlap.rs | 2 - ...rrowck-slice-pattern-element-loan-array.rs | 2 - ...ck-slice-pattern-element-loan-array.stderr | 16 ++-- ...rrowck-slice-pattern-element-loan-rpass.rs | 4 +- ...e-pattern-element-loan-slice-no-overlap.rs | 2 - ...rrowck-slice-pattern-element-loan-slice.rs | 2 - ...ck-slice-pattern-element-loan-slice.stderr | 22 ++--- .../borrowck-vec-pattern-element-loan.rs | 2 - .../borrowck-vec-pattern-element-loan.stderr | 6 +- .../borrowck-vec-pattern-loan-from-mut.rs | 2 - .../borrowck-vec-pattern-loan-from-mut.stderr | 2 +- .../borrowck-vec-pattern-move-tail.rs | 4 - .../borrowck-vec-pattern-move-tail.stderr | 2 +- .../borrowck/borrowck-vec-pattern-nesting.rs | 1 - .../borrowck-vec-pattern-nesting.stderr | 16 ++-- .../borrowck-vec-pattern-tail-element-loan.rs | 2 - ...rowck-vec-pattern-tail-element-loan.stderr | 2 +- .../ui/consts/const_prop_slice_pat_ice.rs | 1 - src/test/ui/drop/dynamic-drop-async.rs | 1 - src/test/ui/drop/dynamic-drop.rs | 7 +- src/test/ui/error-codes/E0528.rs | 2 - src/test/ui/error-codes/E0528.stderr | 2 +- src/test/ui/ignore-all-the-things.rs | 4 +- src/test/ui/issues/issue-12369.rs | 1 - src/test/ui/issues/issue-12369.stderr | 4 +- src/test/ui/issues/issue-12567.rs | 2 - src/test/ui/issues/issue-12567.stderr | 4 +- src/test/ui/issues/issue-15080.rs | 1 - src/test/ui/issues/issue-15104.rs | 1 - src/test/ui/issues/issue-17877.rs | 1 - src/test/ui/issues/issue-23311.rs | 3 +- src/test/ui/issues/issue-26619.rs | 2 - src/test/ui/issues/issue-26619.stderr | 2 +- src/test/ui/issues/issue-37598.rs | 1 - src/test/ui/issues/issue-7784.rs | 1 - src/test/ui/match/match-vec-mismatch.rs | 2 - src/test/ui/match/match-vec-mismatch.stderr | 10 +-- src/test/ui/moves/move-out-of-array-ref.rs | 2 - .../ui/moves/move-out-of-array-ref.stderr | 8 +- .../exhaustiveness-non-exhaustive.rs | 2 +- .../ui/or-patterns/exhaustiveness-pass.rs | 2 +- .../exhaustiveness-unreachable-pattern.rs | 2 +- src/test/ui/parser/match-vec-invalid.rs | 2 - src/test/ui/parser/match-vec-invalid.stderr | 24 +---- src/test/ui/parser/pat-lt-bracket-6.rs | 1 - src/test/ui/parser/pat-lt-bracket-6.stderr | 16 +--- .../borrowck-move-and-move.rs | 1 - .../borrowck-move-and-move.stderr | 32 +++---- .../borrowck-pat-at-and-box-pass.rs | 1 - .../borrowck-pat-at-and-box.rs | 1 - .../borrowck-pat-at-and-box.stderr | 48 +++++----- .../borrowck-pat-by-copy-bindings-in-at.rs | 1 - .../borrowck-pat-ref-both-sides.rs | 1 - .../borrowck-pat-ref-mut-and-ref.rs | 1 - .../borrowck-pat-ref-mut-and-ref.stderr | 90 +++++++++---------- .../borrowck-pat-ref-mut-twice.rs | 1 - .../borrowck-pat-ref-mut-twice.stderr | 64 ++++++------- .../issue-53820-slice-pattern-large-array.rs | 2 - ...413-constants-and-slices-exhaustiveness.rs | 2 +- .../usefulness/match-byte-array-patterns.rs | 1 - .../match-byte-array-patterns.stderr | 18 ++-- .../usefulness/match-slice-patterns.rs | 2 - .../usefulness/match-slice-patterns.stderr | 2 +- .../usefulness/match-vec-unreachable.rs | 1 - .../usefulness/match-vec-unreachable.stderr | 8 +- .../usefulness/non-exhaustive-match-nested.rs | 2 - .../non-exhaustive-match-nested.stderr | 4 +- .../usefulness/non-exhaustive-match.rs | 1 - .../usefulness/non-exhaustive-match.stderr | 16 ++-- .../non-exhaustive-pattern-witness.rs | 2 - .../non-exhaustive-pattern-witness.stderr | 14 +-- .../slice-patterns-exhaustiveness.rs | 2 - .../slice-patterns-exhaustiveness.stderr | 32 +++---- .../usefulness/slice-patterns-irrefutable.rs | 1 - .../usefulness/slice-patterns-reachability.rs | 1 - .../slice-patterns-reachability.stderr | 14 +-- .../ui/rfc-2005-default-binding-mode/slice.rs | 2 - .../slice.stderr | 2 +- .../rfc-2005-default-binding-mode/slice.rs | 1 - src/test/ui/trailing-comma.rs | 2 - .../ui/uninhabited/uninhabited-patterns.rs | 2 +- 116 files changed, 349 insertions(+), 490 deletions(-) diff --git a/src/test/mir-opt/uniform_array_move_out.rs b/src/test/mir-opt/uniform_array_move_out.rs index f2e1864096ea9..d587d237227ad 100644 --- a/src/test/mir-opt/uniform_array_move_out.rs +++ b/src/test/mir-opt/uniform_array_move_out.rs @@ -1,5 +1,4 @@ #![feature(box_syntax)] -#![feature(slice_patterns)] fn move_out_from_end() { let a = [box 1, box 2]; diff --git a/src/test/ui/array-slice-vec/subslice-patterns-const-eval-match.rs b/src/test/ui/array-slice-vec/subslice-patterns-const-eval-match.rs index 0e767d9613a99..69c33921868cf 100644 --- a/src/test/ui/array-slice-vec/subslice-patterns-const-eval-match.rs +++ b/src/test/ui/array-slice-vec/subslice-patterns-const-eval-match.rs @@ -2,7 +2,7 @@ // run-pass -#![feature(slice_patterns, const_fn, const_if_match)] +#![feature(const_fn, const_if_match)] #[derive(PartialEq, Debug, Clone)] struct N(u8); diff --git a/src/test/ui/array-slice-vec/subslice-patterns-const-eval.rs b/src/test/ui/array-slice-vec/subslice-patterns-const-eval.rs index 5444f8a9051bd..0b793fa0120e9 100644 --- a/src/test/ui/array-slice-vec/subslice-patterns-const-eval.rs +++ b/src/test/ui/array-slice-vec/subslice-patterns-const-eval.rs @@ -2,8 +2,6 @@ // run-pass -#![feature(slice_patterns)] - #[derive(PartialEq, Debug, Clone)] struct N(u8); diff --git a/src/test/ui/array-slice-vec/subslice-patterns-pass.rs b/src/test/ui/array-slice-vec/subslice-patterns-pass.rs index 1ebf3def78876..e05790911f52d 100644 --- a/src/test/ui/array-slice-vec/subslice-patterns-pass.rs +++ b/src/test/ui/array-slice-vec/subslice-patterns-pass.rs @@ -4,8 +4,6 @@ // run-pass -#![feature(slice_patterns)] - #![allow(unreachable_patterns)] use std::convert::identity; diff --git a/src/test/ui/array-slice-vec/vec-matching-fixed.rs b/src/test/ui/array-slice-vec/vec-matching-fixed.rs index 5253bc1b21430..fdeb7e4fda640 100644 --- a/src/test/ui/array-slice-vec/vec-matching-fixed.rs +++ b/src/test/ui/array-slice-vec/vec-matching-fixed.rs @@ -1,7 +1,5 @@ // run-pass -#![feature(slice_patterns)] - fn a() { let x = [1, 2, 3]; match x { diff --git a/src/test/ui/array-slice-vec/vec-matching-fold.rs b/src/test/ui/array-slice-vec/vec-matching-fold.rs index f416160db2422..998899271e411 100644 --- a/src/test/ui/array-slice-vec/vec-matching-fold.rs +++ b/src/test/ui/array-slice-vec/vec-matching-fold.rs @@ -1,7 +1,5 @@ // run-pass -#![feature(slice_patterns)] - use std::fmt::Debug; fn foldl(values: &[T], diff --git a/src/test/ui/array-slice-vec/vec-matching-legal-tail-element-borrow.rs b/src/test/ui/array-slice-vec/vec-matching-legal-tail-element-borrow.rs index f0602c328b071..ed34f074a929a 100644 --- a/src/test/ui/array-slice-vec/vec-matching-legal-tail-element-borrow.rs +++ b/src/test/ui/array-slice-vec/vec-matching-legal-tail-element-borrow.rs @@ -1,7 +1,6 @@ // run-pass -#![allow(unused_variables)] -#![feature(slice_patterns)] +#![allow(unused_variables)] pub fn main() { let x = &[1, 2, 3, 4, 5]; diff --git a/src/test/ui/array-slice-vec/vec-matching.rs b/src/test/ui/array-slice-vec/vec-matching.rs index 49c736bd72847..7009244aa189a 100644 --- a/src/test/ui/array-slice-vec/vec-matching.rs +++ b/src/test/ui/array-slice-vec/vec-matching.rs @@ -1,7 +1,5 @@ // run-pass -#![feature(slice_patterns)] - fn a() { let x = [1]; match x { diff --git a/src/test/ui/array-slice-vec/vec-tail-matching.rs b/src/test/ui/array-slice-vec/vec-tail-matching.rs index 3c7b160dcc540..5f1699227d8e6 100644 --- a/src/test/ui/array-slice-vec/vec-tail-matching.rs +++ b/src/test/ui/array-slice-vec/vec-tail-matching.rs @@ -1,7 +1,5 @@ // run-pass -#![feature(slice_patterns)] - struct Foo { string: &'static str } diff --git a/src/test/ui/binding/empty-types-in-patterns.rs b/src/test/ui/binding/empty-types-in-patterns.rs index 4271ffb7b1b4d..0d0dbcaf40f43 100644 --- a/src/test/ui/binding/empty-types-in-patterns.rs +++ b/src/test/ui/binding/empty-types-in-patterns.rs @@ -1,7 +1,8 @@ // run-pass + #![feature(never_type, never_type_fallback)] #![feature(exhaustive_patterns)] -#![feature(slice_patterns)] + #![allow(unreachable_patterns)] #![allow(unreachable_code)] #![allow(unused_variables)] diff --git a/src/test/ui/binding/irrefutable-slice-patterns.rs b/src/test/ui/binding/irrefutable-slice-patterns.rs index ac733ef6e9c86..048e1e5e9b4b6 100644 --- a/src/test/ui/binding/irrefutable-slice-patterns.rs +++ b/src/test/ui/binding/irrefutable-slice-patterns.rs @@ -1,7 +1,6 @@ // run-pass -// #47096 -#![feature(slice_patterns)] +// Regression test for #47096. fn foo(s: &[i32]) -> &[i32] { let &[ref xs @ ..] = s; diff --git a/src/test/ui/binding/match-byte-array-patterns.rs b/src/test/ui/binding/match-byte-array-patterns.rs index e87745705da08..f0c988c01c2b8 100644 --- a/src/test/ui/binding/match-byte-array-patterns.rs +++ b/src/test/ui/binding/match-byte-array-patterns.rs @@ -1,5 +1,4 @@ // run-pass -#![feature(slice_patterns)] fn main() { let buf = &[0u8; 4]; diff --git a/src/test/ui/binding/match-vec-alternatives.rs b/src/test/ui/binding/match-vec-alternatives.rs index 9b06a86a7b91e..af95eb95df04c 100644 --- a/src/test/ui/binding/match-vec-alternatives.rs +++ b/src/test/ui/binding/match-vec-alternatives.rs @@ -1,5 +1,4 @@ // run-pass -#![feature(slice_patterns)] fn match_vecs<'a, T>(l1: &'a [T], l2: &'a [T]) -> &'static str { match (l1, l2) { diff --git a/src/test/ui/binding/zero_sized_subslice_match.rs b/src/test/ui/binding/zero_sized_subslice_match.rs index 5326fa612a87b..187c2983633e7 100644 --- a/src/test/ui/binding/zero_sized_subslice_match.rs +++ b/src/test/ui/binding/zero_sized_subslice_match.rs @@ -1,5 +1,4 @@ // run-pass -#![feature(slice_patterns)] fn main() { let x = [(), ()]; diff --git a/src/test/ui/borrowck/borrowck-closures-slice-patterns-ok.rs b/src/test/ui/borrowck/borrowck-closures-slice-patterns-ok.rs index a70ccb7aa4b73..0229ca37a692a 100644 --- a/src/test/ui/borrowck/borrowck-closures-slice-patterns-ok.rs +++ b/src/test/ui/borrowck/borrowck-closures-slice-patterns-ok.rs @@ -1,6 +1,5 @@ // Check that closure captures for slice patterns are inferred correctly -#![feature(slice_patterns)] #![allow(unused_variables)] // run-pass diff --git a/src/test/ui/borrowck/borrowck-closures-slice-patterns.rs b/src/test/ui/borrowck/borrowck-closures-slice-patterns.rs index 984eb8804b7a2..32057d5c126ed 100644 --- a/src/test/ui/borrowck/borrowck-closures-slice-patterns.rs +++ b/src/test/ui/borrowck/borrowck-closures-slice-patterns.rs @@ -1,7 +1,5 @@ // Check that closure captures for slice patterns are inferred correctly -#![feature(slice_patterns)] - fn arr_by_ref(mut x: [String; 3]) { let f = || { let [ref y, ref z @ ..] = x; diff --git a/src/test/ui/borrowck/borrowck-closures-slice-patterns.stderr b/src/test/ui/borrowck/borrowck-closures-slice-patterns.stderr index c5b27f5f8b403..483975e5778a8 100644 --- a/src/test/ui/borrowck/borrowck-closures-slice-patterns.stderr +++ b/src/test/ui/borrowck/borrowck-closures-slice-patterns.stderr @@ -1,5 +1,5 @@ error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-closures-slice-patterns.rs:9:13 + --> $DIR/borrowck-closures-slice-patterns.rs:7:13 | LL | let f = || { | -- immutable borrow occurs here @@ -13,7 +13,7 @@ LL | f(); | - immutable borrow later used here error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-closures-slice-patterns.rs:18:13 + --> $DIR/borrowck-closures-slice-patterns.rs:16:13 | LL | let mut f = || { | -- mutable borrow occurs here @@ -27,7 +27,7 @@ LL | f(); | - mutable borrow later used here error[E0382]: borrow of moved value: `x` - --> $DIR/borrowck-closures-slice-patterns.rs:27:5 + --> $DIR/borrowck-closures-slice-patterns.rs:25:5 | LL | fn arr_by_move(x: [String; 3]) { | - move occurs because `x` has type `[std::string::String; 3]`, which does not implement the `Copy` trait @@ -40,7 +40,7 @@ LL | &x; | ^^ value borrowed here after move error[E0502]: cannot borrow `*x` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-closures-slice-patterns.rs:35:13 + --> $DIR/borrowck-closures-slice-patterns.rs:33:13 | LL | let f = || { | -- immutable borrow occurs here @@ -54,7 +54,7 @@ LL | f(); | - immutable borrow later used here error[E0501]: cannot borrow `x` as immutable because previous closure requires unique access - --> $DIR/borrowck-closures-slice-patterns.rs:44:13 + --> $DIR/borrowck-closures-slice-patterns.rs:42:13 | LL | let mut f = || { | -- closure construction occurs here @@ -68,7 +68,7 @@ LL | f(); | - first borrow later used here error[E0382]: borrow of moved value: `x` - --> $DIR/borrowck-closures-slice-patterns.rs:53:5 + --> $DIR/borrowck-closures-slice-patterns.rs:51:5 | LL | fn arr_box_by_move(x: Box<[String; 3]>) { | - move occurs because `x` has type `std::boxed::Box<[std::string::String; 3]>`, which does not implement the `Copy` trait @@ -81,7 +81,7 @@ LL | &x; | ^^ value borrowed here after move error[E0502]: cannot borrow `*x` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-closures-slice-patterns.rs:61:13 + --> $DIR/borrowck-closures-slice-patterns.rs:59:13 | LL | let f = || { | -- immutable borrow occurs here @@ -95,7 +95,7 @@ LL | f(); | - immutable borrow later used here error[E0501]: cannot borrow `x` as immutable because previous closure requires unique access - --> $DIR/borrowck-closures-slice-patterns.rs:70:13 + --> $DIR/borrowck-closures-slice-patterns.rs:68:13 | LL | let mut f = || { | -- closure construction occurs here diff --git a/src/test/ui/borrowck/borrowck-describe-lvalue.rs b/src/test/ui/borrowck/borrowck-describe-lvalue.rs index 8425960aa8600..c8bfbe0729c59 100644 --- a/src/test/ui/borrowck/borrowck-describe-lvalue.rs +++ b/src/test/ui/borrowck/borrowck-describe-lvalue.rs @@ -1,7 +1,5 @@ // ignore-tidy-linelength -#![feature(slice_patterns)] - pub struct Foo { x: u32 } diff --git a/src/test/ui/borrowck/borrowck-describe-lvalue.stderr b/src/test/ui/borrowck/borrowck-describe-lvalue.stderr index 4213523d2fa4b..075e0e2e4515e 100644 --- a/src/test/ui/borrowck/borrowck-describe-lvalue.stderr +++ b/src/test/ui/borrowck/borrowck-describe-lvalue.stderr @@ -1,5 +1,5 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time - --> $DIR/borrowck-describe-lvalue.rs:258:13 + --> $DIR/borrowck-describe-lvalue.rs:256:13 | LL | let y = &mut x; | ------ first mutable borrow occurs here @@ -9,7 +9,7 @@ LL | *y = 1; | ------ first borrow later used here error[E0499]: cannot borrow `x` as mutable more than once at a time - --> $DIR/borrowck-describe-lvalue.rs:268:20 + --> $DIR/borrowck-describe-lvalue.rs:266:20 | LL | let y = &mut x; | ------ first mutable borrow occurs here @@ -19,7 +19,7 @@ LL | *y = 1; | ------ first borrow later used here error: captured variable cannot escape `FnMut` closure body - --> $DIR/borrowck-describe-lvalue.rs:266:16 + --> $DIR/borrowck-describe-lvalue.rs:264:16 | LL | || { | - inferred to be a `FnMut` closure @@ -35,7 +35,7 @@ LL | | } = note: ...therefore, they cannot allow references to captured variables to escape error[E0503]: cannot use `f.x` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:41:9 + --> $DIR/borrowck-describe-lvalue.rs:39:9 | LL | let x = f.x(); | - borrow of `f` occurs here @@ -45,7 +45,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `g.0` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:48:9 + --> $DIR/borrowck-describe-lvalue.rs:46:9 | LL | let x = g.x(); | - borrow of `g` occurs here @@ -55,7 +55,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `h.0` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:55:9 + --> $DIR/borrowck-describe-lvalue.rs:53:9 | LL | let x = &mut h.0; | -------- borrow of `h.0` occurs here @@ -65,7 +65,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `e.0` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:63:20 + --> $DIR/borrowck-describe-lvalue.rs:61:20 | LL | let x = e.x(); | - borrow of `e` occurs here @@ -77,7 +77,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `u.a` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:71:9 + --> $DIR/borrowck-describe-lvalue.rs:69:9 | LL | let x = &mut u.a; | -------- borrow of `u.a` occurs here @@ -87,7 +87,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `f.x` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:78:9 + --> $DIR/borrowck-describe-lvalue.rs:76:9 | LL | let x = f.x(); | - borrow of `*f` occurs here @@ -97,7 +97,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `g.0` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:85:9 + --> $DIR/borrowck-describe-lvalue.rs:83:9 | LL | let x = g.x(); | - borrow of `*g` occurs here @@ -107,7 +107,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `h.0` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:92:9 + --> $DIR/borrowck-describe-lvalue.rs:90:9 | LL | let x = &mut h.0; | -------- borrow of `h.0` occurs here @@ -117,7 +117,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `e.0` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:100:20 + --> $DIR/borrowck-describe-lvalue.rs:98:20 | LL | let x = e.x(); | - borrow of `*e` occurs here @@ -129,7 +129,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `u.a` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:109:9 + --> $DIR/borrowck-describe-lvalue.rs:107:9 | LL | let x = &mut u.a; | -------- borrow of `u.a` occurs here @@ -139,7 +139,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `v[..]` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:117:15 + --> $DIR/borrowck-describe-lvalue.rs:115:15 | LL | let x = &mut v; | ------ borrow of `v` occurs here @@ -151,7 +151,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `v[..]` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:122:18 + --> $DIR/borrowck-describe-lvalue.rs:120:18 | LL | let x = &mut v; | ------ borrow of `v` occurs here @@ -163,7 +163,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `v[..]` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:127:25 + --> $DIR/borrowck-describe-lvalue.rs:125:25 | LL | let x = &mut v; | ------ borrow of `v` occurs here @@ -175,7 +175,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `v[..]` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:132:28 + --> $DIR/borrowck-describe-lvalue.rs:130:28 | LL | let x = &mut v; | ------ borrow of `v` occurs here @@ -187,7 +187,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `v[..]` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:143:15 + --> $DIR/borrowck-describe-lvalue.rs:141:15 | LL | let x = &mut v; | ------ borrow of `v` occurs here @@ -199,7 +199,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `v[..]` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:148:18 + --> $DIR/borrowck-describe-lvalue.rs:146:18 | LL | let x = &mut v; | ------ borrow of `v` occurs here @@ -211,7 +211,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `v[..]` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:153:15 + --> $DIR/borrowck-describe-lvalue.rs:151:15 | LL | let x = &mut v; | ------ borrow of `v` occurs here @@ -223,7 +223,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `v[..]` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:158:18 + --> $DIR/borrowck-describe-lvalue.rs:156:18 | LL | let x = &mut v; | ------ borrow of `v` occurs here @@ -235,7 +235,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `e` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:171:13 + --> $DIR/borrowck-describe-lvalue.rs:169:13 | LL | let x = &mut e; | ------ borrow of `e` occurs here @@ -247,7 +247,7 @@ LL | drop(x); | - borrow later used here error[E0502]: cannot borrow `e.0` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-describe-lvalue.rs:171:18 + --> $DIR/borrowck-describe-lvalue.rs:169:18 | LL | let x = &mut e; | ------ mutable borrow occurs here @@ -259,7 +259,7 @@ LL | drop(x); | - mutable borrow later used here error[E0502]: cannot borrow `e.x` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-describe-lvalue.rs:175:23 + --> $DIR/borrowck-describe-lvalue.rs:173:23 | LL | let x = &mut e; | ------ mutable borrow occurs here @@ -271,7 +271,7 @@ LL | drop(x); | - mutable borrow later used here error[E0502]: cannot borrow `s.y.0` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-describe-lvalue.rs:188:22 + --> $DIR/borrowck-describe-lvalue.rs:186:22 | LL | let x = &mut s; | ------ mutable borrow occurs here @@ -283,7 +283,7 @@ LL | drop(x); | - mutable borrow later used here error[E0502]: cannot borrow `s.x.y` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-describe-lvalue.rs:194:28 + --> $DIR/borrowck-describe-lvalue.rs:192:28 | LL | let x = &mut s; | ------ mutable borrow occurs here @@ -295,7 +295,7 @@ LL | drop(x); | - mutable borrow later used here error[E0503]: cannot use `*v` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:236:9 + --> $DIR/borrowck-describe-lvalue.rs:234:9 | LL | let x = &mut v; | ------ borrow of `v` occurs here @@ -306,7 +306,7 @@ LL | drop(x); | - borrow later used here error[E0503]: cannot use `v[_].y` because it was mutably borrowed - --> $DIR/borrowck-describe-lvalue.rs:236:9 + --> $DIR/borrowck-describe-lvalue.rs:234:9 | LL | let x = &mut v; | ------ borrow of `v` occurs here @@ -317,7 +317,7 @@ LL | drop(x); | - borrow later used here error[E0502]: cannot borrow `v[..].x` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-describe-lvalue.rs:247:24 + --> $DIR/borrowck-describe-lvalue.rs:245:24 | LL | let x = &mut v; | ------ mutable borrow occurs here @@ -329,7 +329,7 @@ LL | drop(x); | - mutable borrow later used here error[E0502]: cannot borrow `*block.current` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-describe-lvalue.rs:210:29 + --> $DIR/borrowck-describe-lvalue.rs:208:29 | LL | let x = &mut block; | ---------- mutable borrow occurs here @@ -340,7 +340,7 @@ LL | drop(x); | - mutable borrow later used here error[E0502]: cannot borrow `*block.current` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-describe-lvalue.rs:225:33 + --> $DIR/borrowck-describe-lvalue.rs:223:33 | LL | let x = &mut block; | ---------- mutable borrow occurs here @@ -351,7 +351,7 @@ LL | drop(x); | - mutable borrow later used here error[E0382]: use of moved value: `x` - --> $DIR/borrowck-describe-lvalue.rs:278:22 + --> $DIR/borrowck-describe-lvalue.rs:276:22 | LL | drop(x); | - value moved here diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-match.rs b/src/test/ui/borrowck/borrowck-move-out-from-array-match.rs index 232d43679b484..c1513fcba8a66 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array-match.rs +++ b/src/test/ui/borrowck/borrowck-move-out-from-array-match.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - fn array() -> [(String, String); 3] { Default::default() } diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-match.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array-match.stderr index e46a58a8a3500..84930b000ccb3 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array-match.stderr +++ b/src/test/ui/borrowck/borrowck-move-out-from-array-match.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `a[..]` - --> $DIR/borrowck-move-out-from-array-match.rs:15:14 + --> $DIR/borrowck-move-out-from-array-match.rs:13:14 | LL | [_, _, _x] => {} | -- value moved here @@ -10,7 +10,7 @@ LL | [.., _y] => {} = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a[..]` - --> $DIR/borrowck-move-out-from-array-match.rs:25:14 + --> $DIR/borrowck-move-out-from-array-match.rs:23:14 | LL | [_, _, (_x, _)] => {} | -- value moved here @@ -21,7 +21,7 @@ LL | [.., _y] => {} = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a[..].0` - --> $DIR/borrowck-move-out-from-array-match.rs:35:15 + --> $DIR/borrowck-move-out-from-array-match.rs:33:15 | LL | [_, _, (_x, _)] => {} | -- value moved here @@ -32,7 +32,7 @@ LL | [.., (_y, _)] => {} = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-match.rs:46:11 + --> $DIR/borrowck-move-out-from-array-match.rs:44:11 | LL | [_x, _, _] => {} | -- value moved here @@ -43,7 +43,7 @@ LL | match a { = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-match.rs:57:11 + --> $DIR/borrowck-move-out-from-array-match.rs:55:11 | LL | [.., _x] => {} | -- value moved here @@ -54,7 +54,7 @@ LL | match a { = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-match.rs:68:11 + --> $DIR/borrowck-move-out-from-array-match.rs:66:11 | LL | [(_x, _), _, _] => {} | -- value moved here @@ -65,7 +65,7 @@ LL | match a { = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-match.rs:79:11 + --> $DIR/borrowck-move-out-from-array-match.rs:77:11 | LL | [.., (_x, _)] => {} | -- value moved here @@ -76,7 +76,7 @@ LL | match a { = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a[..].0` - --> $DIR/borrowck-move-out-from-array-match.rs:91:11 + --> $DIR/borrowck-move-out-from-array-match.rs:89:11 | LL | [_y @ .., _, _] => {} | ------- value moved here @@ -87,7 +87,7 @@ LL | [(_x, _), _, _] => {} = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a[..].0` - --> $DIR/borrowck-move-out-from-array-match.rs:101:15 + --> $DIR/borrowck-move-out-from-array-match.rs:99:15 | LL | [_, _, _y @ ..] => {} | ------- value moved here @@ -98,7 +98,7 @@ LL | [.., (_x, _)] => {} = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-match.rs:112:11 + --> $DIR/borrowck-move-out-from-array-match.rs:110:11 | LL | [x @ .., _] => {} | ------ value moved here diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.rs b/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.rs index e5e61697c68c6..056b8e672bd93 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.rs +++ b/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.rs @@ -3,8 +3,6 @@ // Once the bug is fixed, the test, which is derived from a // passing test for `let` statements, should become check-pass. -#![feature(slice_patterns)] - fn array() -> [(String, String); 3] { Default::default() } diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.stderr index 72cd4207cce65..ff5eab2442c83 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.stderr +++ b/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:19:11 + --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:17:11 | LL | [_, _, _x] => {} | -- value moved here @@ -10,7 +10,7 @@ LL | match a { = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:30:11 + --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:28:11 | LL | [_, _, (_x, _)] => {} | -- value moved here @@ -21,7 +21,7 @@ LL | match a { = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:43:11 + --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:41:11 | LL | [_x, _, _] => {} | -- value moved here @@ -32,7 +32,7 @@ LL | match a { = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:54:11 + --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:52:11 | LL | [.., _x] => {} | -- value moved here @@ -43,7 +43,7 @@ LL | match a { = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:65:11 + --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:63:11 | LL | [(_x, _), _, _] => {} | -- value moved here @@ -54,7 +54,7 @@ LL | match a { = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:76:11 + --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:74:11 | LL | [.., (_x, _)] => {} | -- value moved here @@ -65,7 +65,7 @@ LL | match a { = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:87:11 + --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:85:11 | LL | [_, _y @ ..] => {} | ------- value moved here @@ -76,7 +76,7 @@ LL | match a { = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:98:11 + --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:96:11 | LL | [_y @ .., _] => {} | ------- value moved here @@ -87,7 +87,7 @@ LL | match a { = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:111:11 + --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:109:11 | LL | [x @ .., _, _] => {} | ------ value moved here diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap.rs b/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap.rs index 8f274cf73cb0e..c91b4286b6478 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap.rs +++ b/src/test/ui/borrowck/borrowck-move-out-from-array-no-overlap.rs @@ -1,7 +1,5 @@ // check-pass -#![feature(slice_patterns)] - fn array() -> [(String, String); 3] { Default::default() } diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.rs b/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.rs index 1ca3df52ada91..604a25cdcc1d6 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.rs +++ b/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - fn array() -> [(String, String); 3] { Default::default() } diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.stderr index 028442a4c07ea..0ef63105cfbd3 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.stderr +++ b/src/test/ui/borrowck/borrowck-move-out-from-array-use-match.stderr @@ -1,5 +1,5 @@ error[E0382]: borrow of moved value: `a[..]` - --> $DIR/borrowck-move-out-from-array-use-match.rs:15:14 + --> $DIR/borrowck-move-out-from-array-use-match.rs:13:14 | LL | [_, _, _x] => {} | -- value moved here @@ -10,7 +10,7 @@ LL | [.., ref _y] => {} = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `a[..]` - --> $DIR/borrowck-move-out-from-array-use-match.rs:25:14 + --> $DIR/borrowck-move-out-from-array-use-match.rs:23:14 | LL | [_, _, (_x, _)] => {} | -- value moved here @@ -21,7 +21,7 @@ LL | [.., ref _y] => {} = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `a[..].0` - --> $DIR/borrowck-move-out-from-array-use-match.rs:35:15 + --> $DIR/borrowck-move-out-from-array-use-match.rs:33:15 | LL | [_, _, (_x, _)] => {} | -- value moved here @@ -32,7 +32,7 @@ LL | [.., (ref _y, _)] => {} = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-match.rs:46:11 + --> $DIR/borrowck-move-out-from-array-use-match.rs:44:11 | LL | [_x, _, _] => {} | -- value moved here @@ -43,7 +43,7 @@ LL | match a { = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-match.rs:57:11 + --> $DIR/borrowck-move-out-from-array-use-match.rs:55:11 | LL | [.., _x] => {} | -- value moved here @@ -54,7 +54,7 @@ LL | match a { = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-match.rs:68:11 + --> $DIR/borrowck-move-out-from-array-use-match.rs:66:11 | LL | [(_x, _), _, _] => {} | -- value moved here @@ -65,7 +65,7 @@ LL | match a { = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-match.rs:79:11 + --> $DIR/borrowck-move-out-from-array-use-match.rs:77:11 | LL | [.., (_x, _)] => {} | -- value moved here @@ -76,7 +76,7 @@ LL | match a { = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `a[..]` - --> $DIR/borrowck-move-out-from-array-use-match.rs:91:11 + --> $DIR/borrowck-move-out-from-array-use-match.rs:89:11 | LL | [_y @ .., _, _] => {} | ------- value moved here @@ -87,7 +87,7 @@ LL | [(ref _x, _), _, _] => {} = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `a[..]` - --> $DIR/borrowck-move-out-from-array-use-match.rs:101:15 + --> $DIR/borrowck-move-out-from-array-use-match.rs:99:15 | LL | [_, _, _y @ ..] => {} | ------- value moved here @@ -98,7 +98,7 @@ LL | [.., (ref _x, _)] => {} = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-match.rs:112:11 + --> $DIR/borrowck-move-out-from-array-use-match.rs:110:11 | LL | [x @ .., _] => {} | ------ value moved here @@ -109,7 +109,7 @@ LL | match a { = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-match.rs:125:5 + --> $DIR/borrowck-move-out-from-array-use-match.rs:123:5 | LL | [_, _, _x] => {} | -- value moved here @@ -120,7 +120,7 @@ LL | a[2] = Default::default(); = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-match.rs:133:5 + --> $DIR/borrowck-move-out-from-array-use-match.rs:131:5 | LL | [_, _, (_x, _)] => {} | -- value moved here @@ -131,7 +131,7 @@ LL | a[2].1 = Default::default(); = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-match.rs:141:5 + --> $DIR/borrowck-move-out-from-array-use-match.rs:139:5 | LL | [_, _, _x @ ..] => {} | ------- value moved here @@ -142,7 +142,7 @@ LL | a[0] = Default::default(); = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-match.rs:149:5 + --> $DIR/borrowck-move-out-from-array-use-match.rs:147:5 | LL | [_, _, _x @ ..] => {} | ------- value moved here diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.rs b/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.rs index 79fe593009652..5afd6835dcfb6 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.rs +++ b/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.rs @@ -3,8 +3,6 @@ // Once the bug is fixed, the test, which is derived from a // passing test for `let` statements, should become check-pass. -#![feature(slice_patterns)] - fn array() -> [(String, String); 3] { Default::default() } diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.stderr index 43ba2b664a1e1..a4042ce7db336 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.stderr +++ b/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:19:11 + --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:17:11 | LL | [_, _, _x] => {} | -- value moved here @@ -10,7 +10,7 @@ LL | match a { = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:30:11 + --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:28:11 | LL | [_, _, (_x, _)] => {} | -- value moved here @@ -21,7 +21,7 @@ LL | match a { = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:43:11 + --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:41:11 | LL | [_x, _, _] => {} | -- value moved here @@ -32,7 +32,7 @@ LL | match a { = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:54:11 + --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:52:11 | LL | [.., _x] => {} | -- value moved here @@ -43,7 +43,7 @@ LL | match a { = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:65:11 + --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:63:11 | LL | [(_x, _), _, _] => {} | -- value moved here @@ -54,7 +54,7 @@ LL | match a { = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:76:11 + --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:74:11 | LL | [.., (_x, _)] => {} | -- value moved here @@ -65,7 +65,7 @@ LL | match a { = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:87:11 + --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:85:11 | LL | [_, _y @ ..] => {} | ------- value moved here @@ -76,7 +76,7 @@ LL | match a { = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:98:11 + --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:96:11 | LL | [_y @ .., _] => {} | ------- value moved here @@ -87,7 +87,7 @@ LL | match a { = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:111:11 + --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:109:11 | LL | [x @ .., _, _] => {} | ------ value moved here diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap.rs b/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap.rs index 57ce2417570b0..e3498cef37719 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap.rs +++ b/src/test/ui/borrowck/borrowck-move-out-from-array-use-no-overlap.rs @@ -1,7 +1,5 @@ // check-pass -#![feature(slice_patterns)] - fn array() -> [(String, String); 3] { Default::default() } diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-use.rs b/src/test/ui/borrowck/borrowck-move-out-from-array-use.rs index 778beefbf2c85..ad08367a3b5b3 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array-use.rs +++ b/src/test/ui/borrowck/borrowck-move-out-from-array-use.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - fn array() -> [(String, String); 3] { Default::default() } diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array-use.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array-use.stderr index 2a7b89132c1b7..7ad4116645e93 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array-use.stderr +++ b/src/test/ui/borrowck/borrowck-move-out-from-array-use.stderr @@ -1,5 +1,5 @@ error[E0382]: borrow of moved value: `a[..]` - --> $DIR/borrowck-move-out-from-array-use.rs:12:14 + --> $DIR/borrowck-move-out-from-array-use.rs:10:14 | LL | let [_, _, _x] = a; | -- value moved here @@ -9,7 +9,7 @@ LL | let [.., ref _y] = a; = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `a[..]` - --> $DIR/borrowck-move-out-from-array-use.rs:18:14 + --> $DIR/borrowck-move-out-from-array-use.rs:16:14 | LL | let [_, _, (_x, _)] = a; | -- value moved here @@ -19,7 +19,7 @@ LL | let [.., ref _y] = a; = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `a[..].0` - --> $DIR/borrowck-move-out-from-array-use.rs:24:15 + --> $DIR/borrowck-move-out-from-array-use.rs:22:15 | LL | let [_, _, (_x, _)] = a; | -- value moved here @@ -29,7 +29,7 @@ LL | let [.., (ref _y, _)] = a; = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use.rs:32:10 + --> $DIR/borrowck-move-out-from-array-use.rs:30:10 | LL | let [_x, _, _] = a; | -- value moved here @@ -39,7 +39,7 @@ LL | let [ref _y @ .., _, _] = a; = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use.rs:38:16 + --> $DIR/borrowck-move-out-from-array-use.rs:36:16 | LL | let [.., _x] = a; | -- value moved here @@ -49,7 +49,7 @@ LL | let [_, _, ref _y @ ..] = a; = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use.rs:44:10 + --> $DIR/borrowck-move-out-from-array-use.rs:42:10 | LL | let [(_x, _), _, _] = a; | -- value moved here @@ -59,7 +59,7 @@ LL | let [ref _y @ .., _, _] = a; = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use.rs:50:16 + --> $DIR/borrowck-move-out-from-array-use.rs:48:16 | LL | let [.., (_x, _)] = a; | -- value moved here @@ -69,7 +69,7 @@ LL | let [_, _, ref _y @ ..] = a; = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `a[..]` - --> $DIR/borrowck-move-out-from-array-use.rs:56:11 + --> $DIR/borrowck-move-out-from-array-use.rs:54:11 | LL | let [_y @ .., _, _] = a; | ------- value moved here @@ -79,7 +79,7 @@ LL | let [(ref _x, _), _, _] = a; = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `a[..]` - --> $DIR/borrowck-move-out-from-array-use.rs:62:15 + --> $DIR/borrowck-move-out-from-array-use.rs:60:15 | LL | let [_, _, _y @ ..] = a; | ------- value moved here @@ -89,7 +89,7 @@ LL | let [.., (ref _x, _)] = a; = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: borrow of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use.rs:70:13 + --> $DIR/borrowck-move-out-from-array-use.rs:68:13 | LL | let [x @ .., _] = a; | ------ value moved here @@ -99,7 +99,7 @@ LL | let [_, ref _y @ ..] = a; = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use.rs:78:5 + --> $DIR/borrowck-move-out-from-array-use.rs:76:5 | LL | let [_, _, _x] = a; | -- value moved here @@ -109,7 +109,7 @@ LL | a[2] = Default::default(); = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use.rs:84:5 + --> $DIR/borrowck-move-out-from-array-use.rs:82:5 | LL | let [_, _, (_x, _)] = a; | -- value moved here @@ -119,7 +119,7 @@ LL | a[2].1 = Default::default(); = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use.rs:90:5 + --> $DIR/borrowck-move-out-from-array-use.rs:88:5 | LL | let [_, _, _x @ ..] = a; | ------- value moved here @@ -129,7 +129,7 @@ LL | a[0] = Default::default(); = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array-use.rs:96:5 + --> $DIR/borrowck-move-out-from-array-use.rs:94:5 | LL | let [_, _, _x @ ..] = a; | ------- value moved here diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array.rs b/src/test/ui/borrowck/borrowck-move-out-from-array.rs index f9d3f6f2c0724..83755812f4b32 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array.rs +++ b/src/test/ui/borrowck/borrowck-move-out-from-array.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - fn array() -> [(String, String); 3] { Default::default() } diff --git a/src/test/ui/borrowck/borrowck-move-out-from-array.stderr b/src/test/ui/borrowck/borrowck-move-out-from-array.stderr index 08134a2a323e7..b7babd93ed7a6 100644 --- a/src/test/ui/borrowck/borrowck-move-out-from-array.stderr +++ b/src/test/ui/borrowck/borrowck-move-out-from-array.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `a[..]` - --> $DIR/borrowck-move-out-from-array.rs:12:14 + --> $DIR/borrowck-move-out-from-array.rs:10:14 | LL | let [_, _, _x] = a; | -- value moved here @@ -9,7 +9,7 @@ LL | let [.., _y] = a; = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a[..]` - --> $DIR/borrowck-move-out-from-array.rs:18:14 + --> $DIR/borrowck-move-out-from-array.rs:16:14 | LL | let [_, _, (_x, _)] = a; | -- value moved here @@ -19,7 +19,7 @@ LL | let [.., _y] = a; = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a[..].0` - --> $DIR/borrowck-move-out-from-array.rs:24:15 + --> $DIR/borrowck-move-out-from-array.rs:22:15 | LL | let [_, _, (_x, _)] = a; | -- value moved here @@ -29,7 +29,7 @@ LL | let [.., (_y, _)] = a; = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array.rs:32:10 + --> $DIR/borrowck-move-out-from-array.rs:30:10 | LL | let [_x, _, _] = a; | -- value moved here @@ -39,7 +39,7 @@ LL | let [_y @ .., _, _] = a; = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array.rs:38:16 + --> $DIR/borrowck-move-out-from-array.rs:36:16 | LL | let [.., _x] = a; | -- value moved here @@ -49,7 +49,7 @@ LL | let [_, _, _y @ ..] = a; = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array.rs:44:10 + --> $DIR/borrowck-move-out-from-array.rs:42:10 | LL | let [(_x, _), _, _] = a; | -- value moved here @@ -59,7 +59,7 @@ LL | let [_y @ .., _, _] = a; = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array.rs:50:16 + --> $DIR/borrowck-move-out-from-array.rs:48:16 | LL | let [.., (_x, _)] = a; | -- value moved here @@ -69,7 +69,7 @@ LL | let [_, _, _y @ ..] = a; = note: move occurs because `a[..].0` has type `std::string::String`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a[..].0` - --> $DIR/borrowck-move-out-from-array.rs:56:11 + --> $DIR/borrowck-move-out-from-array.rs:54:11 | LL | let [_y @ .., _, _] = a; | ------- value moved here @@ -79,7 +79,7 @@ LL | let [(_x, _), _, _] = a; = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a[..].0` - --> $DIR/borrowck-move-out-from-array.rs:62:15 + --> $DIR/borrowck-move-out-from-array.rs:60:15 | LL | let [_, _, _y @ ..] = a; | ------- value moved here @@ -89,7 +89,7 @@ LL | let [.., (_x, _)] = a; = note: move occurs because `a[..]` has type `(std::string::String, std::string::String)`, which does not implement the `Copy` trait error[E0382]: use of moved value: `a` - --> $DIR/borrowck-move-out-from-array.rs:70:13 + --> $DIR/borrowck-move-out-from-array.rs:68:13 | LL | let [x @ .., _] = a; | ------ value moved here diff --git a/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.rs b/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.rs index fa9a3c217db77..8ece81a3c845e 100644 --- a/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.rs +++ b/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.rs @@ -1,7 +1,5 @@ // Test that we do not permit moves from &[] matched by a vec pattern. -#![feature(slice_patterns)] - #[derive(Clone, Debug)] struct Foo { string: String diff --git a/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.stderr b/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.stderr index 8fb4c062c0363..a345c1238f02c 100644 --- a/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.stderr +++ b/src/test/ui/borrowck/borrowck-move-out-of-vec-tail.stderr @@ -1,5 +1,5 @@ error[E0508]: cannot move out of type `[Foo]`, a non-copy slice - --> $DIR/borrowck-move-out-of-vec-tail.rs:19:19 + --> $DIR/borrowck-move-out-of-vec-tail.rs:17:19 | LL | match tail { | ^^^^ cannot move out of here diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array-no-overlap.rs b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array-no-overlap.rs index 7d91a21264723..a8e56f648e2e5 100644 --- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array-no-overlap.rs +++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array-no-overlap.rs @@ -1,7 +1,5 @@ // check-pass -#![feature(slice_patterns)] - fn nop(_s: &[& i32]) {} fn nop_subslice(_s: &[i32]) {} diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.rs b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.rs index f03a2ab8fa8e4..6b210d73228f8 100644 --- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.rs +++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - fn nop(_s: &[& i32]) {} fn nop_subslice(_s: &[i32]) {} diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.stderr b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.stderr index e50e7eb3e2230..0432aaf51d29f 100644 --- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.stderr +++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-array.stderr @@ -1,5 +1,5 @@ error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-array.rs:8:13 + --> $DIR/borrowck-slice-pattern-element-loan-array.rs:6:13 | LL | let [ref first, ref second, ..] = *s; | ---------- immutable borrow occurs here @@ -9,7 +9,7 @@ LL | nop(&[first, second, second2, third]); | ------ immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-array.rs:14:14 + --> $DIR/borrowck-slice-pattern-element-loan-array.rs:12:14 | LL | let [.., ref fourth, ref third, _, ref first] = *s; | --------- immutable borrow occurs here @@ -19,7 +19,7 @@ LL | nop(&[first, third, third2, fourth]); | ----- immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-array.rs:21:16 + --> $DIR/borrowck-slice-pattern-element-loan-array.rs:19:16 | LL | let [.., _, ref from_end4, ref from_end3, _, ref from_end1] = *s; | ------------- immutable borrow occurs here @@ -30,7 +30,7 @@ LL | nop(&[from_begin2, from_end1, from_end3, from_end4]); | --------- immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-array.rs:23:19 + --> $DIR/borrowck-slice-pattern-element-loan-array.rs:21:19 | LL | let [.., _, ref from_end4, ref from_end3, _, ref from_end1] = *s; | ------------- immutable borrow occurs here @@ -41,7 +41,7 @@ LL | nop(&[from_begin3, from_end1, from_end3, from_end4]); | --------- immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-array.rs:28:14 + --> $DIR/borrowck-slice-pattern-element-loan-array.rs:26:14 | LL | let [ref from_begin0, ref from_begin1, _, ref from_begin3, _, ..] = *s; | --------------- immutable borrow occurs here @@ -52,7 +52,7 @@ LL | nop(&[from_begin0, from_begin1, from_begin3, from_end3]); | ----------- immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-array.rs:34:13 + --> $DIR/borrowck-slice-pattern-element-loan-array.rs:32:13 | LL | let [ref first, ref second, ..] = *s; | ---------- immutable borrow occurs here @@ -62,7 +62,7 @@ LL | nop(&[first, second]); | ------ immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-array.rs:41:10 + --> $DIR/borrowck-slice-pattern-element-loan-array.rs:39:10 | LL | let [.., ref second, ref first] = *s; | ---------- immutable borrow occurs here @@ -72,7 +72,7 @@ LL | nop(&[first, second]); | ------ immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-array.rs:48:10 + --> $DIR/borrowck-slice-pattern-element-loan-array.rs:46:10 | LL | let [_, ref s1 @ ..] = *s; | ----------- immutable borrow occurs here diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs index 048813b2b93e6..1c9c052970f9a 100644 --- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs +++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs @@ -1,7 +1,5 @@ // run-pass -//compile-flags: -Z borrowck=mir - -#![feature(slice_patterns)] +// compile-flags: -Z borrowck=mir fn mut_head_tail<'a, A>(v: &'a mut [A]) -> Option<(&'a mut A, &'a mut [A])> { match *v { diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice-no-overlap.rs b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice-no-overlap.rs index e69071f87720b..6390dc3a91a0d 100644 --- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice-no-overlap.rs +++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice-no-overlap.rs @@ -1,7 +1,5 @@ // check-pass -#![feature(slice_patterns)] - fn nop(_s: &[& i32]) {} fn nop_subslice(_s: &[i32]) {} diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.rs b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.rs index 2ef98741dc35a..0e1c90a1cd83d 100644 --- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.rs +++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - fn nop(_s: &[& i32]) {} fn nop_subslice(_s: &[i32]) {} diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.stderr b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.stderr index b6f5ac64b2061..d3388e071aa53 100644 --- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.stderr +++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-slice.stderr @@ -1,5 +1,5 @@ error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:8:20 + --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:6:20 | LL | if let [ref first, ref second, ..] = *s { | ---------- immutable borrow occurs here @@ -9,7 +9,7 @@ LL | nop(&[first, second, second2, third]); | ------ immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:16:21 + --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:14:21 | LL | if let [.., ref fourth, ref third, _, ref first] = *s { | --------- immutable borrow occurs here @@ -19,7 +19,7 @@ LL | nop(&[first, third, third2, fourth]); | ----- immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:24:20 + --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:22:20 | LL | if let [.., _, ref from_end4, ref from_end3, _, ref from_end1] = *s { | ------------- immutable borrow occurs here @@ -29,7 +29,7 @@ LL | nop(&[from_begin1, from_end1, from_end3, from_end4]); | --------- immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:27:23 + --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:25:23 | LL | if let [.., _, ref from_end4, ref from_end3, _, ref from_end1] = *s { | ------------- immutable borrow occurs here @@ -40,7 +40,7 @@ LL | nop(&[from_begin2, from_end1, from_end3, from_end4]); | --------- immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:30:26 + --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:28:26 | LL | if let [.., _, ref from_end4, ref from_end3, _, ref from_end1] = *s { | ------------- immutable borrow occurs here @@ -51,7 +51,7 @@ LL | nop(&[from_begin3, from_end1, from_end3, from_end4]); | --------- immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:35:21 + --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:33:21 | LL | if let [ref from_begin0, ref from_begin1, _, ref from_begin3, _, ..] = *s { | --------------- immutable borrow occurs here @@ -61,7 +61,7 @@ LL | nop(&[from_begin0, from_begin1, from_begin3, from_end2]); | ----------- immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:38:21 + --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:36:21 | LL | if let [ref from_begin0, ref from_begin1, _, ref from_begin3, _, ..] = *s { | --------------- immutable borrow occurs here @@ -72,7 +72,7 @@ LL | nop(&[from_begin0, from_begin1, from_begin3, from_end3]); | ----------- immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:41:21 + --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:39:21 | LL | if let [ref from_begin0, ref from_begin1, _, ref from_begin3, _, ..] = *s { | --------------- immutable borrow occurs here @@ -83,7 +83,7 @@ LL | nop(&[from_begin0, from_begin1, from_begin3, from_end4]); | ----------- immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:49:20 + --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:47:20 | LL | if let [ref first, ref second, ..] = *s { | ---------- immutable borrow occurs here @@ -93,7 +93,7 @@ LL | nop(&[first, second]); | ------ immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:58:17 + --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:56:17 | LL | if let [.., ref second, ref first] = *s { | ---------- immutable borrow occurs here @@ -103,7 +103,7 @@ LL | nop(&[first, second]); | ------ immutable borrow later used here error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:67:17 + --> $DIR/borrowck-slice-pattern-element-loan-slice.rs:65:17 | LL | if let [_, _, _, ref s1 @ ..] = *s { | ----------- immutable borrow occurs here diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.rs b/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.rs index 53a9bcef74a22..cd853b83363ab 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.rs +++ b/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - fn a<'a>() -> &'a [isize] { let vec = vec![1, 2, 3, 4]; let vec: &[isize] = &vec; diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.stderr index da6d9293b408a..170982b1693fb 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.stderr +++ b/src/test/ui/borrowck/borrowck-vec-pattern-element-loan.stderr @@ -1,5 +1,5 @@ error[E0515]: cannot return value referencing local variable `vec` - --> $DIR/borrowck-vec-pattern-element-loan.rs:10:5 + --> $DIR/borrowck-vec-pattern-element-loan.rs:8:5 | LL | let vec: &[isize] = &vec; | ---- `vec` is borrowed here @@ -8,7 +8,7 @@ LL | tail | ^^^^ returns a value referencing data owned by the current function error[E0515]: cannot return value referencing local variable `vec` - --> $DIR/borrowck-vec-pattern-element-loan.rs:20:5 + --> $DIR/borrowck-vec-pattern-element-loan.rs:18:5 | LL | let vec: &[isize] = &vec; | ---- `vec` is borrowed here @@ -17,7 +17,7 @@ LL | init | ^^^^ returns a value referencing data owned by the current function error[E0515]: cannot return value referencing local variable `vec` - --> $DIR/borrowck-vec-pattern-element-loan.rs:30:5 + --> $DIR/borrowck-vec-pattern-element-loan.rs:28:5 | LL | let vec: &[isize] = &vec; | ---- `vec` is borrowed here diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.rs b/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.rs index dd9023f6d9f79..05859c95d174d 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.rs +++ b/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - fn a() { let mut v = vec![1, 2, 3]; let vb: &mut [isize] = &mut v; diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.stderr index 251f44592905d..5141fcc1bb261 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.stderr +++ b/src/test/ui/borrowck/borrowck-vec-pattern-loan-from-mut.stderr @@ -1,5 +1,5 @@ error[E0499]: cannot borrow `v` as mutable more than once at a time - --> $DIR/borrowck-vec-pattern-loan-from-mut.rs:8:13 + --> $DIR/borrowck-vec-pattern-loan-from-mut.rs:6:13 | LL | let vb: &mut [isize] = &mut v; | ------ first mutable borrow occurs here diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.rs b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.rs index 420223009a45b..9b8ba2ea8adc5 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.rs +++ b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.rs @@ -1,7 +1,3 @@ -// http://rust-lang.org/COPYRIGHT. - -#![feature(slice_patterns)] - fn main() { let mut a = [1, 2, 3, 4]; let t = match a { diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr index 9f8e6fe3b6898..ff70ba9fcca8b 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr +++ b/src/test/ui/borrowck/borrowck-vec-pattern-move-tail.stderr @@ -1,5 +1,5 @@ error[E0506]: cannot assign to `a[_]` because it is borrowed - --> $DIR/borrowck-vec-pattern-move-tail.rs:12:5 + --> $DIR/borrowck-vec-pattern-move-tail.rs:8:5 | LL | [1, 2, ref tail @ ..] => tail, | ------------- borrow of `a[_]` occurs here diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs index e274d105e0503..67b6c12ba803a 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs +++ b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.rs @@ -1,6 +1,5 @@ #![feature(box_patterns)] #![feature(box_syntax)] -#![feature(slice_patterns)] fn a() { let mut vec = [box 1, box 2, box 3]; diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr index a3324f25d0bb5..e2c0852dd83c6 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr +++ b/src/test/ui/borrowck/borrowck-vec-pattern-nesting.stderr @@ -1,5 +1,5 @@ error[E0506]: cannot assign to `vec[_]` because it is borrowed - --> $DIR/borrowck-vec-pattern-nesting.rs:10:13 + --> $DIR/borrowck-vec-pattern-nesting.rs:9:13 | LL | [box ref _a, _, _] => { | ------ borrow of `vec[_]` occurs here @@ -11,7 +11,7 @@ LL | _a.use_ref(); | -- borrow later used here error[E0506]: cannot assign to `vec[_]` because it is borrowed - --> $DIR/borrowck-vec-pattern-nesting.rs:24:13 + --> $DIR/borrowck-vec-pattern-nesting.rs:23:13 | LL | &mut [ref _b @ ..] => { | ----------- borrow of `vec[_]` occurs here @@ -23,7 +23,7 @@ LL | _b.use_ref(); | -- borrow later used here error[E0508]: cannot move out of type `[std::boxed::Box]`, a non-copy slice - --> $DIR/borrowck-vec-pattern-nesting.rs:35:11 + --> $DIR/borrowck-vec-pattern-nesting.rs:34:11 | LL | match vec { | ^^^ cannot move out of here @@ -45,7 +45,7 @@ LL | ] => { | error[E0508]: cannot move out of type `[std::boxed::Box]`, a non-copy slice - --> $DIR/borrowck-vec-pattern-nesting.rs:47:13 + --> $DIR/borrowck-vec-pattern-nesting.rs:46:13 | LL | let a = vec[0]; | ^^^^^^ @@ -55,7 +55,7 @@ LL | let a = vec[0]; | help: consider borrowing here: `&vec[0]` error[E0508]: cannot move out of type `[std::boxed::Box]`, a non-copy slice - --> $DIR/borrowck-vec-pattern-nesting.rs:56:11 + --> $DIR/borrowck-vec-pattern-nesting.rs:55:11 | LL | match vec { | ^^^ cannot move out of here @@ -74,7 +74,7 @@ LL | _b] => {} | error[E0508]: cannot move out of type `[std::boxed::Box]`, a non-copy slice - --> $DIR/borrowck-vec-pattern-nesting.rs:66:13 + --> $DIR/borrowck-vec-pattern-nesting.rs:65:13 | LL | let a = vec[0]; | ^^^^^^ @@ -84,7 +84,7 @@ LL | let a = vec[0]; | help: consider borrowing here: `&vec[0]` error[E0508]: cannot move out of type `[std::boxed::Box]`, a non-copy slice - --> $DIR/borrowck-vec-pattern-nesting.rs:75:11 + --> $DIR/borrowck-vec-pattern-nesting.rs:74:11 | LL | match vec { | ^^^ cannot move out of here @@ -100,7 +100,7 @@ LL | &mut [_a, _b, _c] => {} = note: move occurs because these variables have types that don't implement the `Copy` trait error[E0508]: cannot move out of type `[std::boxed::Box]`, a non-copy slice - --> $DIR/borrowck-vec-pattern-nesting.rs:86:13 + --> $DIR/borrowck-vec-pattern-nesting.rs:85:13 | LL | let a = vec[0]; | ^^^^^^ diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.rs b/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.rs index c35be2f6be62c..39872825cd2a4 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.rs +++ b/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - fn a<'a>() -> &'a isize { let vec = vec![1, 2, 3, 4]; let vec: &[isize] = &vec; diff --git a/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.stderr b/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.stderr index c1290a6f63f33..7e21c55f21b5f 100644 --- a/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.stderr +++ b/src/test/ui/borrowck/borrowck-vec-pattern-tail-element-loan.stderr @@ -1,5 +1,5 @@ error[E0515]: cannot return value referencing local variable `vec` - --> $DIR/borrowck-vec-pattern-tail-element-loan.rs:10:5 + --> $DIR/borrowck-vec-pattern-tail-element-loan.rs:8:5 | LL | let vec: &[isize] = &vec; | ---- `vec` is borrowed here diff --git a/src/test/ui/consts/const_prop_slice_pat_ice.rs b/src/test/ui/consts/const_prop_slice_pat_ice.rs index 5fec36e44bd8c..60b06a497d6de 100644 --- a/src/test/ui/consts/const_prop_slice_pat_ice.rs +++ b/src/test/ui/consts/const_prop_slice_pat_ice.rs @@ -1,5 +1,4 @@ // check-pass -#![feature(slice_patterns)] fn main() { match &[0, 1] as &[i32] { diff --git a/src/test/ui/drop/dynamic-drop-async.rs b/src/test/ui/drop/dynamic-drop-async.rs index 91063edf0f6c4..30a8960594493 100644 --- a/src/test/ui/drop/dynamic-drop-async.rs +++ b/src/test/ui/drop/dynamic-drop-async.rs @@ -7,7 +7,6 @@ // edition:2018 // ignore-wasm32-bare compiled with panic=abort by default -#![feature(slice_patterns)] #![allow(unused)] use std::{ diff --git a/src/test/ui/drop/dynamic-drop.rs b/src/test/ui/drop/dynamic-drop.rs index 0f0ec0ba460c8..b4406204a5db9 100644 --- a/src/test/ui/drop/dynamic-drop.rs +++ b/src/test/ui/drop/dynamic-drop.rs @@ -1,11 +1,10 @@ // run-pass -#![allow(unused_assignments)] -#![allow(unused_variables)] - // ignore-wasm32-bare compiled with panic=abort by default #![feature(generators, generator_trait, untagged_unions)] -#![feature(slice_patterns)] + +#![allow(unused_assignments)] +#![allow(unused_variables)] use std::cell::{Cell, RefCell}; use std::mem::ManuallyDrop; diff --git a/src/test/ui/error-codes/E0528.rs b/src/test/ui/error-codes/E0528.rs index 17d03b14fc6e1..0a337c9611c8b 100644 --- a/src/test/ui/error-codes/E0528.rs +++ b/src/test/ui/error-codes/E0528.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - fn main() { let r = &[1, 2]; match r { diff --git a/src/test/ui/error-codes/E0528.stderr b/src/test/ui/error-codes/E0528.stderr index 0f566091145bf..21615f954c363 100644 --- a/src/test/ui/error-codes/E0528.stderr +++ b/src/test/ui/error-codes/E0528.stderr @@ -1,5 +1,5 @@ error[E0528]: pattern requires at least 3 elements but array has 2 - --> $DIR/E0528.rs:6:10 + --> $DIR/E0528.rs:4:10 | LL | &[a, b, c, rest @ ..] => { | ^^^^^^^^^^^^^^^^^^^^ pattern cannot match array of 2 elements diff --git a/src/test/ui/ignore-all-the-things.rs b/src/test/ui/ignore-all-the-things.rs index 8c046a289fad2..ab90a69ce6f06 100644 --- a/src/test/ui/ignore-all-the-things.rs +++ b/src/test/ui/ignore-all-the-things.rs @@ -1,11 +1,9 @@ // run-pass +// pretty-expanded FIXME #23616 #![allow(non_shorthand_field_patterns)] #![allow(dead_code)] #![allow(unused_variables)] -// pretty-expanded FIXME #23616 - -#![feature(slice_patterns)] struct Foo(isize, isize, isize, isize); struct Bar{a: isize, b: isize, c: isize, d: isize} diff --git a/src/test/ui/issues/issue-12369.rs b/src/test/ui/issues/issue-12369.rs index 0866131807463..0481c1fd9e1bb 100644 --- a/src/test/ui/issues/issue-12369.rs +++ b/src/test/ui/issues/issue-12369.rs @@ -1,4 +1,3 @@ -#![feature(slice_patterns)] #![deny(unreachable_patterns)] fn main() { diff --git a/src/test/ui/issues/issue-12369.stderr b/src/test/ui/issues/issue-12369.stderr index f27425e28c61d..754b94bab75eb 100644 --- a/src/test/ui/issues/issue-12369.stderr +++ b/src/test/ui/issues/issue-12369.stderr @@ -1,11 +1,11 @@ error: unreachable pattern - --> $DIR/issue-12369.rs:10:9 + --> $DIR/issue-12369.rs:9:9 | LL | &[10,a, ref rest @ ..] => 10 | ^^^^^^^^^^^^^^^^^^^^^^ | note: lint level defined here - --> $DIR/issue-12369.rs:2:9 + --> $DIR/issue-12369.rs:1:9 | LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/issues/issue-12567.rs b/src/test/ui/issues/issue-12567.rs index 643d9a2fc69e9..1b2a37de47539 100644 --- a/src/test/ui/issues/issue-12567.rs +++ b/src/test/ui/issues/issue-12567.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - fn match_vecs<'a, T>(l1: &'a [T], l2: &'a [T]) { match (l1, l2) { //~^ ERROR: cannot move out of type `[T]`, a non-copy slice diff --git a/src/test/ui/issues/issue-12567.stderr b/src/test/ui/issues/issue-12567.stderr index 9d9a88f4f9b06..2a88d8f0524ac 100644 --- a/src/test/ui/issues/issue-12567.stderr +++ b/src/test/ui/issues/issue-12567.stderr @@ -1,5 +1,5 @@ error[E0508]: cannot move out of type `[T]`, a non-copy slice - --> $DIR/issue-12567.rs:4:11 + --> $DIR/issue-12567.rs:2:11 | LL | match (l1, l2) { | ^^^^^^^^ cannot move out of here @@ -13,7 +13,7 @@ LL | (&[hd1, ..], &[hd2, ..]) = note: move occurs because these variables have types that don't implement the `Copy` trait error[E0508]: cannot move out of type `[T]`, a non-copy slice - --> $DIR/issue-12567.rs:4:11 + --> $DIR/issue-12567.rs:2:11 | LL | match (l1, l2) { | ^^^^^^^^ cannot move out of here diff --git a/src/test/ui/issues/issue-15080.rs b/src/test/ui/issues/issue-15080.rs index b11b1cda38ae1..4dd6981d448e5 100644 --- a/src/test/ui/issues/issue-15080.rs +++ b/src/test/ui/issues/issue-15080.rs @@ -1,5 +1,4 @@ // run-pass -#![feature(slice_patterns)] fn main() { let mut x: &[_] = &[1, 2, 3, 4]; diff --git a/src/test/ui/issues/issue-15104.rs b/src/test/ui/issues/issue-15104.rs index ee977541137db..47b207ea9cbf5 100644 --- a/src/test/ui/issues/issue-15104.rs +++ b/src/test/ui/issues/issue-15104.rs @@ -1,5 +1,4 @@ // run-pass -#![feature(slice_patterns)] fn main() { assert_eq!(count_members(&[1, 2, 3, 4]), 4); diff --git a/src/test/ui/issues/issue-17877.rs b/src/test/ui/issues/issue-17877.rs index fefa3f2f87304..126e01de5ee3f 100644 --- a/src/test/ui/issues/issue-17877.rs +++ b/src/test/ui/issues/issue-17877.rs @@ -1,5 +1,4 @@ // run-pass -#![feature(slice_patterns)] fn main() { assert_eq!(match [0u8; 1024] { diff --git a/src/test/ui/issues/issue-23311.rs b/src/test/ui/issues/issue-23311.rs index f275c6338b194..62c96840b3bc4 100644 --- a/src/test/ui/issues/issue-23311.rs +++ b/src/test/ui/issues/issue-23311.rs @@ -1,7 +1,6 @@ // run-pass -// Test that we do not ICE when pattern matching an array against a slice. -#![feature(slice_patterns)] +// Test that we do not ICE when pattern matching an array against a slice. fn main() { match "foo".as_bytes() { diff --git a/src/test/ui/issues/issue-26619.rs b/src/test/ui/issues/issue-26619.rs index 00e09f3f07764..b9d34b0555aee 100644 --- a/src/test/ui/issues/issue-26619.rs +++ b/src/test/ui/issues/issue-26619.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - pub struct History<'a> { pub _s: &'a str } impl<'a> History<'a> { diff --git a/src/test/ui/issues/issue-26619.stderr b/src/test/ui/issues/issue-26619.stderr index d1157cda92bf8..1282fd7d3c238 100644 --- a/src/test/ui/issues/issue-26619.stderr +++ b/src/test/ui/issues/issue-26619.stderr @@ -1,5 +1,5 @@ error[E0515]: cannot return value referencing function parameter - --> $DIR/issue-26619.rs:7:76 + --> $DIR/issue-26619.rs:5:76 | LL | for s in vec!["1|2".to_string()].into_iter().filter_map(|ref line| self.make_entry(line)) { | -------- ^^^^^^^^^^^^^^^^^^^^^ returns a value referencing data owned by the current function diff --git a/src/test/ui/issues/issue-37598.rs b/src/test/ui/issues/issue-37598.rs index 31b3aba6bc204..458e999c3faa2 100644 --- a/src/test/ui/issues/issue-37598.rs +++ b/src/test/ui/issues/issue-37598.rs @@ -1,5 +1,4 @@ // check-pass -#![feature(slice_patterns)] fn check(list: &[u8]) { match list { diff --git a/src/test/ui/issues/issue-7784.rs b/src/test/ui/issues/issue-7784.rs index 5b70bd6e5ff54..b7323f09daff2 100644 --- a/src/test/ui/issues/issue-7784.rs +++ b/src/test/ui/issues/issue-7784.rs @@ -1,5 +1,4 @@ // run-pass -#![feature(slice_patterns)] use std::ops::Add; diff --git a/src/test/ui/match/match-vec-mismatch.rs b/src/test/ui/match/match-vec-mismatch.rs index a0ef92743ac5a..34adb42a32f96 100644 --- a/src/test/ui/match/match-vec-mismatch.rs +++ b/src/test/ui/match/match-vec-mismatch.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - fn main() { match "foo".to_string() { ['f', 'o', ..] => {} diff --git a/src/test/ui/match/match-vec-mismatch.stderr b/src/test/ui/match/match-vec-mismatch.stderr index a3523bb689e6b..4b0e429e51ca5 100644 --- a/src/test/ui/match/match-vec-mismatch.stderr +++ b/src/test/ui/match/match-vec-mismatch.stderr @@ -1,29 +1,29 @@ error[E0425]: cannot find value `does_not_exist` in this scope - --> $DIR/match-vec-mismatch.rs:28:11 + --> $DIR/match-vec-mismatch.rs:26:11 | LL | match does_not_exist { | ^^^^^^^^^^^^^^ not found in this scope error[E0529]: expected an array or slice, found `std::string::String` - --> $DIR/match-vec-mismatch.rs:5:9 + --> $DIR/match-vec-mismatch.rs:3:9 | LL | ['f', 'o', ..] => {} | ^^^^^^^^^^^^^^ pattern cannot match with input type `std::string::String` error[E0527]: pattern requires 1 element but array has 3 - --> $DIR/match-vec-mismatch.rs:20:9 + --> $DIR/match-vec-mismatch.rs:18:9 | LL | [0] => {}, | ^^^ expected 3 elements error[E0528]: pattern requires at least 4 elements but array has 3 - --> $DIR/match-vec-mismatch.rs:25:9 + --> $DIR/match-vec-mismatch.rs:23:9 | LL | [0, 1, 2, 3, x @ ..] => {} | ^^^^^^^^^^^^^^^^^^^^ pattern cannot match array of 3 elements error[E0282]: type annotations needed - --> $DIR/match-vec-mismatch.rs:36:9 + --> $DIR/match-vec-mismatch.rs:34:9 | LL | [] => {} | ^^ cannot infer type diff --git a/src/test/ui/moves/move-out-of-array-ref.rs b/src/test/ui/moves/move-out-of-array-ref.rs index 4ca60ddfec27c..343f00ff29181 100644 --- a/src/test/ui/moves/move-out-of-array-ref.rs +++ b/src/test/ui/moves/move-out-of-array-ref.rs @@ -1,7 +1,5 @@ // Ensure that we cannot move out of a reference to a fixed-size array -#![feature(slice_patterns)] - struct D { _x: u8 } impl Drop for D { fn drop(&mut self) { } } diff --git a/src/test/ui/moves/move-out-of-array-ref.stderr b/src/test/ui/moves/move-out-of-array-ref.stderr index ae3d2f5f2826a..fd682e56ae1de 100644 --- a/src/test/ui/moves/move-out-of-array-ref.stderr +++ b/src/test/ui/moves/move-out-of-array-ref.stderr @@ -1,5 +1,5 @@ error[E0508]: cannot move out of type `[D; 4]`, a non-copy array - --> $DIR/move-out-of-array-ref.rs:10:24 + --> $DIR/move-out-of-array-ref.rs:8:24 | LL | let [_, e, _, _] = *a; | - ^^ @@ -10,7 +10,7 @@ LL | let [_, e, _, _] = *a; | move occurs because `e` has type `D`, which does not implement the `Copy` trait error[E0508]: cannot move out of type `[D; 4]`, a non-copy array - --> $DIR/move-out-of-array-ref.rs:15:27 + --> $DIR/move-out-of-array-ref.rs:13:27 | LL | let [_, s @ .. , _] = *a; | ------ ^^ @@ -21,7 +21,7 @@ LL | let [_, s @ .. , _] = *a; | move occurs because `s` has type `[D; 2]`, which does not implement the `Copy` trait error[E0508]: cannot move out of type `[D; 4]`, a non-copy array - --> $DIR/move-out-of-array-ref.rs:20:24 + --> $DIR/move-out-of-array-ref.rs:18:24 | LL | let [_, e, _, _] = *a; | - ^^ @@ -32,7 +32,7 @@ LL | let [_, e, _, _] = *a; | move occurs because `e` has type `D`, which does not implement the `Copy` trait error[E0508]: cannot move out of type `[D; 4]`, a non-copy array - --> $DIR/move-out-of-array-ref.rs:25:27 + --> $DIR/move-out-of-array-ref.rs:23:27 | LL | let [_, s @ .. , _] = *a; | ------ ^^ diff --git a/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.rs b/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.rs index d7c191bb5a28d..8b0be2e7a66b4 100644 --- a/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.rs +++ b/src/test/ui/or-patterns/exhaustiveness-non-exhaustive.rs @@ -1,5 +1,5 @@ #![feature(or_patterns)] -#![feature(slice_patterns)] + #![allow(incomplete_features)] #![deny(unreachable_patterns)] diff --git a/src/test/ui/or-patterns/exhaustiveness-pass.rs b/src/test/ui/or-patterns/exhaustiveness-pass.rs index ce0fe6fc2a375..f0dc3447f3154 100644 --- a/src/test/ui/or-patterns/exhaustiveness-pass.rs +++ b/src/test/ui/or-patterns/exhaustiveness-pass.rs @@ -1,5 +1,5 @@ #![feature(or_patterns)] -#![feature(slice_patterns)] + #![allow(incomplete_features)] #![deny(unreachable_patterns)] diff --git a/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs b/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs index 860c7a1bde5fb..81bc1176f572e 100644 --- a/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs +++ b/src/test/ui/or-patterns/exhaustiveness-unreachable-pattern.rs @@ -1,5 +1,5 @@ #![feature(or_patterns)] -#![feature(slice_patterns)] + #![allow(incomplete_features)] #![deny(unreachable_patterns)] diff --git a/src/test/ui/parser/match-vec-invalid.rs b/src/test/ui/parser/match-vec-invalid.rs index 00f4374b256d2..97e33624bf6de 100644 --- a/src/test/ui/parser/match-vec-invalid.rs +++ b/src/test/ui/parser/match-vec-invalid.rs @@ -3,8 +3,6 @@ fn main() { match a { [1, tail @ .., tail @ ..] => {}, //~^ ERROR identifier `tail` is bound more than once in the same pattern - //~| ERROR subslice patterns are unstable - //~| ERROR subslice patterns are unstable //~| ERROR `..` can only be used once per slice pattern _ => () } diff --git a/src/test/ui/parser/match-vec-invalid.stderr b/src/test/ui/parser/match-vec-invalid.stderr index 58343e86d7b2d..1dc11c31905c4 100644 --- a/src/test/ui/parser/match-vec-invalid.stderr +++ b/src/test/ui/parser/match-vec-invalid.stderr @@ -4,24 +4,6 @@ error[E0416]: identifier `tail` is bound more than once in the same pattern LL | [1, tail @ .., tail @ ..] => {}, | ^^^^ used in a pattern more than once -error[E0658]: subslice patterns are unstable - --> $DIR/match-vec-invalid.rs:4:13 - | -LL | [1, tail @ .., tail @ ..] => {}, - | ^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/62254 - = help: add `#![feature(slice_patterns)]` to the crate attributes to enable - -error[E0658]: subslice patterns are unstable - --> $DIR/match-vec-invalid.rs:4:24 - | -LL | [1, tail @ .., tail @ ..] => {}, - | ^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/62254 - = help: add `#![feature(slice_patterns)]` to the crate attributes to enable - error: `..` can only be used once per slice pattern --> $DIR/match-vec-invalid.rs:4:31 | @@ -31,12 +13,12 @@ LL | [1, tail @ .., tail @ ..] => {}, | previously used here error[E0308]: mismatched types - --> $DIR/match-vec-invalid.rs:13:30 + --> $DIR/match-vec-invalid.rs:11:30 | LL | const RECOVERY_WITNESS: () = 0; | ^ expected `()`, found integer -error: aborting due to 5 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0308, E0416, E0658. +Some errors have detailed explanations: E0308, E0416. For more information about an error, try `rustc --explain E0308`. diff --git a/src/test/ui/parser/pat-lt-bracket-6.rs b/src/test/ui/parser/pat-lt-bracket-6.rs index f27caa5d78c8e..7becffa9fe2f7 100644 --- a/src/test/ui/parser/pat-lt-bracket-6.rs +++ b/src/test/ui/parser/pat-lt-bracket-6.rs @@ -4,7 +4,6 @@ fn main() { let Test(&desc[..]) = x; //~^ ERROR: expected one of `)`, `,`, `@`, or `|`, found `[` - //~^^ ERROR subslice patterns are unstable } const RECOVERY_WITNESS: () = 0; //~ ERROR mismatched types diff --git a/src/test/ui/parser/pat-lt-bracket-6.stderr b/src/test/ui/parser/pat-lt-bracket-6.stderr index fe9603cb57f1f..035d0dbfe06d6 100644 --- a/src/test/ui/parser/pat-lt-bracket-6.stderr +++ b/src/test/ui/parser/pat-lt-bracket-6.stderr @@ -7,22 +7,12 @@ LL | let Test(&desc[..]) = x; | expected one of `)`, `,`, `@`, or `|` | help: missing `,` -error[E0658]: subslice patterns are unstable - --> $DIR/pat-lt-bracket-6.rs:5:20 - | -LL | let Test(&desc[..]) = x; - | ^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/62254 - = help: add `#![feature(slice_patterns)]` to the crate attributes to enable - error[E0308]: mismatched types - --> $DIR/pat-lt-bracket-6.rs:10:30 + --> $DIR/pat-lt-bracket-6.rs:9:30 | LL | const RECOVERY_WITNESS: () = 0; | ^ expected `()`, found integer -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0308, E0658. -For more information about an error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.rs b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.rs index 1d9f341c5146a..2cd375da9a56f 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.rs @@ -1,7 +1,6 @@ // Test that moving on both sides of an `@` pattern is not allowed. #![feature(bindings_after_at)] -#![feature(slice_patterns)] fn main() { struct U; // Not copy! diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr index f3f8fd655ce0c..12ebcb72af11c 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr @@ -1,53 +1,53 @@ error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:12:9 + --> $DIR/borrowck-move-and-move.rs:11:9 | LL | let a @ b = U; | ^^^^^ binds an already bound by-move value by moving it error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:16:9 + --> $DIR/borrowck-move-and-move.rs:15:9 | LL | let a @ (b, c) = (U, U); | ^^^^^^^^^^ binds an already bound by-move value by moving it error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:20:9 + --> $DIR/borrowck-move-and-move.rs:19:9 | LL | let a @ (b, c) = (u(), u()); | ^^^^^^^^^^ binds an already bound by-move value by moving it error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:25:9 + --> $DIR/borrowck-move-and-move.rs:24:9 | LL | a @ Ok(b) | a @ Err(b) => {} | ^^^^^^^^^ binds an already bound by-move value by moving it error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:25:21 + --> $DIR/borrowck-move-and-move.rs:24:21 | LL | a @ Ok(b) | a @ Err(b) => {} | ^^^^^^^^^^ binds an already bound by-move value by moving it error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:37:9 + --> $DIR/borrowck-move-and-move.rs:36:9 | LL | xs @ [a, .., b] => {} | ^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:43:9 + --> $DIR/borrowck-move-and-move.rs:42:9 | LL | xs @ [_, ys @ .., _] => {} | ^^^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-move-and-move.rs:32:12 + --> $DIR/borrowck-move-and-move.rs:31:12 | LL | fn fun(a @ b: U) {} | ^^^^^ binds an already bound by-move value by moving it error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:12:13 + --> $DIR/borrowck-move-and-move.rs:11:13 | LL | let a @ b = U; | ----^ - move occurs because value has type `main::U`, which does not implement the `Copy` trait @@ -56,7 +56,7 @@ LL | let a @ b = U; | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:16:17 + --> $DIR/borrowck-move-and-move.rs:15:17 | LL | let a @ (b, c) = (U, U); | --------^- ------ move occurs because value has type `(main::U, main::U)`, which does not implement the `Copy` trait @@ -65,7 +65,7 @@ LL | let a @ (b, c) = (U, U); | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:20:17 + --> $DIR/borrowck-move-and-move.rs:19:17 | LL | let a @ (b, c) = (u(), u()); | --------^- ---------- move occurs because value has type `(main::U, main::U)`, which does not implement the `Copy` trait @@ -74,7 +74,7 @@ LL | let a @ (b, c) = (u(), u()); | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:25:16 + --> $DIR/borrowck-move-and-move.rs:24:16 | LL | match Ok(U) { | ----- move occurs because value has type `std::result::Result`, which does not implement the `Copy` trait @@ -85,7 +85,7 @@ LL | a @ Ok(b) | a @ Err(b) => {} | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:25:29 + --> $DIR/borrowck-move-and-move.rs:24:29 | LL | match Ok(U) { | ----- move occurs because value has type `std::result::Result`, which does not implement the `Copy` trait @@ -96,7 +96,7 @@ LL | a @ Ok(b) | a @ Err(b) => {} | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:37:22 + --> $DIR/borrowck-move-and-move.rs:36:22 | LL | match [u(), u(), u(), u()] { | -------------------- move occurs because value has type `[main::U; 4]`, which does not implement the `Copy` trait @@ -107,7 +107,7 @@ LL | xs @ [a, .., b] => {} | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:43:18 + --> $DIR/borrowck-move-and-move.rs:42:18 | LL | match [u(), u(), u(), u()] { | -------------------- move occurs because value has type `[main::U; 4]`, which does not implement the `Copy` trait @@ -118,7 +118,7 @@ LL | xs @ [_, ys @ .., _] => {} | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-move-and-move.rs:32:16 + --> $DIR/borrowck-move-and-move.rs:31:16 | LL | fn fun(a @ b: U) {} | ----^ diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs index afac8d990b474..092bd1133dd62 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box-pass.rs @@ -4,7 +4,6 @@ #![feature(bindings_after_at)] #![feature(box_patterns)] -#![feature(slice_patterns)] #[derive(Copy, Clone)] struct C; diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs index fce31409e16c4..3b2f598dc0157 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.rs @@ -2,7 +2,6 @@ #![feature(bindings_after_at)] #![feature(box_patterns)] -#![feature(slice_patterns)] #[derive(Copy, Clone)] struct C; diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr index 5772fadd1e741..e96c15b0fa7dd 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-at-and-box.stderr @@ -1,23 +1,23 @@ error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-at-and-box.rs:17:9 + --> $DIR/borrowck-pat-at-and-box.rs:16:9 | LL | let a @ box &b = Box::new(&C); | ^^^^^^^^^^ binds an already bound by-move value by moving it error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-at-and-box.rs:21:9 + --> $DIR/borrowck-pat-at-and-box.rs:20:9 | LL | let a @ box b = Box::new(C); | ^^^^^^^^^ binds an already bound by-move value by moving it error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-at-and-box.rs:33:25 + --> $DIR/borrowck-pat-at-and-box.rs:32:25 | LL | match Box::new(C) { a @ box b => {} } | ^^^^^^^^^ binds an already bound by-move value by moving it error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/borrowck-pat-at-and-box.rs:37:21 + --> $DIR/borrowck-pat-at-and-box.rs:36:21 | LL | let ref a @ box b = Box::new(NC); | ------------^ @@ -26,7 +26,7 @@ LL | let ref a @ box b = Box::new(NC); | by-ref pattern here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-at-and-box.rs:39:9 + --> $DIR/borrowck-pat-at-and-box.rs:38:9 | LL | let ref a @ box ref mut b = Box::new(nc()); | -----^^^^^^^--------- @@ -35,7 +35,7 @@ LL | let ref a @ box ref mut b = Box::new(nc()); | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-at-and-box.rs:41:9 + --> $DIR/borrowck-pat-at-and-box.rs:40:9 | LL | let ref a @ box ref mut b = Box::new(NC); | -----^^^^^^^--------- @@ -44,7 +44,7 @@ LL | let ref a @ box ref mut b = Box::new(NC); | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-at-and-box.rs:43:9 + --> $DIR/borrowck-pat-at-and-box.rs:42:9 | LL | let ref a @ box ref mut b = Box::new(NC); | -----^^^^^^^--------- @@ -53,7 +53,7 @@ LL | let ref a @ box ref mut b = Box::new(NC); | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-at-and-box.rs:46:9 + --> $DIR/borrowck-pat-at-and-box.rs:45:9 | LL | let ref a @ box ref mut b = Box::new(NC); | -----^^^^^^^--------- @@ -62,7 +62,7 @@ LL | let ref a @ box ref mut b = Box::new(NC); | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-at-and-box.rs:52:9 + --> $DIR/borrowck-pat-at-and-box.rs:51:9 | LL | let ref mut a @ box ref b = Box::new(NC); | ---------^^^^^^^----- @@ -71,7 +71,7 @@ LL | let ref mut a @ box ref b = Box::new(NC); | mutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-at-and-box.rs:66:9 + --> $DIR/borrowck-pat-at-and-box.rs:65:9 | LL | ref mut a @ box ref b => { | ---------^^^^^^^----- @@ -80,7 +80,7 @@ LL | ref mut a @ box ref b => { | mutable borrow occurs here error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/borrowck-pat-at-and-box.rs:75:38 + --> $DIR/borrowck-pat-at-and-box.rs:74:38 | LL | box [Ok(a), ref xs @ .., Err(b)] => {} | ----------- ^ by-move pattern here @@ -88,7 +88,7 @@ LL | box [Ok(a), ref xs @ .., Err(b)] => {} | by-ref pattern here error[E0009]: cannot bind by-move and by-ref in the same pattern - --> $DIR/borrowck-pat-at-and-box.rs:81:46 + --> $DIR/borrowck-pat-at-and-box.rs:80:46 | LL | [Ok(box ref a), ref xs @ .., Err(box b), Err(box ref mut c)] => {} | ----- ----------- ^ --------- by-ref pattern here @@ -98,19 +98,19 @@ LL | [Ok(box ref a), ref xs @ .., Err(box b), Err(box ref mut c)] => {} | by-ref pattern here error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-at-and-box.rs:25:11 + --> $DIR/borrowck-pat-at-and-box.rs:24:11 | LL | fn f1(a @ box &b: Box<&C>) {} | ^^^^^^^^^^ binds an already bound by-move value by moving it error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-at-and-box.rs:29:11 + --> $DIR/borrowck-pat-at-and-box.rs:28:11 | LL | fn f2(a @ box b: Box) {} | ^^^^^^^^^ binds an already bound by-move value by moving it error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-at-and-box.rs:58:11 + --> $DIR/borrowck-pat-at-and-box.rs:57:11 | LL | fn f5(ref mut a @ box ref b: Box) { | ---------^^^^^^^----- @@ -119,7 +119,7 @@ LL | fn f5(ref mut a @ box ref b: Box) { | mutable borrow occurs here error[E0382]: use of moved value - --> $DIR/borrowck-pat-at-and-box.rs:17:18 + --> $DIR/borrowck-pat-at-and-box.rs:16:18 | LL | let a @ box &b = Box::new(&C); | ---------^ ------------ move occurs because value has type `std::boxed::Box<&C>`, which does not implement the `Copy` trait @@ -128,7 +128,7 @@ LL | let a @ box &b = Box::new(&C); | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-pat-at-and-box.rs:21:17 + --> $DIR/borrowck-pat-at-and-box.rs:20:17 | LL | let a @ box b = Box::new(C); | --------^ ----------- move occurs because value has type `std::boxed::Box`, which does not implement the `Copy` trait @@ -137,7 +137,7 @@ LL | let a @ box b = Box::new(C); | value moved here error[E0382]: use of moved value - --> $DIR/borrowck-pat-at-and-box.rs:33:33 + --> $DIR/borrowck-pat-at-and-box.rs:32:33 | LL | match Box::new(C) { a @ box b => {} } | ----------- --------^ @@ -147,7 +147,7 @@ LL | match Box::new(C) { a @ box b => {} } | move occurs because value has type `std::boxed::Box`, which does not implement the `Copy` trait error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-at-and-box.rs:46:21 + --> $DIR/borrowck-pat-at-and-box.rs:45:21 | LL | let ref a @ box ref mut b = Box::new(NC); | ------------^^^^^^^^^ @@ -159,7 +159,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-at-and-box.rs:52:25 + --> $DIR/borrowck-pat-at-and-box.rs:51:25 | LL | let ref mut a @ box ref b = Box::new(NC); | ----------------^^^^^ @@ -171,7 +171,7 @@ LL | *a = Box::new(NC); | -- mutable borrow later used here error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-at-and-box.rs:66:25 + --> $DIR/borrowck-pat-at-and-box.rs:65:25 | LL | ref mut a @ box ref b => { | ----------------^^^^^ @@ -183,7 +183,7 @@ LL | *a = Box::new(NC); | -- mutable borrow later used here error[E0382]: use of moved value - --> $DIR/borrowck-pat-at-and-box.rs:25:20 + --> $DIR/borrowck-pat-at-and-box.rs:24:20 | LL | fn f1(a @ box &b: Box<&C>) {} | ---------^ @@ -193,7 +193,7 @@ LL | fn f1(a @ box &b: Box<&C>) {} | move occurs because value has type `std::boxed::Box<&C>`, which does not implement the `Copy` trait error[E0382]: use of moved value - --> $DIR/borrowck-pat-at-and-box.rs:29:19 + --> $DIR/borrowck-pat-at-and-box.rs:28:19 | LL | fn f2(a @ box b: Box) {} | --------^ @@ -203,7 +203,7 @@ LL | fn f2(a @ box b: Box) {} | move occurs because value has type `std::boxed::Box`, which does not implement the `Copy` trait error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-at-and-box.rs:58:27 + --> $DIR/borrowck-pat-at-and-box.rs:57:27 | LL | fn f5(ref mut a @ box ref b: Box) { | ----------------^^^^^ diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs index be19e5f2a85ca..c4ce50c8b9a16 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-by-copy-bindings-in-at.rs @@ -2,7 +2,6 @@ // Test `Copy` bindings in the rhs of `@` patterns. -#![feature(slice_patterns)] #![feature(bindings_after_at)] #[derive(Copy, Clone)] diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs index edf9fb3145890..fb243016a1185 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-both-sides.rs @@ -4,7 +4,6 @@ // of an `@` pattern according to NLL borrowck. #![feature(bindings_after_at)] -#![feature(slice_patterns)] fn main() { struct U; // Not copy! diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs index 559925c282f9a..e8510dfa64999 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs @@ -1,5 +1,4 @@ #![feature(bindings_after_at)] -#![feature(slice_patterns)] enum Option { None, diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr index b5c26a1fa0399..0d7b703f1816b 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr @@ -1,5 +1,5 @@ error: cannot borrow `z` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:11:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:10:9 | LL | ref mut z @ &mut Some(ref a) => { | ---------^^^^^^^^^^^^^-----^ @@ -8,7 +8,7 @@ LL | ref mut z @ &mut Some(ref a) => { | mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:32:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:31:9 | LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub | ---------^^^^-----------------^ @@ -18,7 +18,7 @@ LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub | first mutable borrow occurs here error: cannot borrow `b` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:32:22 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:31:22 | LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub | -----^^^--------- @@ -27,7 +27,7 @@ LL | let ref mut a @ (ref b @ ref mut c) = u(); // sub-in-sub | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:36:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:35:9 | LL | let ref a @ ref mut b = U; | -----^^^--------- @@ -36,7 +36,7 @@ LL | let ref a @ ref mut b = U; | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:38:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:37:9 | LL | let ref mut a @ ref b = U; | ---------^^^----- @@ -45,7 +45,7 @@ LL | let ref mut a @ ref b = U; | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:40:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:39:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ @@ -55,7 +55,7 @@ LL | let ref a @ (ref mut b, ref mut c) = (U, U); | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:42:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:41:9 | LL | let ref mut a @ (ref b, ref c) = (U, U); | ---------^^^^-----^^-----^ @@ -65,7 +65,7 @@ LL | let ref mut a @ (ref b, ref c) = (U, U); | mutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:45:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:44:9 | LL | let ref mut a @ ref b = u(); | ---------^^^----- @@ -74,7 +74,7 @@ LL | let ref mut a @ ref b = u(); | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:50:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:49:9 | LL | let ref a @ ref mut b = u(); | -----^^^--------- @@ -83,7 +83,7 @@ LL | let ref a @ ref mut b = u(); | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:56:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:55:9 | LL | let ref mut a @ ref b = U; | ---------^^^----- @@ -92,7 +92,7 @@ LL | let ref mut a @ ref b = U; | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:60:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:59:9 | LL | let ref a @ ref mut b = U; | -----^^^--------- @@ -101,7 +101,7 @@ LL | let ref a @ ref mut b = U; | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:66:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:65:9 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { | ---------^^^^^^-----^ @@ -110,7 +110,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { | mutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:66:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:65:33 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { | ---------^^^^^^^-----^ @@ -119,7 +119,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) => { | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:75:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:74:9 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | -----^^^^^^---------^ @@ -128,7 +128,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:75:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:74:33 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | -----^^^^^^^---------^ @@ -137,7 +137,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:86:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:85:9 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} | -----^^^^^^---------^ @@ -146,7 +146,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:86:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:85:33 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} | -----^^^^^^^---------^ @@ -155,7 +155,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:93:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:92:9 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} | ---------^^^^^^-----^ @@ -164,7 +164,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); fa | mutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:93:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:92:33 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} | ---------^^^^^^^-----^ @@ -173,7 +173,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); fa | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:100:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:99:9 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} | -----^^^^^^---------^ @@ -182,7 +182,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:100:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:99:33 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} | -----^^^^^^^---------^ @@ -191,7 +191,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:108:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:9 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} | ---------^^^^^^-----^ @@ -200,7 +200,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false | mutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:108:33 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:33 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} | ---------^^^^^^^-----^ @@ -209,7 +209,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:116:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:115:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ @@ -219,7 +219,7 @@ LL | let ref a @ (ref mut b, ref mut c) = (U, U); | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:121:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:120:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ @@ -229,7 +229,7 @@ LL | let ref a @ (ref mut b, ref mut c) = (U, U); | immutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:128:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:127:9 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | -----^^^^---------^^---------^ @@ -239,7 +239,7 @@ LL | let ref a @ (ref mut b, ref mut c) = (U, U); | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:133:9 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:132:9 | LL | let ref mut a @ (ref b, ref c) = (U, U); | ---------^^^^-----^^-----^ @@ -249,7 +249,7 @@ LL | let ref mut a @ (ref b, ref c) = (U, U); | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:25:11 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:24:11 | LL | fn f1(ref a @ ref mut b: U) {} | -----^^^--------- @@ -258,7 +258,7 @@ LL | fn f1(ref a @ ref mut b: U) {} | immutable borrow occurs here error: cannot borrow `a` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:27:11 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:26:11 | LL | fn f2(ref mut a @ ref b: U) {} | ---------^^^----- @@ -267,7 +267,7 @@ LL | fn f2(ref mut a @ ref b: U) {} | mutable borrow occurs here error: cannot borrow `a` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:29:11 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:28:11 | LL | fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {} | -----^^^^^^^^^^^----------------^^^^^^^^ @@ -276,7 +276,7 @@ LL | fn f3(ref a @ [ref b, ref mut mid @ .., ref c]: [U; 4]) {} | immutable borrow occurs here error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:11:31 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:10:31 | LL | ref mut z @ &mut Some(ref a) => { | ----------------------^^^^^- @@ -288,7 +288,7 @@ LL | **z = None; | ---------- mutable borrow later used here error[E0502]: cannot borrow `_` as immutable because it is also borrowed as mutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:45:21 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:44:21 | LL | let ref mut a @ ref b = u(); | ------------^^^^^ @@ -300,7 +300,7 @@ LL | *a = u(); | -------- mutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:50:17 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:49:17 | LL | let ref a @ ref mut b = u(); | --------^^^^^^^^^ @@ -312,7 +312,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:75:20 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:74:20 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | -----------^^^^^^^^^- @@ -324,7 +324,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:75:45 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:74:45 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => { | ------------^^^^^^^^^- @@ -336,7 +336,7 @@ LL | drop(a); | - immutable borrow later used here error[E0594]: cannot assign to `*b`, as it is immutable for the pattern guard - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:86:61 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:85:61 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {} | ^^^^^^ cannot assign @@ -344,7 +344,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } = note: variables bound in patterns are immutable until the end of the pattern guard error[E0594]: cannot assign to `*a`, as it is immutable for the pattern guard - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:93:61 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:92:61 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {} | ^^^^^^^^^^^ cannot assign @@ -352,7 +352,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); fa = note: variables bound in patterns are immutable until the end of the pattern guard error[E0507]: cannot move out of `b` in pattern guard - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:100:66 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:99:66 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} | ^ move occurs because `b` has type `&mut main::U`, which does not implement the `Copy` trait @@ -360,7 +360,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false = note: variables bound in patterns cannot be moved from until after the end of the pattern guard error[E0507]: cannot move out of `b` in pattern guard - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:100:66 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:99:66 | LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {} | ^ move occurs because `b` has type `&mut main::U`, which does not implement the `Copy` trait @@ -368,7 +368,7 @@ LL | ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false = note: variables bound in patterns cannot be moved from until after the end of the pattern guard error[E0507]: cannot move out of `a` in pattern guard - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:108:66 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:66 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} | ^ move occurs because `a` has type `&mut std::result::Result`, which does not implement the `Copy` trait @@ -376,7 +376,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false = note: variables bound in patterns cannot be moved from until after the end of the pattern guard error[E0507]: cannot move out of `a` in pattern guard - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:108:66 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:107:66 | LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {} | ^ move occurs because `a` has type `&mut std::result::Result`, which does not implement the `Copy` trait @@ -384,7 +384,7 @@ LL | ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false = note: variables bound in patterns cannot be moved from until after the end of the pattern guard error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:121:18 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:120:18 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | ---------^^^^^^^^^------------ @@ -396,7 +396,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:121:29 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:120:29 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | --------------------^^^^^^^^^- @@ -408,7 +408,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:128:18 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:127:18 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | ---------^^^^^^^^^------------ @@ -420,7 +420,7 @@ LL | drop(a); | - immutable borrow later used here error[E0502]: cannot borrow `_` as mutable because it is also borrowed as immutable - --> $DIR/borrowck-pat-ref-mut-and-ref.rs:128:29 + --> $DIR/borrowck-pat-ref-mut-and-ref.rs:127:29 | LL | let ref a @ (ref mut b, ref mut c) = (U, U); | --------------------^^^^^^^^^- diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs index 6b8b7545e687d..f425b35630d17 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs @@ -1,7 +1,6 @@ // Test that `ref mut x @ ref mut y` and varieties of that are not allowed. #![feature(bindings_after_at)] -#![feature(slice_patterns)] fn main() { struct U; diff --git a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr index 1b5e6c7411703..d07ad140cc23a 100644 --- a/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr +++ b/src/test/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr @@ -1,5 +1,5 @@ error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:25:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:24:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -8,7 +8,7 @@ LL | let ref mut a @ ref mut b = U; | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:29:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:28:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -17,7 +17,7 @@ LL | let ref mut a @ ref mut b = U; | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:32:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:31:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -26,7 +26,7 @@ LL | let ref mut a @ ref mut b = U; | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:35:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:34:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -35,7 +35,7 @@ LL | let ref mut a @ ref mut b = U; | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:39:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:38:9 | LL | let ref mut a @ ref mut b = U; | ---------^^^--------- @@ -44,7 +44,7 @@ LL | let ref mut a @ ref mut b = U; | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:43:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:42:9 | LL | let ref mut a @ ( | ^-------- @@ -66,7 +66,7 @@ LL | | ) = (U, [U, U, U]); | |_____^ error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:53:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:52:9 | LL | let ref mut a @ ( | ^-------- @@ -88,31 +88,31 @@ LL | | ) = (u(), [u(), u(), u()]); | |_________^ error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-ref-mut-twice.rs:63:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:62:9 | LL | let a @ (ref mut b, ref mut c) = (U, U); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-ref-mut-twice.rs:67:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:66:9 | LL | let a @ (b, [c, d]) = &mut val; // Same as ^-- | ^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-ref-mut-twice.rs:71:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:70:9 | LL | let a @ &mut ref mut b = &mut U; | ^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it error[E0007]: cannot bind by-move with sub-bindings - --> $DIR/borrowck-pat-ref-mut-twice.rs:74:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:73:9 | LL | let a @ &mut (ref mut b, ref mut c) = &mut (U, U); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:79:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:78:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ @@ -121,7 +121,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:79:37 + --> $DIR/borrowck-pat-ref-mut-twice.rs:78:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ @@ -130,7 +130,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:85:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:84:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ @@ -139,7 +139,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:85:37 + --> $DIR/borrowck-pat-ref-mut-twice.rs:84:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ @@ -148,7 +148,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:92:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:91:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ @@ -157,7 +157,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:92:37 + --> $DIR/borrowck-pat-ref-mut-twice.rs:91:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ @@ -166,7 +166,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:104:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:103:9 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^---------^ @@ -175,7 +175,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:104:37 + --> $DIR/borrowck-pat-ref-mut-twice.rs:103:37 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------^^^^^^^---------^ @@ -184,7 +184,7 @@ LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:11:11 + --> $DIR/borrowck-pat-ref-mut-twice.rs:10:11 | LL | fn f1(ref mut a @ ref mut b: U) {} | ---------^^^--------- @@ -193,7 +193,7 @@ LL | fn f1(ref mut a @ ref mut b: U) {} | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:13:11 + --> $DIR/borrowck-pat-ref-mut-twice.rs:12:11 | LL | fn f2(ref mut a @ ref mut b: U) {} | ---------^^^--------- @@ -202,7 +202,7 @@ LL | fn f2(ref mut a @ ref mut b: U) {} | first mutable borrow occurs here error: cannot borrow `a` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:16:9 + --> $DIR/borrowck-pat-ref-mut-twice.rs:15:9 | LL | ref mut a @ [ | ^-------- @@ -220,7 +220,7 @@ LL | | ] : [[U; 4]; 5] | |_________^ error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:25:21 + --> $DIR/borrowck-pat-ref-mut-twice.rs:24:21 | LL | let ref mut a @ ref mut b = U; | ------------^^^^^^^^^ @@ -232,7 +232,7 @@ LL | drop(a); | - first borrow later used here error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:35:21 + --> $DIR/borrowck-pat-ref-mut-twice.rs:34:21 | LL | let ref mut a @ ref mut b = U; | ------------^^^^^^^^^ @@ -244,7 +244,7 @@ LL | *a = U; | ------ first borrow later used here error[E0382]: borrow of moved value - --> $DIR/borrowck-pat-ref-mut-twice.rs:63:25 + --> $DIR/borrowck-pat-ref-mut-twice.rs:62:25 | LL | let a @ (ref mut b, ref mut c) = (U, U); | ----------------^^^^^^^^^- ------ move occurs because value has type `(main::U, main::U)`, which does not implement the `Copy` trait @@ -253,7 +253,7 @@ LL | let a @ (ref mut b, ref mut c) = (U, U); | value moved here error[E0382]: borrow of moved value - --> $DIR/borrowck-pat-ref-mut-twice.rs:67:21 + --> $DIR/borrowck-pat-ref-mut-twice.rs:66:21 | LL | let a @ (b, [c, d]) = &mut val; // Same as ^-- | ------------^-- -------- move occurs because value has type `&mut (main::U, [main::U; 2])`, which does not implement the `Copy` trait @@ -262,7 +262,7 @@ LL | let a @ (b, [c, d]) = &mut val; // Same as ^-- | value moved here error[E0382]: borrow of moved value - --> $DIR/borrowck-pat-ref-mut-twice.rs:71:18 + --> $DIR/borrowck-pat-ref-mut-twice.rs:70:18 | LL | let a @ &mut ref mut b = &mut U; | ---------^^^^^^^^^ ------ move occurs because value has type `&mut main::U`, which does not implement the `Copy` trait @@ -271,7 +271,7 @@ LL | let a @ &mut ref mut b = &mut U; | value moved here error[E0382]: borrow of moved value - --> $DIR/borrowck-pat-ref-mut-twice.rs:74:30 + --> $DIR/borrowck-pat-ref-mut-twice.rs:73:30 | LL | let a @ &mut (ref mut b, ref mut c) = &mut (U, U); | ---------------------^^^^^^^^^- ----------- move occurs because value has type `&mut (main::U, main::U)`, which does not implement the `Copy` trait @@ -280,7 +280,7 @@ LL | let a @ &mut (ref mut b, ref mut c) = &mut (U, U); | value moved here error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:92:24 + --> $DIR/borrowck-pat-ref-mut-twice.rs:91:24 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------------^^^^^^^^^- @@ -292,7 +292,7 @@ LL | *a = Err(U); | ----------- first borrow later used here error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:92:53 + --> $DIR/borrowck-pat-ref-mut-twice.rs:91:53 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ----------------^^^^^^^^^- @@ -304,7 +304,7 @@ LL | *a = Err(U); | ----------- first borrow later used here error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:104:24 + --> $DIR/borrowck-pat-ref-mut-twice.rs:103:24 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ---------------^^^^^^^^^- @@ -316,7 +316,7 @@ LL | drop(a); | - first borrow later used here error[E0499]: cannot borrow `_` as mutable more than once at a time - --> $DIR/borrowck-pat-ref-mut-twice.rs:104:53 + --> $DIR/borrowck-pat-ref-mut-twice.rs:103:53 | LL | ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => { | ----------------^^^^^^^^^- diff --git a/src/test/ui/pattern/issue-53820-slice-pattern-large-array.rs b/src/test/ui/pattern/issue-53820-slice-pattern-large-array.rs index c910cded96be4..1249329206112 100644 --- a/src/test/ui/pattern/issue-53820-slice-pattern-large-array.rs +++ b/src/test/ui/pattern/issue-53820-slice-pattern-large-array.rs @@ -2,8 +2,6 @@ // This used to cause a stack overflow in the compiler. -#![feature(slice_patterns)] - fn main() { const LARGE_SIZE: usize = 1024 * 1024; let [..] = [0u8; LARGE_SIZE]; diff --git a/src/test/ui/pattern/usefulness/65413-constants-and-slices-exhaustiveness.rs b/src/test/ui/pattern/usefulness/65413-constants-and-slices-exhaustiveness.rs index 6c54c938bf110..54dfa889ee35a 100644 --- a/src/test/ui/pattern/usefulness/65413-constants-and-slices-exhaustiveness.rs +++ b/src/test/ui/pattern/usefulness/65413-constants-and-slices-exhaustiveness.rs @@ -1,5 +1,5 @@ // check-pass -#![feature(slice_patterns)] + #![deny(unreachable_patterns)] const C0: &'static [u8] = b"\x00"; diff --git a/src/test/ui/pattern/usefulness/match-byte-array-patterns.rs b/src/test/ui/pattern/usefulness/match-byte-array-patterns.rs index 7541ea3e2e263..9b6c8bd5556be 100644 --- a/src/test/ui/pattern/usefulness/match-byte-array-patterns.rs +++ b/src/test/ui/pattern/usefulness/match-byte-array-patterns.rs @@ -1,4 +1,3 @@ -#![feature(slice_patterns)] #![deny(unreachable_patterns)] fn main() { diff --git a/src/test/ui/pattern/usefulness/match-byte-array-patterns.stderr b/src/test/ui/pattern/usefulness/match-byte-array-patterns.stderr index b28646b50cf01..09484692fab08 100644 --- a/src/test/ui/pattern/usefulness/match-byte-array-patterns.stderr +++ b/src/test/ui/pattern/usefulness/match-byte-array-patterns.stderr @@ -1,53 +1,53 @@ error: unreachable pattern - --> $DIR/match-byte-array-patterns.rs:9:9 + --> $DIR/match-byte-array-patterns.rs:8:9 | LL | &[0x41, 0x41, 0x41, 0x41] => {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: lint level defined here - --> $DIR/match-byte-array-patterns.rs:2:9 + --> $DIR/match-byte-array-patterns.rs:1:9 | LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/match-byte-array-patterns.rs:15:9 + --> $DIR/match-byte-array-patterns.rs:14:9 | LL | b"AAAA" => {}, | ^^^^^^^ error: unreachable pattern - --> $DIR/match-byte-array-patterns.rs:21:9 + --> $DIR/match-byte-array-patterns.rs:20:9 | LL | b"AAAA" => {}, | ^^^^^^^ error: unreachable pattern - --> $DIR/match-byte-array-patterns.rs:27:9 + --> $DIR/match-byte-array-patterns.rs:26:9 | LL | b"AAAA" => {}, | ^^^^^^^ error: unreachable pattern - --> $DIR/match-byte-array-patterns.rs:35:9 + --> $DIR/match-byte-array-patterns.rs:34:9 | LL | &[0x41, 0x41, 0x41, 0x41] => {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/match-byte-array-patterns.rs:41:9 + --> $DIR/match-byte-array-patterns.rs:40:9 | LL | b"AAAA" => {}, | ^^^^^^^ error: unreachable pattern - --> $DIR/match-byte-array-patterns.rs:47:9 + --> $DIR/match-byte-array-patterns.rs:46:9 | LL | b"AAAA" => {}, | ^^^^^^^ error: unreachable pattern - --> $DIR/match-byte-array-patterns.rs:53:9 + --> $DIR/match-byte-array-patterns.rs:52:9 | LL | b"AAAA" => {}, | ^^^^^^^ diff --git a/src/test/ui/pattern/usefulness/match-slice-patterns.rs b/src/test/ui/pattern/usefulness/match-slice-patterns.rs index af7fd53a1f1e9..92d74b8c229d6 100644 --- a/src/test/ui/pattern/usefulness/match-slice-patterns.rs +++ b/src/test/ui/pattern/usefulness/match-slice-patterns.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - fn check(list: &[Option<()>]) { match list { //~^ ERROR `&[_, Some(_), .., None, _]` not covered diff --git a/src/test/ui/pattern/usefulness/match-slice-patterns.stderr b/src/test/ui/pattern/usefulness/match-slice-patterns.stderr index 72ae5d5fe3b33..977a112808190 100644 --- a/src/test/ui/pattern/usefulness/match-slice-patterns.stderr +++ b/src/test/ui/pattern/usefulness/match-slice-patterns.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `&[_, Some(_), .., None, _]` not covered - --> $DIR/match-slice-patterns.rs:4:11 + --> $DIR/match-slice-patterns.rs:2:11 | LL | match list { | ^^^^ pattern `&[_, Some(_), .., None, _]` not covered diff --git a/src/test/ui/pattern/usefulness/match-vec-unreachable.rs b/src/test/ui/pattern/usefulness/match-vec-unreachable.rs index 78810525bad0f..3342389be6e4c 100644 --- a/src/test/ui/pattern/usefulness/match-vec-unreachable.rs +++ b/src/test/ui/pattern/usefulness/match-vec-unreachable.rs @@ -1,4 +1,3 @@ -#![feature(slice_patterns)] #![deny(unreachable_patterns)] fn main() { diff --git a/src/test/ui/pattern/usefulness/match-vec-unreachable.stderr b/src/test/ui/pattern/usefulness/match-vec-unreachable.stderr index 415c24ae77ef5..e9a751074c2e1 100644 --- a/src/test/ui/pattern/usefulness/match-vec-unreachable.stderr +++ b/src/test/ui/pattern/usefulness/match-vec-unreachable.stderr @@ -1,23 +1,23 @@ error: unreachable pattern - --> $DIR/match-vec-unreachable.rs:9:9 + --> $DIR/match-vec-unreachable.rs:8:9 | LL | [(1, 2), (2, 3), b] => (), | ^^^^^^^^^^^^^^^^^^^ | note: lint level defined here - --> $DIR/match-vec-unreachable.rs:2:9 + --> $DIR/match-vec-unreachable.rs:1:9 | LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/match-vec-unreachable.rs:19:9 + --> $DIR/match-vec-unreachable.rs:18:9 | LL | [_, _, _, _, _] => { } | ^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/match-vec-unreachable.rs:27:9 + --> $DIR/match-vec-unreachable.rs:26:9 | LL | ['a', 'b', 'c'] => {} | ^^^^^^^^^^^^^^^ diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.rs b/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.rs index 9423a2891a620..d198144790be1 100644 --- a/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.rs +++ b/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - enum T { A(U), B } enum U { C, D } diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.stderr index 67c818e19cbda..72b4b522198e0 100644 --- a/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.stderr +++ b/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `(Some(&[]), Err(_))` not covered - --> $DIR/non-exhaustive-match-nested.rs:7:11 + --> $DIR/non-exhaustive-match-nested.rs:5:11 | LL | match (l1, l2) { | ^^^^^^^^ pattern `(Some(&[]), Err(_))` not covered @@ -7,7 +7,7 @@ LL | match (l1, l2) { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `A(C)` not covered - --> $DIR/non-exhaustive-match-nested.rs:17:11 + --> $DIR/non-exhaustive-match-nested.rs:15:11 | LL | enum T { A(U), B } | ------------------ diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match.rs b/src/test/ui/pattern/usefulness/non-exhaustive-match.rs index bfca5352353a7..9947989dc1211 100644 --- a/src/test/ui/pattern/usefulness/non-exhaustive-match.rs +++ b/src/test/ui/pattern/usefulness/non-exhaustive-match.rs @@ -1,4 +1,3 @@ -#![feature(slice_patterns)] #![allow(illegal_floating_point_literal_pattern)] enum T { A, B } diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr index 577867e4e7122..a06ad5788515c 100644 --- a/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr +++ b/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `A` not covered - --> $DIR/non-exhaustive-match.rs:8:11 + --> $DIR/non-exhaustive-match.rs:7:11 | LL | enum T { A, B } | --------------- @@ -13,7 +13,7 @@ LL | match x { T::B => { } } = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `false` not covered - --> $DIR/non-exhaustive-match.rs:9:11 + --> $DIR/non-exhaustive-match.rs:8:11 | LL | match true { | ^^^^ pattern `false` not covered @@ -21,7 +21,7 @@ LL | match true { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `Some(_)` not covered - --> $DIR/non-exhaustive-match.rs:12:11 + --> $DIR/non-exhaustive-match.rs:11:11 | LL | match Some(10) { | ^^^^^^^^ pattern `Some(_)` not covered @@ -29,7 +29,7 @@ LL | match Some(10) { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `(_, _, std::i32::MIN..=3i32)` and `(_, _, 5i32..=std::i32::MAX)` not covered - --> $DIR/non-exhaustive-match.rs:15:11 + --> $DIR/non-exhaustive-match.rs:14:11 | LL | match (2, 3, 4) { | ^^^^^^^^^ patterns `(_, _, std::i32::MIN..=3i32)` and `(_, _, 5i32..=std::i32::MAX)` not covered @@ -37,7 +37,7 @@ LL | match (2, 3, 4) { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `(A, A)` not covered - --> $DIR/non-exhaustive-match.rs:19:11 + --> $DIR/non-exhaustive-match.rs:18:11 | LL | match (T::A, T::A) { | ^^^^^^^^^^^^ pattern `(A, A)` not covered @@ -45,7 +45,7 @@ LL | match (T::A, T::A) { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `B` not covered - --> $DIR/non-exhaustive-match.rs:23:11 + --> $DIR/non-exhaustive-match.rs:22:11 | LL | enum T { A, B } | --------------- @@ -59,7 +59,7 @@ LL | match T::A { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `[]` not covered - --> $DIR/non-exhaustive-match.rs:34:11 + --> $DIR/non-exhaustive-match.rs:33:11 | LL | match *vec { | ^^^^ pattern `[]` not covered @@ -67,7 +67,7 @@ LL | match *vec { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `[_, _, _, _, ..]` not covered - --> $DIR/non-exhaustive-match.rs:47:11 + --> $DIR/non-exhaustive-match.rs:46:11 | LL | match *vec { | ^^^^ pattern `[_, _, _, _, ..]` not covered diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.rs b/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.rs index 4ca1cbcebccf5..abb4ea8daf57b 100644 --- a/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.rs +++ b/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - struct Foo { first: bool, second: Option<[usize; 4]> diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.stderr index a0b497dd4c0ba..2a9fa07d22fe7 100644 --- a/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.stderr +++ b/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `Foo { first: false, second: Some([_, _, _, _]) }` not covered - --> $DIR/non-exhaustive-pattern-witness.rs:9:11 + --> $DIR/non-exhaustive-pattern-witness.rs:7:11 | LL | / struct Foo { LL | | first: bool, @@ -13,7 +13,7 @@ LL | match (Foo { first: true, second: None }) { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `Red` not covered - --> $DIR/non-exhaustive-pattern-witness.rs:25:11 + --> $DIR/non-exhaustive-pattern-witness.rs:23:11 | LL | / enum Color { LL | | Red, @@ -29,7 +29,7 @@ LL | match Color::Red { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `East`, `South` and `West` not covered - --> $DIR/non-exhaustive-pattern-witness.rs:37:11 + --> $DIR/non-exhaustive-pattern-witness.rs:35:11 | LL | / enum Direction { LL | | North, East, South, West @@ -46,7 +46,7 @@ LL | match Direction::North { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `Second`, `Third`, `Fourth` and 8 more not covered - --> $DIR/non-exhaustive-pattern-witness.rs:48:11 + --> $DIR/non-exhaustive-pattern-witness.rs:46:11 | LL | / enum ExcessiveEnum { LL | | First, Second, Third, Fourth, Fifth, Sixth, Seventh, Eighth, Ninth, Tenth, Eleventh, Twelfth @@ -59,7 +59,7 @@ LL | match ExcessiveEnum::First { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `CustomRGBA { a: true, .. }` not covered - --> $DIR/non-exhaustive-pattern-witness.rs:56:11 + --> $DIR/non-exhaustive-pattern-witness.rs:54:11 | LL | / enum Color { LL | | Red, @@ -75,7 +75,7 @@ LL | match Color::Red { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `[Second(true), Second(false)]` not covered - --> $DIR/non-exhaustive-pattern-witness.rs:72:11 + --> $DIR/non-exhaustive-pattern-witness.rs:70:11 | LL | match *x { | ^^ pattern `[Second(true), Second(false)]` not covered @@ -83,7 +83,7 @@ LL | match *x { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `((), false)` not covered - --> $DIR/non-exhaustive-pattern-witness.rs:85:11 + --> $DIR/non-exhaustive-pattern-witness.rs:83:11 | LL | match ((), false) { | ^^^^^^^^^^^ pattern `((), false)` not covered diff --git a/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.rs b/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.rs index 41ba2cc4501c0..52d1320dad153 100644 --- a/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.rs +++ b/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - fn main() { let s: &[bool] = &[true; 0]; let s1: &[bool; 1] = &[false; 1]; diff --git a/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr b/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr index 8cb342f33dfa0..b3701efef3de2 100644 --- a/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr +++ b/src/test/ui/pattern/usefulness/slice-patterns-exhaustiveness.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `&[false, _]` not covered - --> $DIR/slice-patterns-exhaustiveness.rs:10:11 + --> $DIR/slice-patterns-exhaustiveness.rs:8:11 | LL | match s2 { | ^^ pattern `&[false, _]` not covered @@ -7,7 +7,7 @@ LL | match s2 { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[false, ..]` not covered - --> $DIR/slice-patterns-exhaustiveness.rs:14:11 + --> $DIR/slice-patterns-exhaustiveness.rs:12:11 | LL | match s3 { | ^^ pattern `&[false, ..]` not covered @@ -15,7 +15,7 @@ LL | match s3 { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[false, ..]` not covered - --> $DIR/slice-patterns-exhaustiveness.rs:18:11 + --> $DIR/slice-patterns-exhaustiveness.rs:16:11 | LL | match s10 { | ^^^ pattern `&[false, ..]` not covered @@ -23,7 +23,7 @@ LL | match s10 { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[false, true]` not covered - --> $DIR/slice-patterns-exhaustiveness.rs:27:11 + --> $DIR/slice-patterns-exhaustiveness.rs:25:11 | LL | match s2 { | ^^ pattern `&[false, true]` not covered @@ -31,7 +31,7 @@ LL | match s2 { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[false, .., true]` not covered - --> $DIR/slice-patterns-exhaustiveness.rs:32:11 + --> $DIR/slice-patterns-exhaustiveness.rs:30:11 | LL | match s3 { | ^^ pattern `&[false, .., true]` not covered @@ -39,7 +39,7 @@ LL | match s3 { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[false, .., true]` not covered - --> $DIR/slice-patterns-exhaustiveness.rs:37:11 + --> $DIR/slice-patterns-exhaustiveness.rs:35:11 | LL | match s { | ^ pattern `&[false, .., true]` not covered @@ -47,7 +47,7 @@ LL | match s { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered - --> $DIR/slice-patterns-exhaustiveness.rs:44:11 + --> $DIR/slice-patterns-exhaustiveness.rs:42:11 | LL | match s { | ^ pattern `&[_, ..]` not covered @@ -55,7 +55,7 @@ LL | match s { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[_, _, ..]` not covered - --> $DIR/slice-patterns-exhaustiveness.rs:48:11 + --> $DIR/slice-patterns-exhaustiveness.rs:46:11 | LL | match s { | ^ pattern `&[_, _, ..]` not covered @@ -63,7 +63,7 @@ LL | match s { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[false, ..]` not covered - --> $DIR/slice-patterns-exhaustiveness.rs:53:11 + --> $DIR/slice-patterns-exhaustiveness.rs:51:11 | LL | match s { | ^ pattern `&[false, ..]` not covered @@ -71,7 +71,7 @@ LL | match s { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[false, _, ..]` not covered - --> $DIR/slice-patterns-exhaustiveness.rs:58:11 + --> $DIR/slice-patterns-exhaustiveness.rs:56:11 | LL | match s { | ^ pattern `&[false, _, ..]` not covered @@ -79,7 +79,7 @@ LL | match s { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[_, .., false]` not covered - --> $DIR/slice-patterns-exhaustiveness.rs:64:11 + --> $DIR/slice-patterns-exhaustiveness.rs:62:11 | LL | match s { | ^ pattern `&[_, .., false]` not covered @@ -87,7 +87,7 @@ LL | match s { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[_, _, .., true]` not covered - --> $DIR/slice-patterns-exhaustiveness.rs:71:11 + --> $DIR/slice-patterns-exhaustiveness.rs:69:11 | LL | match s { | ^ pattern `&[_, _, .., true]` not covered @@ -95,7 +95,7 @@ LL | match s { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[true, _, .., _]` not covered - --> $DIR/slice-patterns-exhaustiveness.rs:78:11 + --> $DIR/slice-patterns-exhaustiveness.rs:76:11 | LL | match s { | ^ pattern `&[true, _, .., _]` not covered @@ -103,7 +103,7 @@ LL | match s { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[..]` not covered - --> $DIR/slice-patterns-exhaustiveness.rs:87:11 + --> $DIR/slice-patterns-exhaustiveness.rs:85:11 | LL | match s { | ^ pattern `&[..]` not covered @@ -111,7 +111,7 @@ LL | match s { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[true]` not covered - --> $DIR/slice-patterns-exhaustiveness.rs:91:11 + --> $DIR/slice-patterns-exhaustiveness.rs:89:11 | LL | match s { | ^ pattern `&[true]` not covered @@ -119,7 +119,7 @@ LL | match s { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms error[E0004]: non-exhaustive patterns: `&[false]` not covered - --> $DIR/slice-patterns-exhaustiveness.rs:99:11 + --> $DIR/slice-patterns-exhaustiveness.rs:97:11 | LL | match s1 { | ^^ pattern `&[false]` not covered diff --git a/src/test/ui/pattern/usefulness/slice-patterns-irrefutable.rs b/src/test/ui/pattern/usefulness/slice-patterns-irrefutable.rs index 3b716bae77209..cbf64e2c53d02 100644 --- a/src/test/ui/pattern/usefulness/slice-patterns-irrefutable.rs +++ b/src/test/ui/pattern/usefulness/slice-patterns-irrefutable.rs @@ -1,5 +1,4 @@ // check-pass -#![feature(slice_patterns)] fn main() { let s: &[bool] = &[true; 0]; diff --git a/src/test/ui/pattern/usefulness/slice-patterns-reachability.rs b/src/test/ui/pattern/usefulness/slice-patterns-reachability.rs index cd229a0fcbee4..7c747b5e0b9d3 100644 --- a/src/test/ui/pattern/usefulness/slice-patterns-reachability.rs +++ b/src/test/ui/pattern/usefulness/slice-patterns-reachability.rs @@ -1,4 +1,3 @@ -#![feature(slice_patterns)] #![deny(unreachable_patterns)] fn main() { diff --git a/src/test/ui/pattern/usefulness/slice-patterns-reachability.stderr b/src/test/ui/pattern/usefulness/slice-patterns-reachability.stderr index 333ce170283ea..e24d10281170d 100644 --- a/src/test/ui/pattern/usefulness/slice-patterns-reachability.stderr +++ b/src/test/ui/pattern/usefulness/slice-patterns-reachability.stderr @@ -1,41 +1,41 @@ error: unreachable pattern - --> $DIR/slice-patterns-reachability.rs:9:9 + --> $DIR/slice-patterns-reachability.rs:8:9 | LL | [true, ..] => {} | ^^^^^^^^^^ | note: lint level defined here - --> $DIR/slice-patterns-reachability.rs:2:9 + --> $DIR/slice-patterns-reachability.rs:1:9 | LL | #![deny(unreachable_patterns)] | ^^^^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/slice-patterns-reachability.rs:10:9 + --> $DIR/slice-patterns-reachability.rs:9:9 | LL | [true] => {} | ^^^^^^ error: unreachable pattern - --> $DIR/slice-patterns-reachability.rs:15:9 + --> $DIR/slice-patterns-reachability.rs:14:9 | LL | [.., true] => {} | ^^^^^^^^^^ error: unreachable pattern - --> $DIR/slice-patterns-reachability.rs:16:9 + --> $DIR/slice-patterns-reachability.rs:15:9 | LL | [true] => {} | ^^^^^^ error: unreachable pattern - --> $DIR/slice-patterns-reachability.rs:21:9 + --> $DIR/slice-patterns-reachability.rs:20:9 | LL | [false, .., true] => {} | ^^^^^^^^^^^^^^^^^ error: unreachable pattern - --> $DIR/slice-patterns-reachability.rs:22:9 + --> $DIR/slice-patterns-reachability.rs:21:9 | LL | [false, true] => {} | ^^^^^^^^^^^^^ diff --git a/src/test/ui/rfc-2005-default-binding-mode/slice.rs b/src/test/ui/rfc-2005-default-binding-mode/slice.rs index 1484b8c4a1f13..363a0e3e649d9 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/slice.rs +++ b/src/test/ui/rfc-2005-default-binding-mode/slice.rs @@ -1,5 +1,3 @@ -#![feature(slice_patterns)] - pub fn main() { let sl: &[u8] = b"foo"; diff --git a/src/test/ui/rfc-2005-default-binding-mode/slice.stderr b/src/test/ui/rfc-2005-default-binding-mode/slice.stderr index f1e91a05f082f..c234fdf46ed2d 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/slice.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/slice.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `&[]` not covered - --> $DIR/slice.rs:6:11 + --> $DIR/slice.rs:4:11 | LL | match sl { | ^^ pattern `&[]` not covered diff --git a/src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs b/src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs index 38b0941aad0a6..33229a205f4d8 100644 --- a/src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs +++ b/src/test/ui/rfcs/rfc-2005-default-binding-mode/slice.rs @@ -1,5 +1,4 @@ // run-pass -#![feature(slice_patterns)] fn slice_pat() { let sl: &[u8] = b"foo"; diff --git a/src/test/ui/trailing-comma.rs b/src/test/ui/trailing-comma.rs index 929c35a9e1122..97006ae50a0bf 100644 --- a/src/test/ui/trailing-comma.rs +++ b/src/test/ui/trailing-comma.rs @@ -1,8 +1,6 @@ // run-pass // pretty-expanded FIXME #23616 -#![feature(slice_patterns)] - fn f(_: T,) {} struct Foo(T); diff --git a/src/test/ui/uninhabited/uninhabited-patterns.rs b/src/test/ui/uninhabited/uninhabited-patterns.rs index 1bf01184a08e7..58c726d2185c4 100644 --- a/src/test/ui/uninhabited/uninhabited-patterns.rs +++ b/src/test/ui/uninhabited/uninhabited-patterns.rs @@ -2,7 +2,7 @@ #![feature(box_syntax)] #![feature(never_type)] #![feature(exhaustive_patterns)] -#![feature(slice_patterns)] + #![deny(unreachable_patterns)] mod foo { From e3c2f8fc57e718f4ba1d7f52405eb2c1cb434559 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 30 Dec 2019 01:37:14 +0100 Subject: [PATCH 164/169] slice_patterns: organize some tests --- .../slice-pat-type-mismatches.rs} | 0 .../slice-pat-type-mismatches.stderr} | 10 +++++----- .../subslice-only-once-semantic-restriction.rs} | 0 .../subslice-only-once-semantic-restriction.stderr} | 6 +++--- .../issue-53820-slice-pattern-large-array.rs | 2 +- ...issue-65413-constants-and-slices-exhaustiveness.rs} | 0 6 files changed, 9 insertions(+), 9 deletions(-) rename src/test/ui/{match/match-vec-mismatch.rs => array-slice-vec/slice-pat-type-mismatches.rs} (100%) rename src/test/ui/{match/match-vec-mismatch.stderr => array-slice-vec/slice-pat-type-mismatches.stderr} (81%) rename src/test/ui/{parser/match-vec-invalid.rs => array-slice-vec/subslice-only-once-semantic-restriction.rs} (100%) rename src/test/ui/{parser/match-vec-invalid.stderr => array-slice-vec/subslice-only-once-semantic-restriction.stderr} (80%) rename src/test/ui/pattern/{ => usefulness}/issue-53820-slice-pattern-large-array.rs (65%) rename src/test/ui/pattern/usefulness/{65413-constants-and-slices-exhaustiveness.rs => issue-65413-constants-and-slices-exhaustiveness.rs} (100%) diff --git a/src/test/ui/match/match-vec-mismatch.rs b/src/test/ui/array-slice-vec/slice-pat-type-mismatches.rs similarity index 100% rename from src/test/ui/match/match-vec-mismatch.rs rename to src/test/ui/array-slice-vec/slice-pat-type-mismatches.rs diff --git a/src/test/ui/match/match-vec-mismatch.stderr b/src/test/ui/array-slice-vec/slice-pat-type-mismatches.stderr similarity index 81% rename from src/test/ui/match/match-vec-mismatch.stderr rename to src/test/ui/array-slice-vec/slice-pat-type-mismatches.stderr index 4b0e429e51ca5..c4548142c13ef 100644 --- a/src/test/ui/match/match-vec-mismatch.stderr +++ b/src/test/ui/array-slice-vec/slice-pat-type-mismatches.stderr @@ -1,29 +1,29 @@ error[E0425]: cannot find value `does_not_exist` in this scope - --> $DIR/match-vec-mismatch.rs:26:11 + --> $DIR/slice-pat-type-mismatches.rs:26:11 | LL | match does_not_exist { | ^^^^^^^^^^^^^^ not found in this scope error[E0529]: expected an array or slice, found `std::string::String` - --> $DIR/match-vec-mismatch.rs:3:9 + --> $DIR/slice-pat-type-mismatches.rs:3:9 | LL | ['f', 'o', ..] => {} | ^^^^^^^^^^^^^^ pattern cannot match with input type `std::string::String` error[E0527]: pattern requires 1 element but array has 3 - --> $DIR/match-vec-mismatch.rs:18:9 + --> $DIR/slice-pat-type-mismatches.rs:18:9 | LL | [0] => {}, | ^^^ expected 3 elements error[E0528]: pattern requires at least 4 elements but array has 3 - --> $DIR/match-vec-mismatch.rs:23:9 + --> $DIR/slice-pat-type-mismatches.rs:23:9 | LL | [0, 1, 2, 3, x @ ..] => {} | ^^^^^^^^^^^^^^^^^^^^ pattern cannot match array of 3 elements error[E0282]: type annotations needed - --> $DIR/match-vec-mismatch.rs:34:9 + --> $DIR/slice-pat-type-mismatches.rs:34:9 | LL | [] => {} | ^^ cannot infer type diff --git a/src/test/ui/parser/match-vec-invalid.rs b/src/test/ui/array-slice-vec/subslice-only-once-semantic-restriction.rs similarity index 100% rename from src/test/ui/parser/match-vec-invalid.rs rename to src/test/ui/array-slice-vec/subslice-only-once-semantic-restriction.rs diff --git a/src/test/ui/parser/match-vec-invalid.stderr b/src/test/ui/array-slice-vec/subslice-only-once-semantic-restriction.stderr similarity index 80% rename from src/test/ui/parser/match-vec-invalid.stderr rename to src/test/ui/array-slice-vec/subslice-only-once-semantic-restriction.stderr index 1dc11c31905c4..4d6078788b228 100644 --- a/src/test/ui/parser/match-vec-invalid.stderr +++ b/src/test/ui/array-slice-vec/subslice-only-once-semantic-restriction.stderr @@ -1,11 +1,11 @@ error[E0416]: identifier `tail` is bound more than once in the same pattern - --> $DIR/match-vec-invalid.rs:4:24 + --> $DIR/subslice-only-once-semantic-restriction.rs:4:24 | LL | [1, tail @ .., tail @ ..] => {}, | ^^^^ used in a pattern more than once error: `..` can only be used once per slice pattern - --> $DIR/match-vec-invalid.rs:4:31 + --> $DIR/subslice-only-once-semantic-restriction.rs:4:31 | LL | [1, tail @ .., tail @ ..] => {}, | -- ^^ can only be used once per slice pattern @@ -13,7 +13,7 @@ LL | [1, tail @ .., tail @ ..] => {}, | previously used here error[E0308]: mismatched types - --> $DIR/match-vec-invalid.rs:11:30 + --> $DIR/subslice-only-once-semantic-restriction.rs:11:30 | LL | const RECOVERY_WITNESS: () = 0; | ^ expected `()`, found integer diff --git a/src/test/ui/pattern/issue-53820-slice-pattern-large-array.rs b/src/test/ui/pattern/usefulness/issue-53820-slice-pattern-large-array.rs similarity index 65% rename from src/test/ui/pattern/issue-53820-slice-pattern-large-array.rs rename to src/test/ui/pattern/usefulness/issue-53820-slice-pattern-large-array.rs index 1249329206112..5b0482de2200e 100644 --- a/src/test/ui/pattern/issue-53820-slice-pattern-large-array.rs +++ b/src/test/ui/pattern/usefulness/issue-53820-slice-pattern-large-array.rs @@ -1,6 +1,6 @@ // check-pass -// This used to cause a stack overflow in the compiler. +// This used to cause a stack overflow during exhaustiveness checking in the compiler. fn main() { const LARGE_SIZE: usize = 1024 * 1024; diff --git a/src/test/ui/pattern/usefulness/65413-constants-and-slices-exhaustiveness.rs b/src/test/ui/pattern/usefulness/issue-65413-constants-and-slices-exhaustiveness.rs similarity index 100% rename from src/test/ui/pattern/usefulness/65413-constants-and-slices-exhaustiveness.rs rename to src/test/ui/pattern/usefulness/issue-65413-constants-and-slices-exhaustiveness.rs From 120e98c3c7d28b1667576d0fa32fa94751968699 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Mon, 30 Dec 2019 01:53:22 +0100 Subject: [PATCH 165/169] slice_patterns: remove from unstable book --- .../src/language-features/slice-patterns.md | 32 ------------------- 1 file changed, 32 deletions(-) delete mode 100644 src/doc/unstable-book/src/language-features/slice-patterns.md diff --git a/src/doc/unstable-book/src/language-features/slice-patterns.md b/src/doc/unstable-book/src/language-features/slice-patterns.md deleted file mode 100644 index cdb74495884a8..0000000000000 --- a/src/doc/unstable-book/src/language-features/slice-patterns.md +++ /dev/null @@ -1,32 +0,0 @@ -# `slice_patterns` - -The tracking issue for this feature is: [#62254] - -[#62254]: https://github.com/rust-lang/rust/issues/62254 - ------------------------- - -The `slice_patterns` feature gate lets you use `..` to indicate any number of -elements inside a pattern matching a slice. This wildcard can only be used once -for a given array. If there's an pattern before the `..`, the subslice will be -matched against that pattern. For example: - -```rust -#![feature(slice_patterns)] - -fn is_symmetric(list: &[u32]) -> bool { - match list { - &[] | &[_] => true, - &[x, ref inside @ .., y] if x == y => is_symmetric(inside), - &[..] => false, - } -} - -fn main() { - let sym = &[0, 1, 4, 2, 4, 1, 0]; - assert!(is_symmetric(sym)); - - let not_sym = &[0, 1, 7, 2, 4, 1, 0]; - assert!(!is_symmetric(not_sym)); -} -``` From 57b6843100b247b6065b71e4485572dda4bfccc6 Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Thu, 2 Jan 2020 22:18:34 +0100 Subject: [PATCH 166/169] slice_patterns: address review comments --- .../ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs | 1 - src/test/ui/ignore-all-the-things.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs index 1c9c052970f9a..4367596c6ea88 100644 --- a/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs +++ b/src/test/ui/borrowck/borrowck-slice-pattern-element-loan-rpass.rs @@ -1,5 +1,4 @@ // run-pass -// compile-flags: -Z borrowck=mir fn mut_head_tail<'a, A>(v: &'a mut [A]) -> Option<(&'a mut A, &'a mut [A])> { match *v { diff --git a/src/test/ui/ignore-all-the-things.rs b/src/test/ui/ignore-all-the-things.rs index ab90a69ce6f06..5980e1a857f26 100644 --- a/src/test/ui/ignore-all-the-things.rs +++ b/src/test/ui/ignore-all-the-things.rs @@ -1,5 +1,4 @@ // run-pass -// pretty-expanded FIXME #23616 #![allow(non_shorthand_field_patterns)] #![allow(dead_code)] From e1f70f77bf7aae099453d54a1175d8453ce4f5cb Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Sat, 18 Jan 2020 18:44:05 -0500 Subject: [PATCH 167/169] [const-prop] Remove useless typedef It's confusing because it conflicts with ty::Const and just isn't generally useful. --- src/librustc_mir/transform/const_prop.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 3afc7290ca9c8..2fd59f3ee1944 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -288,8 +288,6 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine { } } -type Const<'tcx> = OpTy<'tcx>; - /// Finds optimization opportunities on the MIR. struct ConstPropagator<'mir, 'tcx> { ecx: InterpCx<'mir, 'tcx, ConstPropMachine>, @@ -387,7 +385,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { } } - fn get_const(&self, local: Local) -> Option> { + fn get_const(&self, local: Local) -> Option> { if local == RETURN_PLACE { // Try to read the return place as an immediate so that if it is representable as a // scalar, we can handle it as such, but otherwise, just return the value as is. @@ -470,7 +468,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { &mut self, c: &Constant<'tcx>, source_info: SourceInfo, - ) -> Option> { + ) -> Option> { self.ecx.tcx.span = c.span; // FIXME we need to revisit this for #67176 @@ -510,12 +508,12 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { } } - fn eval_place(&mut self, place: &Place<'tcx>, source_info: SourceInfo) -> Option> { + fn eval_place(&mut self, place: &Place<'tcx>, source_info: SourceInfo) -> Option> { trace!("eval_place(place={:?})", place); self.use_ecx(source_info, |this| this.ecx.eval_place_to_op(place, None)) } - fn eval_operand(&mut self, op: &Operand<'tcx>, source_info: SourceInfo) -> Option> { + fn eval_operand(&mut self, op: &Operand<'tcx>, source_info: SourceInfo) -> Option> { match *op { Operand::Constant(ref c) => self.eval_constant(c, source_info), Operand::Move(ref place) | Operand::Copy(ref place) => { @@ -664,7 +662,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { fn replace_with_const( &mut self, rval: &mut Rvalue<'tcx>, - value: Const<'tcx>, + value: OpTy<'tcx>, source_info: SourceInfo, ) { trace!("attepting to replace {:?} with {:?}", rval, value); From a957f0d7ff2c6389ec94f921d9ba4e9fade26a72 Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Sat, 18 Jan 2020 18:44:22 -0500 Subject: [PATCH 168/169] [const-prop] Run `x.py fmt` --- src/librustc_mir/transform/const_prop.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 2fd59f3ee1944..bd398c6e5b449 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -464,11 +464,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { r } - fn eval_constant( - &mut self, - c: &Constant<'tcx>, - source_info: SourceInfo, - ) -> Option> { + fn eval_constant(&mut self, c: &Constant<'tcx>, source_info: SourceInfo) -> Option> { self.ecx.tcx.span = c.span; // FIXME we need to revisit this for #67176 From 188f0bbe7fa2f64b6436e3e552320a1de1a00f92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= Date: Sun, 19 Jan 2020 14:01:52 +0100 Subject: [PATCH 169/169] submodules: update clippy from a8d90f6a to fd0428f6 Changes: ```` Treat more strange pattern Split up `if_same_then_else` ui test Apply review comments Run `update_lints` Reduce span range Rename `ok_if_let` to `if_let_some_result` Apply review comments Add suggestion in `if_let_some_result` rustup https://github.com/rust-lang/rust/pull/67712 Allow `unused_self` lint at the function level Downgrade range_plus_one to pedantic Rustup to rust-lang/rust#68204 Add lifetimes to `LateLintPass` Fix rustc lint import paths generated by `new_lint` Add lint for default lint description Update documentation for adding new lints Generate new lints easily Split up `booleans` ui test Fix the ordering on `nonminimal_bool` ```` --- src/tools/clippy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/clippy b/src/tools/clippy index a8d90f6a57925..fd0428f622fee 160000 --- a/src/tools/clippy +++ b/src/tools/clippy @@ -1 +1 @@ -Subproject commit a8d90f6a57925d204efb21b3f6d9726d6674f9bd +Subproject commit fd0428f622feee209e6014b802f5717d48d9e978