From 39eb1482318ffd59461a88e27625a4cdcc9a5f47 Mon Sep 17 00:00:00 2001 From: Matt Fellenz Date: Tue, 28 Jun 2022 17:01:37 -0700 Subject: [PATCH 001/346] Follow C-RW-VALUE in std::io::Cursor example --- library/std/src/io/cursor.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/io/cursor.rs b/library/std/src/io/cursor.rs index f3fbfc44789..570c2a5f0cd 100644 --- a/library/std/src/io/cursor.rs +++ b/library/std/src/io/cursor.rs @@ -34,7 +34,7 @@ use crate::io::{self, ErrorKind, IoSlice, IoSliceMut, ReadBuf, SeekFrom}; /// use std::fs::File; /// /// // a library function we've written -/// fn write_ten_bytes_at_end(writer: &mut W) -> io::Result<()> { +/// fn write_ten_bytes_at_end(mut writer: W) -> io::Result<()> { /// writer.seek(SeekFrom::End(-10))?; /// /// for i in 0..10 { From 22a456ad47f42179268165b009e8925a84d4c43f Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 29 May 2022 13:21:36 +0900 Subject: [PATCH 002/346] Stabilize `nonnull_slice_from_raw_parts` --- library/alloc/src/lib.rs | 1 - library/alloc/tests/lib.rs | 3 +-- library/core/src/ptr/non_null.rs | 13 +++++-------- library/std/src/lib.rs | 1 - 4 files changed, 6 insertions(+), 12 deletions(-) diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 7fde8f670a2..1020c5f97a8 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -129,7 +129,6 @@ #![feature(maybe_uninit_slice)] #![feature(maybe_uninit_uninit_array)] #![cfg_attr(test, feature(new_uninit))] -#![feature(nonnull_slice_from_raw_parts)] #![feature(pattern)] #![feature(pointer_byte_offsets)] #![feature(provide_any)] diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs index f30ebd77e24..4811fedfb96 100644 --- a/library/alloc/tests/lib.rs +++ b/library/alloc/tests/lib.rs @@ -8,7 +8,7 @@ #![feature(const_cow_is_borrowed)] #![feature(const_heap)] #![feature(const_mut_refs)] -#![feature(const_nonnull_slice_from_raw_parts)] +#![feature(const_slice_from_raw_parts_mut)] #![feature(const_ptr_write)] #![feature(const_try)] #![feature(core_intrinsics)] @@ -36,7 +36,6 @@ #![feature(const_default_impls)] #![feature(const_trait_impl)] #![feature(const_str_from_utf8)] -#![feature(nonnull_slice_from_raw_parts)] #![feature(panic_update_hook)] #![feature(pointer_is_aligned)] #![feature(slice_flatten)] diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs index f3ef094cbcc..4814ccfd10f 100644 --- a/library/core/src/ptr/non_null.rs +++ b/library/core/src/ptr/non_null.rs @@ -467,8 +467,6 @@ impl NonNull<[T]> { /// # Examples /// /// ```rust - /// #![feature(nonnull_slice_from_raw_parts)] - /// /// use std::ptr::NonNull; /// /// // create a slice pointer when starting out with a pointer to the first element @@ -480,8 +478,8 @@ impl NonNull<[T]> { /// /// (Note that this example artificially demonstrates a use of this method, /// but `let slice = NonNull::from(&x[..]);` would be a better way to write code like this.) - #[unstable(feature = "nonnull_slice_from_raw_parts", issue = "71941")] - #[rustc_const_unstable(feature = "const_nonnull_slice_from_raw_parts", issue = "71941")] + #[stable(feature = "nonnull_slice_from_raw_parts", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_unstable(feature = "const_slice_from_raw_parts_mut", issue = "67456")] #[must_use] #[inline] pub const fn slice_from_raw_parts(data: NonNull, len: usize) -> Self { @@ -499,7 +497,6 @@ impl NonNull<[T]> { /// # Examples /// /// ```rust - /// #![feature(nonnull_slice_from_raw_parts)] /// use std::ptr::NonNull; /// /// let slice: NonNull<[i8]> = NonNull::slice_from_raw_parts(NonNull::dangling(), 3); @@ -519,7 +516,7 @@ impl NonNull<[T]> { /// # Examples /// /// ```rust - /// #![feature(slice_ptr_get, nonnull_slice_from_raw_parts)] + /// #![feature(slice_ptr_get)] /// use std::ptr::NonNull; /// /// let slice: NonNull<[i8]> = NonNull::slice_from_raw_parts(NonNull::dangling(), 3); @@ -539,7 +536,7 @@ impl NonNull<[T]> { /// # Examples /// /// ```rust - /// #![feature(slice_ptr_get, nonnull_slice_from_raw_parts)] + /// #![feature(slice_ptr_get)] /// use std::ptr::NonNull; /// /// let slice: NonNull<[i8]> = NonNull::slice_from_raw_parts(NonNull::dangling(), 3); @@ -673,7 +670,7 @@ impl NonNull<[T]> { /// # Examples /// /// ``` - /// #![feature(slice_ptr_get, nonnull_slice_from_raw_parts)] + /// #![feature(slice_ptr_get)] /// use std::ptr::NonNull; /// /// let x = &mut [1, 2, 4]; diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 64b62fd3bba..439fd93cb97 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -294,7 +294,6 @@ #![feature(is_some_with)] #![feature(maybe_uninit_slice)] #![feature(maybe_uninit_write_slice)] -#![feature(nonnull_slice_from_raw_parts)] #![feature(panic_can_unwind)] #![feature(panic_info_message)] #![feature(panic_internals)] From 57e12f970cd97c65a7d1ce97989a778ffa102584 Mon Sep 17 00:00:00 2001 From: LegionMammal978 Date: Wed, 30 Nov 2022 13:46:11 -0500 Subject: [PATCH 003/346] Clarify that copied allocators must behave the same --- library/core/src/alloc/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/core/src/alloc/mod.rs b/library/core/src/alloc/mod.rs index a6082455fac..ff390322d55 100644 --- a/library/core/src/alloc/mod.rs +++ b/library/core/src/alloc/mod.rs @@ -95,10 +95,10 @@ impl fmt::Display for AllocError { /// # Safety /// /// * Memory blocks returned from an allocator must point to valid memory and retain their validity -/// until the instance and all of its clones are dropped, +/// until the instance and all of its copies and clones are dropped, /// -/// * cloning or moving the allocator must not invalidate memory blocks returned from this -/// allocator. A cloned allocator must behave like the same allocator, and +/// * copying, cloning, or moving the allocator must not invalidate memory blocks returned from this +/// allocator. A copied or cloned allocator must behave like the same allocator, and /// /// * any pointer to a memory block which is [*currently allocated*] may be passed to any other /// method of the allocator. From 094365e23c633c09f37d72cb345596cecf541f63 Mon Sep 17 00:00:00 2001 From: soc Date: Wed, 15 Feb 2023 18:57:00 +0000 Subject: [PATCH 004/346] Drop unstable `Option::contains`, `Result::contains`, `Result::contains_err` --- library/core/src/option.rs | 30 ------------------ library/core/src/result.rs | 62 -------------------------------------- 2 files changed, 92 deletions(-) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 5d5e9559034..9dfaf81b00c 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -1649,36 +1649,6 @@ impl Option { mem::replace(self, Some(value)) } - /// Returns `true` if the option is a [`Some`] value containing the given value. - /// - /// # Examples - /// - /// ``` - /// #![feature(option_result_contains)] - /// - /// let x: Option = Some(2); - /// assert_eq!(x.contains(&2), true); - /// - /// let x: Option = Some(3); - /// assert_eq!(x.contains(&2), false); - /// - /// let x: Option = None; - /// assert_eq!(x.contains(&2), false); - /// ``` - #[must_use] - #[inline] - #[unstable(feature = "option_result_contains", issue = "62358")] - #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] - pub const fn contains(&self, x: &U) -> bool - where - U: ~const PartialEq, - { - match self { - Some(y) => x.eq(y), - None => false, - } - } - /// Zips `self` with another `Option`. /// /// If `self` is `Some(s)` and `other` is `Some(o)`, this method returns `Some((s, o))`. diff --git a/library/core/src/result.rs b/library/core/src/result.rs index 7596e9cc005..fe89ccd749c 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -1567,68 +1567,6 @@ impl Result { Err(e) => e, } } - - ///////////////////////////////////////////////////////////////////////// - // Misc or niche - ///////////////////////////////////////////////////////////////////////// - - /// Returns `true` if the result is an [`Ok`] value containing the given value. - /// - /// # Examples - /// - /// ``` - /// #![feature(option_result_contains)] - /// - /// let x: Result = Ok(2); - /// assert_eq!(x.contains(&2), true); - /// - /// let x: Result = Ok(3); - /// assert_eq!(x.contains(&2), false); - /// - /// let x: Result = Err("Some error message"); - /// assert_eq!(x.contains(&2), false); - /// ``` - #[must_use] - #[inline] - #[unstable(feature = "option_result_contains", issue = "62358")] - pub fn contains(&self, x: &U) -> bool - where - U: PartialEq, - { - match self { - Ok(y) => x == y, - Err(_) => false, - } - } - - /// Returns `true` if the result is an [`Err`] value containing the given value. - /// - /// # Examples - /// - /// ``` - /// #![feature(result_contains_err)] - /// - /// let x: Result = Ok(2); - /// assert_eq!(x.contains_err(&"Some error message"), false); - /// - /// let x: Result = Err("Some error message"); - /// assert_eq!(x.contains_err(&"Some error message"), true); - /// - /// let x: Result = Err("Some other error message"); - /// assert_eq!(x.contains_err(&"Some error message"), false); - /// ``` - #[must_use] - #[inline] - #[unstable(feature = "result_contains_err", issue = "62358")] - pub fn contains_err(&self, f: &F) -> bool - where - F: PartialEq, - { - match self { - Ok(_) => false, - Err(e) => f == e, - } - } } impl Result<&T, E> { From 3aa9f76a3a27e901e478203e00d17fe26a645c66 Mon Sep 17 00:00:00 2001 From: soc Date: Wed, 15 Feb 2023 19:30:02 +0000 Subject: [PATCH 005/346] Remove `#![feature(option_result_contains)]` from library/core/tests/lib.rs --- library/core/tests/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 42a26ae1675..769ce764690 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -87,7 +87,6 @@ #![feature(portable_simd)] #![feature(ptr_metadata)] #![feature(once_cell)] -#![feature(option_result_contains)] #![feature(unsized_tuple_coercion)] #![feature(const_option)] #![feature(const_option_ext)] From 11c589c04661bff6f4cd7df734d1ac7b97bbd9e0 Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Sat, 25 Feb 2023 16:59:32 +0900 Subject: [PATCH 006/346] binary_heap: Make RebuildOnDrop a common helper. This helper was written for retain() but will also be useful for extend(). --- .../alloc/src/collections/binary_heap/mod.rs | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs index f1d0a305d99..b6cb7913d90 100644 --- a/library/alloc/src/collections/binary_heap/mod.rs +++ b/library/alloc/src/collections/binary_heap/mod.rs @@ -400,6 +400,17 @@ impl fmt::Debug for BinaryHeap { } } +struct RebuildOnDrop<'a, T: Ord> { + heap: &'a mut BinaryHeap, + rebuild_from: usize, +} + +impl<'a, T: Ord> Drop for RebuildOnDrop<'a, T> { + fn drop(&mut self) { + self.heap.rebuild_tail(self.rebuild_from); + } +} + impl BinaryHeap { /// Creates an empty `BinaryHeap` as a max-heap. /// @@ -851,30 +862,19 @@ impl BinaryHeap { where F: FnMut(&T) -> bool, { - struct RebuildOnDrop<'a, T: Ord> { - heap: &'a mut BinaryHeap, - first_removed: usize, - } - - let mut guard = RebuildOnDrop { first_removed: self.len(), heap: self }; - + // rebuild_start will be updated to the first touched element below, and the rebuild will + // only be done for the tail. + let mut guard = RebuildOnDrop { rebuild_from: self.len(), heap: self }; let mut i = 0; + guard.heap.data.retain(|e| { let keep = f(e); - if !keep && i < guard.first_removed { - guard.first_removed = i; + if !keep && i < guard.rebuild_from { + guard.rebuild_from = i; } i += 1; keep }); - - impl<'a, T: Ord> Drop for RebuildOnDrop<'a, T> { - fn drop(&mut self) { - // data[..first_removed] is untouched, so we only need to - // rebuild the tail: - self.heap.rebuild_tail(self.first_removed); - } - } } } From 116bb4dfb21085ec8e6c45551cc69ff59a3598cd Mon Sep 17 00:00:00 2001 From: Tatsuyuki Ishi Date: Sat, 25 Feb 2023 17:03:03 +0900 Subject: [PATCH 007/346] binary_heap: Unify Extend implementation. Previously the bulk rebuild specialization was only available with Vec, and for general iterators Extend only provided pre-allocation through reserve(). By using a drop guard, we can safely bulk rebuild even if the iterator may panic. This allows benefiting from the bulk rebuild optimization without collecting iterator elements into a Vec beforehand, which would nullify any performance gains from bulk rebuild. --- .../alloc/src/collections/binary_heap/mod.rs | 36 ++----------------- 1 file changed, 2 insertions(+), 34 deletions(-) diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs index b6cb7913d90..7c8cdf6ee3b 100644 --- a/library/alloc/src/collections/binary_heap/mod.rs +++ b/library/alloc/src/collections/binary_heap/mod.rs @@ -154,8 +154,6 @@ use crate::collections::TryReserveError; use crate::slice; use crate::vec::{self, AsVecIntoIter, Vec}; -use super::SpecExtend; - #[cfg(test)] mod tests; @@ -1715,7 +1713,8 @@ impl<'a, T> IntoIterator for &'a BinaryHeap { impl Extend for BinaryHeap { #[inline] fn extend>(&mut self, iter: I) { - >::spec_extend(self, iter); + let guard = RebuildOnDrop { rebuild_from: self.len(), heap: self }; + guard.heap.data.extend(iter); } #[inline] @@ -1729,37 +1728,6 @@ impl Extend for BinaryHeap { } } -impl> SpecExtend for BinaryHeap { - default fn spec_extend(&mut self, iter: I) { - self.extend_desugared(iter.into_iter()); - } -} - -impl SpecExtend> for BinaryHeap { - fn spec_extend(&mut self, ref mut other: Vec) { - let start = self.data.len(); - self.data.append(other); - self.rebuild_tail(start); - } -} - -impl SpecExtend> for BinaryHeap { - fn spec_extend(&mut self, ref mut other: BinaryHeap) { - self.append(other); - } -} - -impl BinaryHeap { - fn extend_desugared>(&mut self, iter: I) { - let iterator = iter.into_iter(); - let (lower, _) = iterator.size_hint(); - - self.reserve(lower); - - iterator.for_each(move |elem| self.push(elem)); - } -} - #[stable(feature = "extend_ref", since = "1.2.0")] impl<'a, T: 'a + Ord + Copy> Extend<&'a T> for BinaryHeap { fn extend>(&mut self, iter: I) { From fdbf109b635d8928b7b47570f2a8f00ec9d39d94 Mon Sep 17 00:00:00 2001 From: joboet Date: Sun, 26 Feb 2023 11:33:28 +0100 Subject: [PATCH 008/346] std: use random HashMap keys on Hermit --- library/std/src/sys/hermit/mod.rs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/hermit/mod.rs b/library/std/src/sys/hermit/mod.rs index d34a4cfedea..d0e09890b8b 100644 --- a/library/std/src/sys/hermit/mod.rs +++ b/library/std/src/sys/hermit/mod.rs @@ -76,9 +76,24 @@ pub fn abort_internal() -> ! { } } -// FIXME: just a workaround to test the system pub fn hashmap_random_keys() -> (u64, u64) { - (1, 2) + let mut buf = [0; 16]; + let mut slice = &mut buf[..]; + while !slice.is_empty() { + let res = unsafe { abi::read_entropy(slice.as_mut_ptr(), slice.len(), 0) }; + if res < 0 { + panic!( + "random key generation failed: {}", + crate::io::Error::from_raw_os_error(-res as i32) + ); + } else { + slice = &mut slice[res as usize..]; + } + } + + let key1 = buf[..8].try_into().unwrap(); + let key2 = buf[8..].try_into().unwrap(); + (u64::from_ne_bytes(key1), u64::from_ne_bytes(key2)) } // This function is needed by the panic runtime. The symbol is named in From 003a2119e7ffe70ee341ebc2bde3866783db8d9d Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Mon, 27 Feb 2023 22:01:12 -0500 Subject: [PATCH 009/346] Improve diagnostic of `no_mangle_with_rust_abi` --- clippy_lints/src/no_mangle_with_rust_abi.rs | 28 ++++---- tests/ui/no_mangle_with_rust_abi.fixed | 48 ------------- tests/ui/no_mangle_with_rust_abi.rs | 2 - tests/ui/no_mangle_with_rust_abi.stderr | 74 +++++++++++++++------ 4 files changed, 71 insertions(+), 81 deletions(-) delete mode 100644 tests/ui/no_mangle_with_rust_abi.fixed diff --git a/clippy_lints/src/no_mangle_with_rust_abi.rs b/clippy_lints/src/no_mangle_with_rust_abi.rs index bc64ccb295c..8fd9ae351a0 100644 --- a/clippy_lints/src/no_mangle_with_rust_abi.rs +++ b/clippy_lints/src/no_mangle_with_rust_abi.rs @@ -1,9 +1,10 @@ -use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::snippet_with_applicability; use rustc_errors::Applicability; use rustc_hir::{Item, ItemKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::{BytePos, Pos}; use rustc_target::spec::abi::Abi; declare_clippy_lint! { @@ -38,25 +39,28 @@ impl<'tcx> LateLintPass<'tcx> for NoMangleWithRustAbi { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { if let ItemKind::Fn(fn_sig, _, _) = &item.kind { let attrs = cx.tcx.hir().attrs(item.hir_id()); - let mut applicability = Applicability::MachineApplicable; - let snippet = snippet_with_applicability(cx, fn_sig.span, "..", &mut applicability); + let mut app = Applicability::MaybeIncorrect; + let snippet = snippet_with_applicability(cx, fn_sig.span, "..", &mut app); for attr in attrs { if let Some(ident) = attr.ident() && ident.name == rustc_span::sym::no_mangle && fn_sig.header.abi == Abi::Rust - && !snippet.contains("extern") { + && let Some((fn_attrs, _)) = snippet.split_once("fn") + && !fn_attrs.contains("extern") + { + let sugg_span = fn_sig.span + .with_lo(fn_sig.span.lo() + BytePos::from_usize(fn_attrs.len())) + .shrink_to_lo(); - let suggestion = snippet.split_once("fn") - .map_or(String::new(), |(first, second)| format!(r#"{first}extern "C" fn{second}"#)); - - span_lint_and_sugg( + span_lint_and_then( cx, NO_MANGLE_WITH_RUST_ABI, fn_sig.span, - "attribute #[no_mangle] set on a Rust ABI function", - "try", - suggestion, - applicability + "`#[no_mangle]` set on a function with the default (`Rust`) ABI", + |diag| { + diag.span_suggestion(sugg_span, "set an ABI", "extern \"C\" ", app) + .span_suggestion(sugg_span, "or explicitly set the default", "extern \"Rust\" ", app); + }, ); } } diff --git a/tests/ui/no_mangle_with_rust_abi.fixed b/tests/ui/no_mangle_with_rust_abi.fixed deleted file mode 100644 index d18dec22a8b..00000000000 --- a/tests/ui/no_mangle_with_rust_abi.fixed +++ /dev/null @@ -1,48 +0,0 @@ -// run-rustfix - -#![allow(unused)] -#![warn(clippy::no_mangle_with_rust_abi)] - -#[no_mangle] -extern "C" fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {} - -#[no_mangle] -pub extern "C" fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {} - -/// # Safety -/// This function shouldn't be called unless the horsemen are ready -#[no_mangle] -pub unsafe extern "C" fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {} - -/// # Safety -/// This function shouldn't be called unless the horsemen are ready -#[no_mangle] -unsafe extern "C" fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {} - -#[no_mangle] -extern "C" fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines( - arg_one: u32, - arg_two: usize, -) -> u32 { - 0 -} - -// Must not run on functions that explicitly opt in to Rust ABI with `extern "Rust"` -#[no_mangle] -#[rustfmt::skip] -extern "Rust" fn rust_abi_fn_explicit_opt_in(arg_one: u32, arg_two: usize) {} - -fn rust_abi_fn_again(arg_one: u32, arg_two: usize) {} - -#[no_mangle] -extern "C" fn c_abi_fn(arg_one: u32, arg_two: usize) {} - -extern "C" fn c_abi_fn_again(arg_one: u32, arg_two: usize) {} - -extern "C" { - fn c_abi_in_block(arg_one: u32, arg_two: usize); -} - -fn main() { - // test code goes here -} diff --git a/tests/ui/no_mangle_with_rust_abi.rs b/tests/ui/no_mangle_with_rust_abi.rs index 481e1b6d961..b32e721110e 100644 --- a/tests/ui/no_mangle_with_rust_abi.rs +++ b/tests/ui/no_mangle_with_rust_abi.rs @@ -1,5 +1,3 @@ -// run-rustfix - #![allow(unused)] #![warn(clippy::no_mangle_with_rust_abi)] diff --git a/tests/ui/no_mangle_with_rust_abi.stderr b/tests/ui/no_mangle_with_rust_abi.stderr index 71517d31809..da5d31d8f2d 100644 --- a/tests/ui/no_mangle_with_rust_abi.stderr +++ b/tests/ui/no_mangle_with_rust_abi.stderr @@ -1,31 +1,66 @@ -error: attribute #[no_mangle] set on a Rust ABI function - --> $DIR/no_mangle_with_rust_abi.rs:7:1 +error: `#[no_mangle]` set on a function with the default (`Rust`) ABI + --> $DIR/no_mangle_with_rust_abi.rs:5:1 | LL | fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `extern "C" fn rust_abi_fn_one(arg_one: u32, arg_two: usize)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D clippy::no-mangle-with-rust-abi` implied by `-D warnings` +help: set an ABI + | +LL | extern "C" fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {} + | ++++++++++ +help: or explicitly set the default + | +LL | extern "Rust" fn rust_abi_fn_one(arg_one: u32, arg_two: usize) {} + | +++++++++++++ -error: attribute #[no_mangle] set on a Rust ABI function - --> $DIR/no_mangle_with_rust_abi.rs:10:1 +error: `#[no_mangle]` set on a function with the default (`Rust`) ABI + --> $DIR/no_mangle_with_rust_abi.rs:8:1 | LL | pub fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `pub extern "C" fn rust_abi_fn_two(arg_one: u32, arg_two: usize)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: set an ABI + | +LL | pub extern "C" fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {} + | ++++++++++ +help: or explicitly set the default + | +LL | pub extern "Rust" fn rust_abi_fn_two(arg_one: u32, arg_two: usize) {} + | +++++++++++++ -error: attribute #[no_mangle] set on a Rust ABI function - --> $DIR/no_mangle_with_rust_abi.rs:15:1 +error: `#[no_mangle]` set on a function with the default (`Rust`) ABI + --> $DIR/no_mangle_with_rust_abi.rs:13:1 | LL | pub unsafe fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `pub unsafe extern "C" fn rust_abi_fn_three(arg_one: u32, arg_two: usize)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: set an ABI + | +LL | pub unsafe extern "C" fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {} + | ++++++++++ +help: or explicitly set the default + | +LL | pub unsafe extern "Rust" fn rust_abi_fn_three(arg_one: u32, arg_two: usize) {} + | +++++++++++++ -error: attribute #[no_mangle] set on a Rust ABI function - --> $DIR/no_mangle_with_rust_abi.rs:20:1 +error: `#[no_mangle]` set on a function with the default (`Rust`) ABI + --> $DIR/no_mangle_with_rust_abi.rs:18:1 | LL | unsafe fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `unsafe extern "C" fn rust_abi_fn_four(arg_one: u32, arg_two: usize)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: set an ABI + | +LL | unsafe extern "C" fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {} + | ++++++++++ +help: or explicitly set the default + | +LL | unsafe extern "Rust" fn rust_abi_fn_four(arg_one: u32, arg_two: usize) {} + | +++++++++++++ -error: attribute #[no_mangle] set on a Rust ABI function - --> $DIR/no_mangle_with_rust_abi.rs:23:1 +error: `#[no_mangle]` set on a function with the default (`Rust`) ABI + --> $DIR/no_mangle_with_rust_abi.rs:21:1 | LL | / fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines( LL | | arg_one: u32, @@ -33,13 +68,14 @@ LL | | arg_two: usize, LL | | ) -> u32 { | |________^ | -help: try +help: set an ABI | -LL + extern "C" fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines( -LL + arg_one: u32, -LL + arg_two: usize, -LL ~ ) -> u32 { +LL | extern "C" fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines( + | ++++++++++ +help: or explicitly set the default | +LL | extern "Rust" fn rust_abi_multiline_function_really_long_name_to_overflow_args_to_multiple_lines( + | +++++++++++++ error: aborting due to 5 previous errors From 05c7330ca03650bbcb6a55f5fa490b3bb03c1940 Mon Sep 17 00:00:00 2001 From: The 8472 Date: Sat, 30 Jul 2022 01:48:16 +0200 Subject: [PATCH 010/346] Implement Default for some alloc/core iterators This way one can `mem::take()` them out of structs or #[derive(Default)] on structs containing them. These changes will be insta-stable. --- .../alloc/src/collections/binary_heap/mod.rs | 7 +++ library/alloc/src/collections/btree/map.rs | 56 +++++++++++++++++++ .../alloc/src/collections/btree/map/tests.rs | 16 ++++++ .../alloc/src/collections/btree/navigate.rs | 12 ++++ library/alloc/src/collections/btree/set.rs | 22 ++++++++ library/alloc/src/collections/linked_list.rs | 21 +++++++ .../src/collections/linked_list/tests.rs | 6 ++ library/alloc/src/vec/into_iter.rs | 7 +++ library/alloc/tests/vec.rs | 10 +++- library/core/src/iter/adapters/chain.rs | 11 ++++ library/core/src/iter/adapters/cloned.rs | 11 ++++ library/core/src/iter/adapters/copied.rs | 11 ++++ library/core/src/iter/adapters/enumerate.rs | 10 ++++ library/core/src/iter/adapters/flatten.rs | 11 ++++ library/core/src/iter/adapters/fuse.rs | 7 +++ library/core/src/iter/adapters/rev.rs | 10 ++++ library/core/src/slice/iter/macros.rs | 7 +++ library/core/tests/slice.rs | 10 +++- 18 files changed, 243 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs index f1d0a305d99..b0ec70ad565 100644 --- a/library/alloc/src/collections/binary_heap/mod.rs +++ b/library/alloc/src/collections/binary_heap/mod.rs @@ -1468,6 +1468,13 @@ impl ExactSizeIterator for IntoIter { #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for IntoIter {} +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for IntoIter { + fn default() -> Self { + IntoIter { iter: Default::default() } + } +} + // In addition to the SAFETY invariants of the following three unsafe traits // also refer to the vec::in_place_collect module documentation to get an overview #[unstable(issue = "none", feature = "inplace_iteration")] diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 386cd1a1657..c1e8a84969a 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -362,6 +362,13 @@ impl fmt::Debug for Iter<'_, K, V> { } } +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl<'a, K: 'a, V: 'a> Default for Iter<'a, K, V> { + fn default() -> Self { + Iter { range: Default::default(), length: 0 } + } +} + /// A mutable iterator over the entries of a `BTreeMap`. /// /// This `struct` is created by the [`iter_mut`] method on [`BTreeMap`]. See its @@ -386,6 +393,13 @@ impl fmt::Debug for IterMut<'_, K, V> { } } +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl<'a, K: 'a, V: 'a> Default for IterMut<'a, K, V> { + fn default() -> Self { + IterMut { range: Default::default(), length: 0, _marker: PhantomData {} } + } +} + /// An owning iterator over the entries of a `BTreeMap`. /// /// This `struct` is created by the [`into_iter`] method on [`BTreeMap`] @@ -421,6 +435,13 @@ impl Debug for IntoIter { } } +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for IntoIter { + fn default() -> Self { + IntoIter { range: Default::default(), length: 0, alloc: Global } + } +} + /// An iterator over the keys of a `BTreeMap`. /// /// This `struct` is created by the [`keys`] method on [`BTreeMap`]. See its @@ -1768,6 +1789,13 @@ impl Clone for Keys<'_, K, V> { } } +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for Keys<'_, K, V> { + fn default() -> Self { + Keys { inner: Default::default() } + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl<'a, K, V> Iterator for Values<'a, K, V> { type Item = &'a V; @@ -1809,6 +1837,13 @@ impl Clone for Values<'_, K, V> { } } +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for Values<'_, K, V> { + fn default() -> Self { + Values { inner: Default::default() } + } +} + /// An iterator produced by calling `drain_filter` on BTreeMap. #[unstable(feature = "btree_drain_filter", issue = "70530")] pub struct DrainFilter< @@ -1945,6 +1980,13 @@ impl<'a, K, V> Iterator for Range<'a, K, V> { } } +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for Range<'_, K, V> { + fn default() -> Self { + Range { inner: Default::default() } + } +} + #[stable(feature = "map_values_mut", since = "1.10.0")] impl<'a, K, V> Iterator for ValuesMut<'a, K, V> { type Item = &'a mut V; @@ -2021,6 +2063,13 @@ impl ExactSizeIterator for IntoKeys { #[stable(feature = "map_into_keys_values", since = "1.54.0")] impl FusedIterator for IntoKeys {} +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for IntoKeys { + fn default() -> Self { + IntoKeys { inner: Default::default() } + } +} + #[stable(feature = "map_into_keys_values", since = "1.54.0")] impl Iterator for IntoValues { type Item = V; @@ -2055,6 +2104,13 @@ impl ExactSizeIterator for IntoValues { #[stable(feature = "map_into_keys_values", since = "1.54.0")] impl FusedIterator for IntoValues {} +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for IntoValues { + fn default() -> Self { + IntoValues { inner: Default::default() } + } +} + #[stable(feature = "btree_range", since = "1.17.0")] impl<'a, K, V> DoubleEndedIterator for Range<'a, K, V> { fn next_back(&mut self) -> Option<(&'a K, &'a V)> { diff --git a/library/alloc/src/collections/btree/map/tests.rs b/library/alloc/src/collections/btree/map/tests.rs index 76c2f27b466..4d011195936 100644 --- a/library/alloc/src/collections/btree/map/tests.rs +++ b/library/alloc/src/collections/btree/map/tests.rs @@ -563,6 +563,22 @@ fn test_iter_min_max() { a.check(); } +#[test] +fn test_iters_default() { + let iter: Keys<'_, u8, u8> = Keys::default(); + assert_eq!(iter.len(), 0); + let iter: Values<'_, u8, u8> = Values::default(); + assert_eq!(iter.len(), 0); + let iter: Range<'_, u8, u8> = Range::default(); + assert_eq!(iter.count(), 0); + let iter: IntoIter = IntoIter::default(); + assert_eq!(iter.len(), 0); + let iter: IntoKeys = IntoKeys::default(); + assert_eq!(iter.len(), 0); + let iter: IntoValues = IntoValues::default(); + assert_eq!(iter.len(), 0); +} + fn range_keys(map: &BTreeMap, range: impl RangeBounds) -> Vec { Vec::from_iter(map.range(range).map(|(&k, &v)| { assert_eq!(k, v); diff --git a/library/alloc/src/collections/btree/navigate.rs b/library/alloc/src/collections/btree/navigate.rs index b890717e50b..a85a3162451 100644 --- a/library/alloc/src/collections/btree/navigate.rs +++ b/library/alloc/src/collections/btree/navigate.rs @@ -19,6 +19,12 @@ impl<'a, K: 'a, V: 'a> Clone for LeafRange, K, V> { } } +impl Default for LeafRange { + fn default() -> Self { + LeafRange { front: None, back: None } + } +} + impl LeafRange { pub fn none() -> Self { LeafRange { front: None, back: None } @@ -124,6 +130,12 @@ pub struct LazyLeafRange { back: Option>, } +impl Default for LazyLeafRange { + fn default() -> Self { + LazyLeafRange { front: None, back: None } + } +} + impl<'a, K: 'a, V: 'a> Clone for LazyLeafRange, K, V> { fn clone(&self) -> Self { LazyLeafRange { front: self.front.clone(), back: self.back.clone() } diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index 4ddb2119252..897499db429 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -1544,6 +1544,14 @@ impl Iterator for IntoIter { self.iter.size_hint() } } + +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for Iter<'_, T> { + fn default() -> Self { + Iter { iter: Default::default() } + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl DoubleEndedIterator for IntoIter { fn next_back(&mut self) -> Option { @@ -1560,6 +1568,13 @@ impl ExactSizeIterator for IntoIter { #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for IntoIter {} +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for IntoIter { + fn default() -> Self { + IntoIter { iter: Default::default() } + } +} + #[stable(feature = "btree_range", since = "1.17.0")] impl Clone for Range<'_, T> { fn clone(&self) -> Self { @@ -1598,6 +1613,13 @@ impl<'a, T> DoubleEndedIterator for Range<'a, T> { #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for Range<'_, T> {} +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for Range<'_, T> { + fn default() -> Self { + Range { iter: Default::default() } + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl Clone for Difference<'_, T, A> { fn clone(&self) -> Self { diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs index f2f5dffc25d..dae7fc48b1f 100644 --- a/library/alloc/src/collections/linked_list.rs +++ b/library/alloc/src/collections/linked_list.rs @@ -1075,6 +1075,13 @@ impl ExactSizeIterator for Iter<'_, T> {} #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for Iter<'_, T> {} +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for Iter<'_, T> { + fn default() -> Self { + Iter { head: None, tail: None, len: 0, marker: Default::default() } + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> Iterator for IterMut<'a, T> { type Item = &'a mut T; @@ -1129,6 +1136,13 @@ impl ExactSizeIterator for IterMut<'_, T> {} #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for IterMut<'_, T> {} +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for IterMut<'_, T> { + fn default() -> Self { + IterMut { head: None, tail: None, len: 0, marker: Default::default() } + } +} + /// A cursor over a `LinkedList`. /// /// A `Cursor` is like an iterator, except that it can freely seek back-and-forth. @@ -1808,6 +1822,13 @@ impl ExactSizeIterator for IntoIter {} #[stable(feature = "fused", since = "1.26.0")] impl FusedIterator for IntoIter {} +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for IntoIter { + fn default() -> Self { + LinkedList::new().into_iter() + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl FromIterator for LinkedList { fn from_iter>(iter: I) -> Self { diff --git a/library/alloc/src/collections/linked_list/tests.rs b/library/alloc/src/collections/linked_list/tests.rs index 04594d55b6a..075c68f7241 100644 --- a/library/alloc/src/collections/linked_list/tests.rs +++ b/library/alloc/src/collections/linked_list/tests.rs @@ -172,6 +172,12 @@ fn test_iterator() { assert_eq!(it.next(), None); } +#[test] +fn test_default() { + let iter: IntoIter = Default::default(); + assert_eq!(iter.len(), 0); +} + #[test] fn test_iterator_clone() { let mut n = LinkedList::new(); diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index 37966007eb7..2be484c3dd4 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -347,6 +347,13 @@ impl FusedIterator for IntoIter {} #[unstable(feature = "trusted_len", issue = "37572")] unsafe impl TrustedLen for IntoIter {} +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for IntoIter { + fn default() -> Self { + super::Vec::new().into_iter() + } +} + #[doc(hidden)] #[unstable(issue = "none", feature = "std_internals")] #[rustc_unsafe_specialization_marker] diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index 2f07c2911a5..782b150681c 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -1,5 +1,6 @@ use core::alloc::{Allocator, Layout}; -use core::iter::IntoIterator; +use core::assert_eq; +use core::iter::{ExactSizeIterator, IntoIterator}; use core::ptr::NonNull; use std::alloc::System; use std::assert_matches::assert_matches; @@ -1035,6 +1036,13 @@ fn test_into_iter_clone() { assert_eq!(it.next(), None); } +#[test] +fn test_into_iter_default() { + let iter: IntoIter = Default::default(); + assert_eq!(iter.len(), 0); + assert_eq!(iter.as_slice(), &[]); +} + #[test] fn test_into_iter_leak() { static mut DROPS: i32 = 0; diff --git a/library/core/src/iter/adapters/chain.rs b/library/core/src/iter/adapters/chain.rs index 60eb3a6da3a..21fc3bc6f6f 100644 --- a/library/core/src/iter/adapters/chain.rs +++ b/library/core/src/iter/adapters/chain.rs @@ -282,6 +282,17 @@ where { } +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for Chain +where + A: Iterator + Default, + B: Iterator + Default, +{ + fn default() -> Self { + Chain::new(Default::default(), Default::default()) + } +} + #[inline] fn and_then_or_clear(opt: &mut Option, f: impl FnOnce(&mut T) -> Option) -> Option { let x = f(opt.as_mut()?); diff --git a/library/core/src/iter/adapters/cloned.rs b/library/core/src/iter/adapters/cloned.rs index 914ff86c1a9..d22a6e721f5 100644 --- a/library/core/src/iter/adapters/cloned.rs +++ b/library/core/src/iter/adapters/cloned.rs @@ -153,3 +153,14 @@ where item.clone() } } + +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl<'a, I, T: 'a> Default for Cloned +where + I: Default + Iterator, + T: Clone, +{ + fn default() -> Self { + Self::new(Default::default()) + } +} diff --git a/library/core/src/iter/adapters/copied.rs b/library/core/src/iter/adapters/copied.rs index 62d3afb8160..d5e579834ee 100644 --- a/library/core/src/iter/adapters/copied.rs +++ b/library/core/src/iter/adapters/copied.rs @@ -240,3 +240,14 @@ where } } } + +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl<'a, I, T: 'a> Default for Copied +where + I: Default + Iterator, + T: Copy, +{ + fn default() -> Self { + Self::new(Default::default()) + } +} diff --git a/library/core/src/iter/adapters/enumerate.rs b/library/core/src/iter/adapters/enumerate.rs index 14a12695111..0b44139a83b 100644 --- a/library/core/src/iter/adapters/enumerate.rs +++ b/library/core/src/iter/adapters/enumerate.rs @@ -264,3 +264,13 @@ where #[unstable(issue = "none", feature = "inplace_iteration")] unsafe impl InPlaceIterable for Enumerate {} + +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for Enumerate +where + I: Iterator + Default, +{ + fn default() -> Self { + Enumerate::new(Default::default()) + } +} diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs index b040a0ea901..c0a347a7c1d 100644 --- a/library/core/src/iter/adapters/flatten.rs +++ b/library/core/src/iter/adapters/flatten.rs @@ -302,6 +302,17 @@ where { } +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for Flatten +where + I: Iterator + Default, + ::Item: IntoIterator, +{ + fn default() -> Self { + Flatten::new(Default::default()) + } +} + /// Real logic of both `Flatten` and `FlatMap` which simply delegate to /// this type. #[derive(Clone, Debug)] diff --git a/library/core/src/iter/adapters/fuse.rs b/library/core/src/iter/adapters/fuse.rs index c9314454203..87275fa3951 100644 --- a/library/core/src/iter/adapters/fuse.rs +++ b/library/core/src/iter/adapters/fuse.rs @@ -181,6 +181,13 @@ where } } +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for Fuse { + fn default() -> Self { + Fuse { iter: Default::default() } + } +} + #[unstable(feature = "trusted_len", issue = "37572")] // SAFETY: `TrustedLen` requires that an accurate length is reported via `size_hint()`. As `Fuse` // is just forwarding this to the wrapped iterator `I` this property is preserved and it is safe to diff --git a/library/core/src/iter/adapters/rev.rs b/library/core/src/iter/adapters/rev.rs index 139fb7bbdd9..4ad75ec0ea2 100644 --- a/library/core/src/iter/adapters/rev.rs +++ b/library/core/src/iter/adapters/rev.rs @@ -135,3 +135,13 @@ impl FusedIterator for Rev where I: FusedIterator + DoubleEndedIterator {} #[unstable(feature = "trusted_len", issue = "37572")] unsafe impl TrustedLen for Rev where I: TrustedLen + DoubleEndedIterator {} + +#[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] +impl Default for Rev +where + I: Default + Iterator, +{ + fn default() -> Self { + Rev::new(Default::default()) + } +} diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs index 89b92a7d597..57754182c4e 100644 --- a/library/core/src/slice/iter/macros.rs +++ b/library/core/src/slice/iter/macros.rs @@ -393,6 +393,13 @@ macro_rules! iterator { } } } + + #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] + impl Default for $name<'_, T> { + fn default() -> Self { + (& $( $mut_ )? []).into_iter() + } + } } } diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs index 39559cdbb5e..294de77a6b0 100644 --- a/library/core/tests/slice.rs +++ b/library/core/tests/slice.rs @@ -1,8 +1,10 @@ use core::cell::Cell; use core::cmp::Ordering; +use core::iter::ExactSizeIterator; use core::mem::MaybeUninit; use core::result::Result::{Err, Ok}; -use core::slice; +use core::slice::Iter; +use core::{assert_eq, slice}; #[test] fn test_position() { @@ -224,6 +226,12 @@ fn test_iterator_count() { assert_eq!(iter2.count(), 3); } +#[test] +fn test_iterator_default() { + let iter: Iter<'_, u8> = Iter::default(); + assert_eq!(iter.len(), 0); +} + #[test] fn test_chunks_count() { let v: &[i32] = &[0, 1, 2, 3, 4, 5]; From 2b32b315f91536b32ac60ea0d3a93a1feb1d9215 Mon Sep 17 00:00:00 2001 From: The 8472 Date: Thu, 4 Aug 2022 21:31:37 +0200 Subject: [PATCH 011/346] rewrite iterator `Default` tests as doctests --- .../alloc/src/collections/binary_heap/mod.rs | 7 +++ library/alloc/src/collections/btree/map.rs | 56 +++++++++++++++++++ .../alloc/src/collections/btree/map/tests.rs | 16 ------ library/alloc/src/collections/btree/set.rs | 21 +++++++ library/alloc/src/collections/linked_list.rs | 14 +++++ .../src/collections/linked_list/tests.rs | 6 -- library/alloc/src/vec/into_iter.rs | 8 +++ library/alloc/tests/vec.rs | 10 +--- library/core/src/iter/adapters/chain.rs | 15 +++++ library/core/src/iter/adapters/cloned.rs | 7 +++ library/core/src/iter/adapters/copied.rs | 7 +++ library/core/src/iter/adapters/enumerate.rs | 7 +++ library/core/src/iter/adapters/flatten.rs | 8 +++ library/core/src/iter/adapters/fuse.rs | 8 +++ library/core/src/iter/adapters/rev.rs | 7 +++ library/core/src/slice/iter/macros.rs | 7 +++ library/core/tests/slice.rs | 10 +--- 17 files changed, 174 insertions(+), 40 deletions(-) diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs index b0ec70ad565..d0a87e3fb9f 100644 --- a/library/alloc/src/collections/binary_heap/mod.rs +++ b/library/alloc/src/collections/binary_heap/mod.rs @@ -1470,6 +1470,13 @@ impl FusedIterator for IntoIter {} #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl Default for IntoIter { + /// Creates an empty `binary_heap::IntoIter`. + /// + /// ``` + /// # use std::collections::binary_heap; + /// let iter: binary_heap::IntoIter = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { IntoIter { iter: Default::default() } } diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index c1e8a84969a..8c8a459fec9 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -364,6 +364,13 @@ impl fmt::Debug for Iter<'_, K, V> { #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl<'a, K: 'a, V: 'a> Default for Iter<'a, K, V> { + /// Creates an empty `btree_map::Iter`. + /// + /// ``` + /// # use std::collections::btree_map; + /// let iter: btree_map::Iter<'_, u8, u8> = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { Iter { range: Default::default(), length: 0 } } @@ -395,6 +402,13 @@ impl fmt::Debug for IterMut<'_, K, V> { #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl<'a, K: 'a, V: 'a> Default for IterMut<'a, K, V> { + /// Creates an empty `btree_map::IterMut`. + /// + /// ``` + /// # use std::collections::btree_map; + /// let iter: btree_map::IterMut<'_, u8, u8> = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { IterMut { range: Default::default(), length: 0, _marker: PhantomData {} } } @@ -437,6 +451,13 @@ impl Debug for IntoIter { #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl Default for IntoIter { + /// Creates an empty `btree_map::IntoIter`. + /// + /// ``` + /// # use std::collections::btree_map; + /// let iter: btree_map::IntoIter = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { IntoIter { range: Default::default(), length: 0, alloc: Global } } @@ -1791,6 +1812,13 @@ impl Clone for Keys<'_, K, V> { #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl Default for Keys<'_, K, V> { + /// Creates an empty `btree_map::Keys`. + /// + /// ``` + /// # use std::collections::btree_map; + /// let iter: btree_map::Keys<'_, u8, u8> = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { Keys { inner: Default::default() } } @@ -1839,6 +1867,13 @@ impl Clone for Values<'_, K, V> { #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl Default for Values<'_, K, V> { + /// Creates an empty `btree_map::Values`. + /// + /// ``` + /// # use std::collections::btree_map; + /// let iter: btree_map::Values<'_, u8, u8> = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { Values { inner: Default::default() } } @@ -1982,6 +2017,13 @@ impl<'a, K, V> Iterator for Range<'a, K, V> { #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl Default for Range<'_, K, V> { + /// Creates an empty `btree_map::Range`. + /// + /// ``` + /// # use std::collections::btree_map; + /// let iter: btree_map::Range<'_, u8, u8> = Default::default(); + /// assert_eq!(iter.count(), 0); + /// ``` fn default() -> Self { Range { inner: Default::default() } } @@ -2065,6 +2107,13 @@ impl FusedIterator for IntoKeys {} #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl Default for IntoKeys { + /// Creates an empty `btree_map::IntoKeys`. + /// + /// ``` + /// # use std::collections::btree_map; + /// let iter: btree_map::IntoKeys = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { IntoKeys { inner: Default::default() } } @@ -2106,6 +2155,13 @@ impl FusedIterator for IntoValues {} #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl Default for IntoValues { + /// Creates an empty `btree_map::IntoValues`. + /// + /// ``` + /// # use std::collections::btree_map; + /// let iter: btree_map::IntoValues = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { IntoValues { inner: Default::default() } } diff --git a/library/alloc/src/collections/btree/map/tests.rs b/library/alloc/src/collections/btree/map/tests.rs index 4d011195936..76c2f27b466 100644 --- a/library/alloc/src/collections/btree/map/tests.rs +++ b/library/alloc/src/collections/btree/map/tests.rs @@ -563,22 +563,6 @@ fn test_iter_min_max() { a.check(); } -#[test] -fn test_iters_default() { - let iter: Keys<'_, u8, u8> = Keys::default(); - assert_eq!(iter.len(), 0); - let iter: Values<'_, u8, u8> = Values::default(); - assert_eq!(iter.len(), 0); - let iter: Range<'_, u8, u8> = Range::default(); - assert_eq!(iter.count(), 0); - let iter: IntoIter = IntoIter::default(); - assert_eq!(iter.len(), 0); - let iter: IntoKeys = IntoKeys::default(); - assert_eq!(iter.len(), 0); - let iter: IntoValues = IntoValues::default(); - assert_eq!(iter.len(), 0); -} - fn range_keys(map: &BTreeMap, range: impl RangeBounds) -> Vec { Vec::from_iter(map.range(range).map(|(&k, &v)| { assert_eq!(k, v); diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index 897499db429..5992b814bba 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -1547,6 +1547,13 @@ impl Iterator for IntoIter { #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl Default for Iter<'_, T> { + /// Creates an empty `btree_set::Iter`. + /// + /// ``` + /// # use std::collections::btree_set; + /// let iter: btree_set::Iter<'_, u8> = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { Iter { iter: Default::default() } } @@ -1570,6 +1577,13 @@ impl FusedIterator for IntoIter {} #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl Default for IntoIter { + /// Creates an empty `btree_set::IntoIter`. + /// + /// ``` + /// # use std::collections::btree_set; + /// let iter: btree_set::IntoIter = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { IntoIter { iter: Default::default() } } @@ -1615,6 +1629,13 @@ impl FusedIterator for Range<'_, T> {} #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl Default for Range<'_, T> { + /// Creates an empty `btree_set::Range`. + /// + /// ``` + /// # use std::collections::btree_set; + /// let iter: btree_set::Range<'_, u8> = Default::default(); + /// assert_eq!(iter.count(), 0); + /// ``` fn default() -> Self { Range { iter: Default::default() } } diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs index dae7fc48b1f..080a4a14eda 100644 --- a/library/alloc/src/collections/linked_list.rs +++ b/library/alloc/src/collections/linked_list.rs @@ -1077,6 +1077,13 @@ impl FusedIterator for Iter<'_, T> {} #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl Default for Iter<'_, T> { + /// Creates an empty `linked_list::Iter`. + /// + /// ``` + /// # use std::collections::linked_list; + /// let iter: linked_list::Iter<'_, u8> = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { Iter { head: None, tail: None, len: 0, marker: Default::default() } } @@ -1824,6 +1831,13 @@ impl FusedIterator for IntoIter {} #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl Default for IntoIter { + /// Creates an empty `linked_list::IntoIter`. + /// + /// ``` + /// # use std::collections::linked_list; + /// let iter: linked_list::IntoIter = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { LinkedList::new().into_iter() } diff --git a/library/alloc/src/collections/linked_list/tests.rs b/library/alloc/src/collections/linked_list/tests.rs index 075c68f7241..04594d55b6a 100644 --- a/library/alloc/src/collections/linked_list/tests.rs +++ b/library/alloc/src/collections/linked_list/tests.rs @@ -172,12 +172,6 @@ fn test_iterator() { assert_eq!(it.next(), None); } -#[test] -fn test_default() { - let iter: IntoIter = Default::default(); - assert_eq!(iter.len(), 0); -} - #[test] fn test_iterator_clone() { let mut n = LinkedList::new(); diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index 2be484c3dd4..8fed4a584a3 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -349,6 +349,14 @@ unsafe impl TrustedLen for IntoIter {} #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl Default for IntoIter { + /// Creates an empty `vec::IntoIter`. + /// + /// ``` + /// # use std::vec; + /// let iter: vec::IntoIter = Default::default(); + /// assert_eq!(iter.len(), 0); + /// assert_eq!(iter.as_slice(), &[]); + /// ``` fn default() -> Self { super::Vec::new().into_iter() } diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index 782b150681c..2f07c2911a5 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -1,6 +1,5 @@ use core::alloc::{Allocator, Layout}; -use core::assert_eq; -use core::iter::{ExactSizeIterator, IntoIterator}; +use core::iter::IntoIterator; use core::ptr::NonNull; use std::alloc::System; use std::assert_matches::assert_matches; @@ -1036,13 +1035,6 @@ fn test_into_iter_clone() { assert_eq!(it.next(), None); } -#[test] -fn test_into_iter_default() { - let iter: IntoIter = Default::default(); - assert_eq!(iter.len(), 0); - assert_eq!(iter.as_slice(), &[]); -} - #[test] fn test_into_iter_leak() { static mut DROPS: i32 = 0; diff --git a/library/core/src/iter/adapters/chain.rs b/library/core/src/iter/adapters/chain.rs index 21fc3bc6f6f..0f5e3718408 100644 --- a/library/core/src/iter/adapters/chain.rs +++ b/library/core/src/iter/adapters/chain.rs @@ -288,6 +288,21 @@ where A: Iterator + Default, B: Iterator + Default, { + /// Creates a `Chain` from the default values for `A` and `B`. + /// + /// ``` + /// # use core::iter::Chain; + /// # use core::slice; + /// # use std::collections::{btree_set, BTreeSet}; + /// # use std::mem; + /// struct Foo<'a>(Chain, btree_set::Iter<'a, u8>>); + /// + /// let set = BTreeSet::::new(); + /// let slice: &[u8] = &[]; + /// let mut foo = Foo(slice.iter().chain(set.iter())); + /// + /// // take requires `Default` + /// let _: Chain<_, _> = mem::take(&mut foo.0); fn default() -> Self { Chain::new(Default::default(), Default::default()) } diff --git a/library/core/src/iter/adapters/cloned.rs b/library/core/src/iter/adapters/cloned.rs index d22a6e721f5..b9e2700860c 100644 --- a/library/core/src/iter/adapters/cloned.rs +++ b/library/core/src/iter/adapters/cloned.rs @@ -160,6 +160,13 @@ where I: Default + Iterator, T: Clone, { + /// Creates a `Cloned` iterator from the default value of `I` + /// ``` + /// # use core::slice; + /// # use core::iter::Cloned; + /// let iter: Cloned> = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { Self::new(Default::default()) } diff --git a/library/core/src/iter/adapters/copied.rs b/library/core/src/iter/adapters/copied.rs index d5e579834ee..0aa466e37a2 100644 --- a/library/core/src/iter/adapters/copied.rs +++ b/library/core/src/iter/adapters/copied.rs @@ -247,6 +247,13 @@ where I: Default + Iterator, T: Copy, { + /// Creates a `Copied` iterator from the default value of `I` + /// ``` + /// # use core::slice; + /// # use core::iter::Copied; + /// let iter: Copied> = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { Self::new(Default::default()) } diff --git a/library/core/src/iter/adapters/enumerate.rs b/library/core/src/iter/adapters/enumerate.rs index 0b44139a83b..5b0025cb984 100644 --- a/library/core/src/iter/adapters/enumerate.rs +++ b/library/core/src/iter/adapters/enumerate.rs @@ -270,6 +270,13 @@ impl Default for Enumerate where I: Iterator + Default, { + /// Creates an `Enumerate` iterator from the default value of `I` + /// ``` + /// # use core::slice; + /// # use std::iter::Enumerate; + /// let iter: Enumerate> = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { Enumerate::new(Default::default()) } diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs index c0a347a7c1d..cb68c807bf5 100644 --- a/library/core/src/iter/adapters/flatten.rs +++ b/library/core/src/iter/adapters/flatten.rs @@ -308,6 +308,14 @@ where I: Iterator + Default, ::Item: IntoIterator, { + /// Creates a `Flatten` iterator from the default value of `I`. + /// + /// ``` + /// # use core::slice; + /// # use std::iter::Flatten; + /// let iter: Flatten> = Default::default(); + /// assert_eq!(iter.count(), 0); + /// ``` fn default() -> Self { Flatten::new(Default::default()) } diff --git a/library/core/src/iter/adapters/fuse.rs b/library/core/src/iter/adapters/fuse.rs index 87275fa3951..de91c188eeb 100644 --- a/library/core/src/iter/adapters/fuse.rs +++ b/library/core/src/iter/adapters/fuse.rs @@ -183,6 +183,14 @@ where #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl Default for Fuse { + /// Creates a `Fuse` iterator from the default value of `I`. + /// + /// ``` + /// # use core::slice; + /// # use std::iter::Fuse; + /// let iter: Fuse> = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { Fuse { iter: Default::default() } } diff --git a/library/core/src/iter/adapters/rev.rs b/library/core/src/iter/adapters/rev.rs index 4ad75ec0ea2..0b132e13813 100644 --- a/library/core/src/iter/adapters/rev.rs +++ b/library/core/src/iter/adapters/rev.rs @@ -141,6 +141,13 @@ impl Default for Rev where I: Default + Iterator, { + /// Creates a `Rev` iterator from the default value of `I` + /// ``` + /// # use core::slice; + /// # use core::iter::Rev; + /// let iter: Rev> = Default::default(); + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { Rev::new(Default::default()) } diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs index 57754182c4e..a800da546b4 100644 --- a/library/core/src/slice/iter/macros.rs +++ b/library/core/src/slice/iter/macros.rs @@ -396,6 +396,13 @@ macro_rules! iterator { #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl Default for $name<'_, T> { + /// Creates an empty slice iterator. + /// + /// ``` + #[doc = concat!("# use core::slice::", stringify!($name), ";")] + #[doc = concat!("let iter: ", stringify!($name<'_, u8>), " = Default::default();")] + /// assert_eq!(iter.len(), 0); + /// ``` fn default() -> Self { (& $( $mut_ )? []).into_iter() } diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs index 294de77a6b0..39559cdbb5e 100644 --- a/library/core/tests/slice.rs +++ b/library/core/tests/slice.rs @@ -1,10 +1,8 @@ use core::cell::Cell; use core::cmp::Ordering; -use core::iter::ExactSizeIterator; use core::mem::MaybeUninit; use core::result::Result::{Err, Ok}; -use core::slice::Iter; -use core::{assert_eq, slice}; +use core::slice; #[test] fn test_position() { @@ -226,12 +224,6 @@ fn test_iterator_count() { assert_eq!(iter2.count(), 3); } -#[test] -fn test_iterator_default() { - let iter: Iter<'_, u8> = Iter::default(); - assert_eq!(iter.len(), 0); -} - #[test] fn test_chunks_count() { let v: &[i32] = &[0, 1, 2, 3, 4, 5]; From a4bdfe24c5f83cbb03febdb9ab5fd22414eac05f Mon Sep 17 00:00:00 2001 From: The 8472 Date: Tue, 25 Oct 2022 22:55:04 +0200 Subject: [PATCH 012/346] Support allocators in various Default for IntoIter impls Global implements Default so we can use that as bound for all allocators --- library/alloc/src/collections/btree/map.rs | 17 +++++++++++++---- library/alloc/src/collections/btree/set.rs | 5 ++++- library/alloc/src/vec/into_iter.rs | 7 +++++-- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 8c8a459fec9..61db46314b7 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -450,7 +450,10 @@ impl Debug for IntoIter { } #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] -impl Default for IntoIter { +impl Default for IntoIter +where + A: Allocator + Default + Clone, +{ /// Creates an empty `btree_map::IntoIter`. /// /// ``` @@ -459,7 +462,7 @@ impl Default for IntoIter { /// assert_eq!(iter.len(), 0); /// ``` fn default() -> Self { - IntoIter { range: Default::default(), length: 0, alloc: Global } + IntoIter { range: Default::default(), length: 0, alloc: Default::default() } } } @@ -2106,7 +2109,10 @@ impl ExactSizeIterator for IntoKeys { impl FusedIterator for IntoKeys {} #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] -impl Default for IntoKeys { +impl Default for IntoKeys +where + A: Allocator + Default + Clone, +{ /// Creates an empty `btree_map::IntoKeys`. /// /// ``` @@ -2154,7 +2160,10 @@ impl ExactSizeIterator for IntoValues { impl FusedIterator for IntoValues {} #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] -impl Default for IntoValues { +impl Default for IntoValues +where + A: Allocator + Default + Clone, +{ /// Creates an empty `btree_map::IntoValues`. /// /// ``` diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index 5992b814bba..c2233f86667 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -1576,7 +1576,10 @@ impl ExactSizeIterator for IntoIter { impl FusedIterator for IntoIter {} #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] -impl Default for IntoIter { +impl Default for IntoIter +where + A: Allocator + Default + Clone, +{ /// Creates an empty `btree_set::IntoIter`. /// /// ``` diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index 8fed4a584a3..f6525eb9003 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -348,7 +348,10 @@ impl FusedIterator for IntoIter {} unsafe impl TrustedLen for IntoIter {} #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] -impl Default for IntoIter { +impl Default for IntoIter +where + A: Allocator + Default, +{ /// Creates an empty `vec::IntoIter`. /// /// ``` @@ -358,7 +361,7 @@ impl Default for IntoIter { /// assert_eq!(iter.as_slice(), &[]); /// ``` fn default() -> Self { - super::Vec::new().into_iter() + super::Vec::new_in(Default::default()).into_iter() } } From e44836faf6ff114805062f723b349d6e10bf86b6 Mon Sep 17 00:00:00 2001 From: The 8472 Date: Tue, 28 Feb 2023 21:16:33 +0100 Subject: [PATCH 013/346] relax bounds on iterator adapter Default impls --- library/core/src/iter/adapters/chain.rs | 6 +----- library/core/src/iter/adapters/cloned.rs | 6 +----- library/core/src/iter/adapters/copied.rs | 6 +----- library/core/src/iter/adapters/enumerate.rs | 5 +---- library/core/src/iter/adapters/flatten.rs | 3 +-- library/core/src/iter/adapters/rev.rs | 5 +---- 6 files changed, 6 insertions(+), 25 deletions(-) diff --git a/library/core/src/iter/adapters/chain.rs b/library/core/src/iter/adapters/chain.rs index 0f5e3718408..d4b2640e81d 100644 --- a/library/core/src/iter/adapters/chain.rs +++ b/library/core/src/iter/adapters/chain.rs @@ -283,11 +283,7 @@ where } #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] -impl Default for Chain -where - A: Iterator + Default, - B: Iterator + Default, -{ +impl Default for Chain { /// Creates a `Chain` from the default values for `A` and `B`. /// /// ``` diff --git a/library/core/src/iter/adapters/cloned.rs b/library/core/src/iter/adapters/cloned.rs index b9e2700860c..bb7e1660c6e 100644 --- a/library/core/src/iter/adapters/cloned.rs +++ b/library/core/src/iter/adapters/cloned.rs @@ -155,11 +155,7 @@ where } #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] -impl<'a, I, T: 'a> Default for Cloned -where - I: Default + Iterator, - T: Clone, -{ +impl Default for Cloned { /// Creates a `Cloned` iterator from the default value of `I` /// ``` /// # use core::slice; diff --git a/library/core/src/iter/adapters/copied.rs b/library/core/src/iter/adapters/copied.rs index 0aa466e37a2..a076ab925e3 100644 --- a/library/core/src/iter/adapters/copied.rs +++ b/library/core/src/iter/adapters/copied.rs @@ -242,11 +242,7 @@ where } #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] -impl<'a, I, T: 'a> Default for Copied -where - I: Default + Iterator, - T: Copy, -{ +impl Default for Copied { /// Creates a `Copied` iterator from the default value of `I` /// ``` /// # use core::slice; diff --git a/library/core/src/iter/adapters/enumerate.rs b/library/core/src/iter/adapters/enumerate.rs index 5b0025cb984..8c32a35a12f 100644 --- a/library/core/src/iter/adapters/enumerate.rs +++ b/library/core/src/iter/adapters/enumerate.rs @@ -266,10 +266,7 @@ where unsafe impl InPlaceIterable for Enumerate {} #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] -impl Default for Enumerate -where - I: Iterator + Default, -{ +impl Default for Enumerate { /// Creates an `Enumerate` iterator from the default value of `I` /// ``` /// # use core::slice; diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs index cb68c807bf5..e4020c45f71 100644 --- a/library/core/src/iter/adapters/flatten.rs +++ b/library/core/src/iter/adapters/flatten.rs @@ -305,8 +305,7 @@ where #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] impl Default for Flatten where - I: Iterator + Default, - ::Item: IntoIterator, + I: Default + Iterator, { /// Creates a `Flatten` iterator from the default value of `I`. /// diff --git a/library/core/src/iter/adapters/rev.rs b/library/core/src/iter/adapters/rev.rs index 0b132e13813..8ae6d96fde4 100644 --- a/library/core/src/iter/adapters/rev.rs +++ b/library/core/src/iter/adapters/rev.rs @@ -137,10 +137,7 @@ impl FusedIterator for Rev where I: FusedIterator + DoubleEndedIterator {} unsafe impl TrustedLen for Rev where I: TrustedLen + DoubleEndedIterator {} #[stable(feature = "default_iters", since = "CURRENT_RUSTC_VERSION")] -impl Default for Rev -where - I: Default + Iterator, -{ +impl Default for Rev { /// Creates a `Rev` iterator from the default value of `I` /// ``` /// # use core::slice; From 1a81a3e5cfc47908154b13bd921f9c03c5592010 Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Thu, 2 Mar 2023 00:51:04 -0500 Subject: [PATCH 014/346] Remove `snippet_with_macro_callsite` --- clippy_lints/src/default.rs | 9 ++-- clippy_lints/src/if_then_some_else_none.rs | 17 ++++---- clippy_lints/src/loops/same_item_push.rs | 32 ++++++++------ clippy_lints/src/matches/manual_unwrap_or.rs | 12 ++---- clippy_lints/src/matches/match_bool.rs | 20 +++++---- clippy_lints/src/matches/match_ref_pats.rs | 28 ++++++++++--- .../src/matches/match_single_binding.rs | 41 +++++++++--------- .../src/matches/redundant_pattern_match.rs | 17 ++++---- clippy_lints/src/matches/single_match.rs | 18 +++----- .../src/methods/bind_instead_of_map.rs | 11 ++--- clippy_lints/src/methods/clone_on_ref_ptr.rs | 8 ++-- clippy_lints/src/methods/or_fun_call.rs | 28 ++++--------- clippy_lints/src/misc.rs | 17 ++++---- clippy_lints/src/needless_bool.rs | 13 ++---- clippy_lints/src/option_if_let_else.rs | 28 +++++++++---- .../src/semicolon_if_nothing_returned.rs | 13 +++--- clippy_lints/src/unit_types/let_unit_value.rs | 7 ++-- clippy_lints/src/useless_conversion.rs | 14 ++++--- clippy_utils/src/source.rs | 42 ++++++++++--------- clippy_utils/src/sugg.rs | 10 +---- .../redundant_pattern_matching_result.fixed | 4 +- .../redundant_pattern_matching_result.stderr | 4 +- 22 files changed, 200 insertions(+), 193 deletions(-) diff --git a/clippy_lints/src/default.rs b/clippy_lints/src/default.rs index 080d44e6398..80c22742ba4 100644 --- a/clippy_lints/src/default.rs +++ b/clippy_lints/src/default.rs @@ -1,5 +1,5 @@ use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_sugg}; -use clippy_utils::source::snippet_with_macro_callsite; +use clippy_utils::source::snippet_with_context; use clippy_utils::ty::{has_drop, is_copy}; use clippy_utils::{ any_parent_is_automatically_derived, contains_name, get_parent_expr, is_from_proc_macro, match_def_path, paths, @@ -160,6 +160,8 @@ impl<'tcx> LateLintPass<'tcx> for Default { } }; + let init_ctxt = local.span.ctxt(); + // find all "later statement"'s where the fields of the binding set as // Default::default() get reassigned, unless the reassignment refers to the original binding let mut first_assign = None; @@ -169,7 +171,7 @@ impl<'tcx> LateLintPass<'tcx> for Default { // find out if and which field was set by this `consecutive_statement` if let Some((field_ident, assign_rhs)) = field_reassigned_by_stmt(consecutive_statement, binding_name) { // interrupt and cancel lint if assign_rhs references the original binding - if contains_name(binding_name, assign_rhs, cx) { + if contains_name(binding_name, assign_rhs, cx) || init_ctxt != consecutive_statement.span.ctxt() { cancel_lint = true; break; } @@ -204,11 +206,12 @@ impl<'tcx> LateLintPass<'tcx> for Default { .iter() .all(|field| assigned_fields.iter().any(|(a, _)| a == &field.name)); + let mut app = Applicability::Unspecified; let field_list = assigned_fields .into_iter() .map(|(field, rhs)| { // extract and store the assigned value for help message - let value_snippet = snippet_with_macro_callsite(cx, rhs.span, ".."); + let value_snippet = snippet_with_context(cx, rhs.span, init_ctxt, "..", &mut app).0; format!("{field}: {value_snippet}") }) .collect::>() diff --git a/clippy_lints/src/if_then_some_else_none.rs b/clippy_lints/src/if_then_some_else_none.rs index 9cadaaa493e..725bd3d54bc 100644 --- a/clippy_lints/src/if_then_some_else_none.rs +++ b/clippy_lints/src/if_then_some_else_none.rs @@ -1,8 +1,10 @@ use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::eager_or_lazy::switch_to_eager_eval; use clippy_utils::msrvs::{self, Msrv}; -use clippy_utils::source::snippet_with_macro_callsite; +use clippy_utils::source::snippet_with_context; +use clippy_utils::sugg::Sugg; use clippy_utils::{contains_return, higher, is_else_clause, is_res_lang_ctor, path_res, peel_blocks}; +use rustc_errors::Applicability; use rustc_hir::LangItem::{OptionNone, OptionSome}; use rustc_hir::{Expr, ExprKind, Stmt, StmtKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; @@ -72,21 +74,20 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone { return; } + let ctxt = expr.span.ctxt(); + if let Some(higher::If { cond, then, r#else: Some(els) }) = higher::If::hir(expr) && let ExprKind::Block(then_block, _) = then.kind && let Some(then_expr) = then_block.expr && let ExprKind::Call(then_call, [then_arg]) = then_expr.kind + && then_expr.span.ctxt() == ctxt && is_res_lang_ctor(cx, path_res(cx, then_call), OptionSome) && is_res_lang_ctor(cx, path_res(cx, peel_blocks(els)), OptionNone) && !stmts_contains_early_return(then_block.stmts) { - let cond_snip = snippet_with_macro_callsite(cx, cond.span, "[condition]"); - let cond_snip = if matches!(cond.kind, ExprKind::Unary(_, _) | ExprKind::Binary(_, _, _)) { - format!("({cond_snip})") - } else { - cond_snip.into_owned() - }; - let arg_snip = snippet_with_macro_callsite(cx, then_arg.span, ""); + let mut app = Applicability::Unspecified; + let cond_snip = Sugg::hir_with_context(cx, cond, expr.span.ctxt(), "[condition]", &mut app).maybe_par().to_string(); + let arg_snip = snippet_with_context(cx, then_arg.span, ctxt, "[body]", &mut app).0; let mut method_body = if then_block.stmts.is_empty() { arg_snip.into_owned() } else { diff --git a/clippy_lints/src/loops/same_item_push.rs b/clippy_lints/src/loops/same_item_push.rs index 540656a2cd9..9d9341559ac 100644 --- a/clippy_lints/src/loops/same_item_push.rs +++ b/clippy_lints/src/loops/same_item_push.rs @@ -1,15 +1,17 @@ use super::SAME_ITEM_PUSH; use clippy_utils::diagnostics::span_lint_and_help; use clippy_utils::path_to_local; -use clippy_utils::source::snippet_with_macro_callsite; +use clippy_utils::source::snippet_with_context; use clippy_utils::ty::{implements_trait, is_type_diagnostic_item}; use if_chain::if_chain; use rustc_data_structures::fx::FxHashSet; +use rustc_errors::Applicability; use rustc_hir::def::{DefKind, Res}; use rustc_hir::intravisit::{walk_expr, Visitor}; use rustc_hir::{BindingAnnotation, Block, Expr, ExprKind, HirId, Mutability, Node, Pat, PatKind, Stmt, StmtKind}; use rustc_lint::LateContext; use rustc_span::symbol::sym; +use rustc_span::SyntaxContext; use std::iter::Iterator; /// Detects for loop pushing the same item into a Vec @@ -20,9 +22,10 @@ pub(super) fn check<'tcx>( body: &'tcx Expr<'_>, _: &'tcx Expr<'_>, ) { - fn emit_lint(cx: &LateContext<'_>, vec: &Expr<'_>, pushed_item: &Expr<'_>) { - let vec_str = snippet_with_macro_callsite(cx, vec.span, ""); - let item_str = snippet_with_macro_callsite(cx, pushed_item.span, ""); + fn emit_lint(cx: &LateContext<'_>, vec: &Expr<'_>, pushed_item: &Expr<'_>, ctxt: SyntaxContext) { + let mut app = Applicability::Unspecified; + let vec_str = snippet_with_context(cx, vec.span, ctxt, "", &mut app).0; + let item_str = snippet_with_context(cx, pushed_item.span, ctxt, "", &mut app).0; span_lint_and_help( cx, @@ -43,7 +46,7 @@ pub(super) fn check<'tcx>( walk_expr(&mut same_item_push_visitor, body); if_chain! { if same_item_push_visitor.should_lint(); - if let Some((vec, pushed_item)) = same_item_push_visitor.vec_push; + if let Some((vec, pushed_item, ctxt)) = same_item_push_visitor.vec_push; let vec_ty = cx.typeck_results().expr_ty(vec); let ty = vec_ty.walk().nth(1).unwrap().expect_ty(); if cx @@ -69,11 +72,11 @@ pub(super) fn check<'tcx>( then { match init.kind { // immutable bindings that are initialized with literal - ExprKind::Lit(..) => emit_lint(cx, vec, pushed_item), + ExprKind::Lit(..) => emit_lint(cx, vec, pushed_item, ctxt), // immutable bindings that are initialized with constant ExprKind::Path(ref path) => { if let Res::Def(DefKind::Const, ..) = cx.qpath_res(path, init.hir_id) { - emit_lint(cx, vec, pushed_item); + emit_lint(cx, vec, pushed_item, ctxt); } } _ => {}, @@ -82,11 +85,11 @@ pub(super) fn check<'tcx>( } }, // constant - Res::Def(DefKind::Const, ..) => emit_lint(cx, vec, pushed_item), + Res::Def(DefKind::Const, ..) => emit_lint(cx, vec, pushed_item, ctxt), _ => {}, } }, - ExprKind::Lit(..) => emit_lint(cx, vec, pushed_item), + ExprKind::Lit(..) => emit_lint(cx, vec, pushed_item, ctxt), _ => {}, } } @@ -98,7 +101,7 @@ struct SameItemPushVisitor<'a, 'tcx> { non_deterministic_expr: bool, multiple_pushes: bool, // this field holds the last vec push operation visited, which should be the only push seen - vec_push: Option<(&'tcx Expr<'tcx>, &'tcx Expr<'tcx>)>, + vec_push: Option<(&'tcx Expr<'tcx>, &'tcx Expr<'tcx>, SyntaxContext)>, cx: &'a LateContext<'tcx>, used_locals: FxHashSet, } @@ -118,7 +121,7 @@ impl<'a, 'tcx> SameItemPushVisitor<'a, 'tcx> { if_chain! { if !self.non_deterministic_expr; if !self.multiple_pushes; - if let Some((vec, _)) = self.vec_push; + if let Some((vec, _, _)) = self.vec_push; if let Some(hir_id) = path_to_local(vec); then { !self.used_locals.contains(&hir_id) @@ -173,7 +176,10 @@ impl<'a, 'tcx> Visitor<'tcx> for SameItemPushVisitor<'a, 'tcx> { // Given some statement, determine if that statement is a push on a Vec. If it is, return // the Vec being pushed into and the item being pushed -fn get_vec_push<'tcx>(cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) -> Option<(&'tcx Expr<'tcx>, &'tcx Expr<'tcx>)> { +fn get_vec_push<'tcx>( + cx: &LateContext<'tcx>, + stmt: &'tcx Stmt<'_>, +) -> Option<(&'tcx Expr<'tcx>, &'tcx Expr<'tcx>, SyntaxContext)> { if_chain! { // Extract method being called if let StmtKind::Semi(semi_stmt) = &stmt.kind; @@ -184,7 +190,7 @@ fn get_vec_push<'tcx>(cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) -> Option<(& if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(self_expr), sym::Vec); if path.ident.name.as_str() == "push"; then { - return Some((self_expr, pushed_item)) + return Some((self_expr, pushed_item, semi_stmt.span.ctxt())) } } None diff --git a/clippy_lints/src/matches/manual_unwrap_or.rs b/clippy_lints/src/matches/manual_unwrap_or.rs index 587c926dc01..84ff3c710c2 100644 --- a/clippy_lints/src/matches/manual_unwrap_or.rs +++ b/clippy_lints/src/matches/manual_unwrap_or.rs @@ -33,14 +33,8 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, scrutinee: let reindented_or_body = reindent_multiline(or_body_snippet.into(), true, Some(indent)); - let suggestion = if scrutinee.span.from_expansion() { - // we don't want parentheses around macro, e.g. `(some_macro!()).unwrap_or(0)` - sugg::Sugg::hir_with_macro_callsite(cx, scrutinee, "..") - } - else { - sugg::Sugg::hir(cx, scrutinee, "..").maybe_par() - }; - + let mut app = Applicability::MachineApplicable; + let suggestion = sugg::Sugg::hir_with_context(cx, scrutinee, expr.span.ctxt(), "..", &mut app).maybe_par(); span_lint_and_sugg( cx, MANUAL_UNWRAP_OR, expr.span, @@ -49,7 +43,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, scrutinee: format!( "{suggestion}.unwrap_or({reindented_or_body})", ), - Applicability::MachineApplicable, + app, ); } } diff --git a/clippy_lints/src/matches/match_bool.rs b/clippy_lints/src/matches/match_bool.rs index 1c216e13570..df1e585f10b 100644 --- a/clippy_lints/src/matches/match_bool.rs +++ b/clippy_lints/src/matches/match_bool.rs @@ -10,9 +10,9 @@ use rustc_middle::ty; use super::MATCH_BOOL; -pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>) { +pub(crate) fn check(cx: &LateContext<'_>, scrutinee: &Expr<'_>, arms: &[Arm<'_>], expr: &Expr<'_>) { // Type of expression is `bool`. - if *cx.typeck_results().expr_ty(ex).kind() == ty::Bool { + if *cx.typeck_results().expr_ty(scrutinee).kind() == ty::Bool { span_lint_and_then( cx, MATCH_BOOL, @@ -36,24 +36,26 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: }; if let Some((true_expr, false_expr)) = exprs { + let mut app = Applicability::HasPlaceholders; + let ctxt = expr.span.ctxt(); let sugg = match (is_unit_expr(true_expr), is_unit_expr(false_expr)) { (false, false) => Some(format!( "if {} {} else {}", - snippet(cx, ex.span, "b"), - expr_block(cx, true_expr, None, "..", Some(expr.span)), - expr_block(cx, false_expr, None, "..", Some(expr.span)) + snippet(cx, scrutinee.span, "b"), + expr_block(cx, true_expr, ctxt, "..", Some(expr.span), &mut app), + expr_block(cx, false_expr, ctxt, "..", Some(expr.span), &mut app) )), (false, true) => Some(format!( "if {} {}", - snippet(cx, ex.span, "b"), - expr_block(cx, true_expr, None, "..", Some(expr.span)) + snippet(cx, scrutinee.span, "b"), + expr_block(cx, true_expr, ctxt, "..", Some(expr.span), &mut app) )), (true, false) => { - let test = Sugg::hir(cx, ex, ".."); + let test = Sugg::hir(cx, scrutinee, ".."); Some(format!( "if {} {}", !test, - expr_block(cx, false_expr, None, "..", Some(expr.span)) + expr_block(cx, false_expr, ctxt, "..", Some(expr.span), &mut app) )) }, (true, true) => None, diff --git a/clippy_lints/src/matches/match_ref_pats.rs b/clippy_lints/src/matches/match_ref_pats.rs index 80f964ba1b7..aba4c85c59e 100644 --- a/clippy_lints/src/matches/match_ref_pats.rs +++ b/clippy_lints/src/matches/match_ref_pats.rs @@ -1,13 +1,14 @@ use clippy_utils::diagnostics::{multispan_sugg, span_lint_and_then}; -use clippy_utils::source::snippet; +use clippy_utils::source::{snippet, walk_span_to_context}; use clippy_utils::sugg::Sugg; use core::iter::once; +use rustc_errors::Applicability; use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, Pat, PatKind}; use rustc_lint::LateContext; use super::MATCH_REF_PATS; -pub(crate) fn check<'a, 'b, I>(cx: &LateContext<'_>, ex: &Expr<'_>, pats: I, expr: &Expr<'_>) +pub(crate) fn check<'a, 'b, I>(cx: &LateContext<'_>, scrutinee: &Expr<'_>, pats: I, expr: &Expr<'_>) where 'b: 'a, I: Clone + Iterator>, @@ -17,13 +18,28 @@ where } let (first_sugg, msg, title); - let span = ex.span.source_callsite(); - if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner) = ex.kind { - first_sugg = once((span, Sugg::hir_with_macro_callsite(cx, inner, "..").to_string())); + let ctxt = expr.span.ctxt(); + let mut app = Applicability::Unspecified; + if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, inner) = scrutinee.kind { + if scrutinee.span.ctxt() != ctxt { + return; + } + first_sugg = once(( + scrutinee.span, + Sugg::hir_with_context(cx, inner, ctxt, "..", &mut app).to_string(), + )); msg = "try"; title = "you don't need to add `&` to both the expression and the patterns"; } else { - first_sugg = once((span, Sugg::hir_with_macro_callsite(cx, ex, "..").deref().to_string())); + let Some(span) = walk_span_to_context(scrutinee.span, ctxt) else { + return; + }; + first_sugg = once(( + span, + Sugg::hir_with_context(cx, scrutinee, ctxt, "..", &mut app) + .deref() + .to_string(), + )); msg = "instead of prefixing all patterns with `&`, you can dereference the expression"; title = "you don't need to add `&` to all patterns"; } diff --git a/clippy_lints/src/matches/match_single_binding.rs b/clippy_lints/src/matches/match_single_binding.rs index 065a5c72621..eec5c1143d4 100644 --- a/clippy_lints/src/matches/match_single_binding.rs +++ b/clippy_lints/src/matches/match_single_binding.rs @@ -1,7 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::macros::HirNode; -use clippy_utils::source::{indent_of, snippet, snippet_block, snippet_with_applicability}; -use clippy_utils::sugg::Sugg; +use clippy_utils::source::{indent_of, snippet, snippet_block_with_context, snippet_with_applicability}; use clippy_utils::{get_parent_expr, is_refutable, peel_blocks}; use rustc_errors::Applicability; use rustc_hir::{Arm, Expr, ExprKind, Node, PatKind}; @@ -24,21 +23,25 @@ pub(crate) fn check<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], e let matched_vars = ex.span; let bind_names = arms[0].pat.span; let match_body = peel_blocks(arms[0].body); - let mut snippet_body = if match_body.span.from_expansion() { - Sugg::hir_with_macro_callsite(cx, match_body, "..").to_string() - } else { - snippet_block(cx, match_body.span, "..", Some(expr.span)).to_string() - }; + let mut app = Applicability::MaybeIncorrect; + let (snippet_body, from_macro) = snippet_block_with_context( + cx, + match_body.span, + arms[0].span.ctxt(), + "..", + Some(expr.span), + &mut app, + ); + let mut snippet_body = snippet_body.to_string(); // Do we need to add ';' to suggestion ? - if let ExprKind::Block(block, _) = match_body.kind { + if matches!(match_body.kind, ExprKind::Block(..)) { // macro + expr_ty(body) == () - if block.span.from_expansion() && cx.typeck_results().expr_ty(match_body).is_unit() { + if from_macro && cx.typeck_results().expr_ty(match_body).is_unit() { snippet_body.push(';'); } } - let mut applicability = Applicability::MaybeIncorrect; match arms[0].pat.kind { PatKind::Binding(..) | PatKind::Tuple(_, _) | PatKind::Struct(..) => { let (target_span, sugg) = match opt_parent_assign_span(cx, ex) { @@ -48,7 +51,7 @@ pub(crate) fn check<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], e (ex, expr), (bind_names, matched_vars), &snippet_body, - &mut applicability, + &mut app, Some(span), true, ); @@ -60,7 +63,7 @@ pub(crate) fn check<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], e "this assignment could be simplified", "consider removing the `match` expression", sugg, - applicability, + app, ); return; @@ -69,10 +72,10 @@ pub(crate) fn check<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], e span, format!( "let {} = {};\n{}let {} = {snippet_body};", - snippet_with_applicability(cx, bind_names, "..", &mut applicability), - snippet_with_applicability(cx, matched_vars, "..", &mut applicability), + snippet_with_applicability(cx, bind_names, "..", &mut app), + snippet_with_applicability(cx, matched_vars, "..", &mut app), " ".repeat(indent_of(cx, expr.span).unwrap_or(0)), - snippet_with_applicability(cx, pat_span, "..", &mut applicability) + snippet_with_applicability(cx, pat_span, "..", &mut app) ), ), None => { @@ -81,7 +84,7 @@ pub(crate) fn check<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], e (ex, expr), (bind_names, matched_vars), &snippet_body, - &mut applicability, + &mut app, None, true, ); @@ -96,7 +99,7 @@ pub(crate) fn check<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], e "this match could be written as a `let` statement", "consider using a `let` statement", sugg, - applicability, + app, ); }, PatKind::Wild => { @@ -106,7 +109,7 @@ pub(crate) fn check<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], e (ex, expr), (bind_names, matched_vars), &snippet_body, - &mut applicability, + &mut app, None, false, ); @@ -118,7 +121,7 @@ pub(crate) fn check<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], e "this match could be replaced by its scrutinee and body", "consider using the scrutinee and body instead", sugg, - applicability, + app, ); } else { span_lint_and_sugg( diff --git a/clippy_lints/src/matches/redundant_pattern_match.rs b/clippy_lints/src/matches/redundant_pattern_match.rs index 81bebff34c8..e8610670054 100644 --- a/clippy_lints/src/matches/redundant_pattern_match.rs +++ b/clippy_lints/src/matches/redundant_pattern_match.rs @@ -1,6 +1,6 @@ use super::REDUNDANT_PATTERN_MATCHING; use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::source::snippet; +use clippy_utils::source::{snippet, walk_span_to_context}; use clippy_utils::sugg::Sugg; use clippy_utils::ty::{is_type_diagnostic_item, needs_ordered_drop}; use clippy_utils::visitors::any_temporaries_need_ordered_drop; @@ -150,22 +150,25 @@ fn find_sugg_for_if_let<'tcx>( // if/while let ... = ... { ... } // ^^^^^^^^^^^^^^^^^^^^^^^^^^^ let expr_span = expr.span; + let ctxt = expr.span.ctxt(); // if/while let ... = ... { ... } - // ^^^ - let op_span = result_expr.span.source_callsite(); + // ^^^ + let Some(res_span) = walk_span_to_context(result_expr.span.source_callsite(), ctxt) else { + return; + }; // if/while let ... = ... { ... } - // ^^^^^^^^^^^^^^^^^^^ - let span = expr_span.until(op_span.shrink_to_hi()); + // ^^^^^^^^^^^^^^^^^^^^^^ + let span = expr_span.until(res_span.shrink_to_hi()); - let app = if needs_drop { + let mut app = if needs_drop { Applicability::MaybeIncorrect } else { Applicability::MachineApplicable }; - let sugg = Sugg::hir_with_macro_callsite(cx, result_expr, "_") + let sugg = Sugg::hir_with_context(cx, result_expr, ctxt, "_", &mut app) .maybe_par() .to_string(); diff --git a/clippy_lints/src/matches/single_match.rs b/clippy_lints/src/matches/single_match.rs index 19b49c44d57..ad47c13896c 100644 --- a/clippy_lints/src/matches/single_match.rs +++ b/clippy_lints/src/matches/single_match.rs @@ -67,8 +67,10 @@ fn report_single_pattern( els: Option<&Expr<'_>>, ) { let lint = if els.is_some() { SINGLE_MATCH_ELSE } else { SINGLE_MATCH }; + let ctxt = expr.span.ctxt(); + let mut app = Applicability::HasPlaceholders; let els_str = els.map_or(String::new(), |els| { - format!(" else {}", expr_block(cx, els, None, "..", Some(expr.span))) + format!(" else {}", expr_block(cx, els, ctxt, "..", Some(expr.span), &mut app)) }); let (pat, pat_ref_count) = peel_hir_pat_refs(arms[0].pat); @@ -103,7 +105,7 @@ fn report_single_pattern( // PartialEq for different reference counts may not exist. "&".repeat(ref_count_diff), snippet(cx, arms[0].pat.span, ".."), - expr_block(cx, arms[0].body, None, "..", Some(expr.span)), + expr_block(cx, arms[0].body, ctxt, "..", Some(expr.span), &mut app), ); (msg, sugg) } else { @@ -112,21 +114,13 @@ fn report_single_pattern( "if let {} = {} {}{els_str}", snippet(cx, arms[0].pat.span, ".."), snippet(cx, ex.span, ".."), - expr_block(cx, arms[0].body, None, "..", Some(expr.span)), + expr_block(cx, arms[0].body, ctxt, "..", Some(expr.span), &mut app), ); (msg, sugg) } }; - span_lint_and_sugg( - cx, - lint, - expr.span, - msg, - "try this", - sugg, - Applicability::HasPlaceholders, - ); + span_lint_and_sugg(cx, lint, expr.span, msg, "try this", sugg, app); } fn check_opt_like<'a>( diff --git a/clippy_lints/src/methods/bind_instead_of_map.rs b/clippy_lints/src/methods/bind_instead_of_map.rs index 4720a6e6888..8ddb912f90b 100644 --- a/clippy_lints/src/methods/bind_instead_of_map.rs +++ b/clippy_lints/src/methods/bind_instead_of_map.rs @@ -1,6 +1,6 @@ use super::{contains_return, BIND_INSTEAD_OF_MAP}; use clippy_utils::diagnostics::{multispan_sugg_with_applicability, span_lint_and_sugg, span_lint_and_then}; -use clippy_utils::source::{snippet, snippet_with_macro_callsite}; +use clippy_utils::source::{snippet, snippet_with_context}; use clippy_utils::{peel_blocks, visitors::find_all_ret_expressions}; use if_chain::if_chain; use rustc_errors::Applicability; @@ -77,11 +77,8 @@ pub(crate) trait BindInsteadOfMap { if !contains_return(inner_expr); if let Some(msg) = Self::lint_msg(cx); then { - let some_inner_snip = if inner_expr.span.from_expansion() { - snippet_with_macro_callsite(cx, inner_expr.span, "_") - } else { - snippet(cx, inner_expr.span, "_") - }; + let mut app = Applicability::MachineApplicable; + let some_inner_snip = snippet_with_context(cx, inner_expr.span, closure_expr.span.ctxt(), "_", &mut app).0; let closure_args_snip = snippet(cx, closure_args_span, ".."); let option_snip = snippet(cx, recv.span, ".."); @@ -93,7 +90,7 @@ pub(crate) trait BindInsteadOfMap { &msg, "try this", note, - Applicability::MachineApplicable, + app, ); true } else { diff --git a/clippy_lints/src/methods/clone_on_ref_ptr.rs b/clippy_lints/src/methods/clone_on_ref_ptr.rs index 355f53532e2..5e8ad0861f3 100644 --- a/clippy_lints/src/methods/clone_on_ref_ptr.rs +++ b/clippy_lints/src/methods/clone_on_ref_ptr.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::paths; -use clippy_utils::source::snippet_with_macro_callsite; +use clippy_utils::source::snippet_with_context; use clippy_utils::ty::{is_type_diagnostic_item, match_type}; use rustc_errors::Applicability; use rustc_hir as hir; @@ -33,7 +33,9 @@ pub(super) fn check( return; }; - let snippet = snippet_with_macro_callsite(cx, receiver.span, ".."); + // Sometimes unnecessary ::<_> after Rc/Arc/Weak + let mut app = Applicability::Unspecified; + let snippet = snippet_with_context(cx, receiver.span, expr.span.ctxt(), "..", &mut app).0; span_lint_and_sugg( cx, @@ -42,7 +44,7 @@ pub(super) fn check( "using `.clone()` on a ref-counted pointer", "try this", format!("{caller_type}::<{}>::clone(&{snippet})", subst.type_at(0)), - Applicability::Unspecified, // Sometimes unnecessary ::<_> after Rc/Arc/Weak + app, ); } } diff --git a/clippy_lints/src/methods/or_fun_call.rs b/clippy_lints/src/methods/or_fun_call.rs index 4460f38fcc1..7ce28ea93e0 100644 --- a/clippy_lints/src/methods/or_fun_call.rs +++ b/clippy_lints/src/methods/or_fun_call.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::eager_or_lazy::switch_to_lazy_eval; -use clippy_utils::source::{snippet, snippet_with_macro_callsite}; +use clippy_utils::source::snippet_with_context; use clippy_utils::ty::{implements_trait, is_type_diagnostic_item}; use clippy_utils::{contains_return, is_trait_item, last_path_segment}; use if_chain::if_chain; @@ -9,7 +9,6 @@ use rustc_hir as hir; use rustc_lint::LateContext; use rustc_span::source_map::Span; use rustc_span::symbol::{kw, sym, Symbol}; -use std::borrow::Cow; use super::OR_FUN_CALL; @@ -111,37 +110,24 @@ pub(super) fn check<'tcx>( if poss.contains(&name); then { + let ctxt = span.ctxt(); + let mut app = Applicability::HasPlaceholders; let sugg = { let (snippet_span, use_lambda) = match (fn_has_arguments, fun_span) { (false, Some(fun_span)) => (fun_span, false), _ => (arg.span, true), }; - let format_span = |span: Span| { - let not_macro_argument_snippet = snippet_with_macro_callsite(cx, span, ".."); - let snip = if not_macro_argument_snippet == "vec![]" { - let macro_expanded_snipped = snippet(cx, snippet_span, ".."); - match macro_expanded_snipped.strip_prefix("$crate::vec::") { - Some(stripped) => Cow::Owned(stripped.to_owned()), - None => macro_expanded_snipped, - } - } else { - not_macro_argument_snippet - }; - - snip.to_string() - }; - - let snip = format_span(snippet_span); + let snip = snippet_with_context(cx, snippet_span, ctxt, "..", &mut app).0; let snip = if use_lambda { let l_arg = if fn_has_arguments { "_" } else { "" }; format!("|{l_arg}| {snip}") } else { - snip + snip.into_owned() }; if let Some(f) = second_arg { - let f = format_span(f.span); + let f = snippet_with_context(cx, f.span, ctxt, "..", &mut app).0; format!("{snip}, {f}") } else { snip @@ -155,7 +141,7 @@ pub(super) fn check<'tcx>( &format!("use of `{name}` followed by a function call"), "try this", format!("{name}_{suffix}({sugg})"), - Applicability::HasPlaceholders, + app, ); } } diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs index 0705029a613..3752b9a946f 100644 --- a/clippy_lints/src/misc.rs +++ b/clippy_lints/src/misc.rs @@ -1,5 +1,5 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_hir_and_then}; -use clippy_utils::source::{snippet, snippet_opt}; +use clippy_utils::source::{snippet, snippet_opt, snippet_with_context}; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::intravisit::FnKind; @@ -181,20 +181,17 @@ impl<'tcx> LateLintPass<'tcx> for LintPass { if let PatKind::Binding(BindingAnnotation(ByRef::Yes, mutabl), .., name, None) = local.pat.kind; if let Some(init) = local.init; then { - // use the macro callsite when the init span (but not the whole local span) - // comes from an expansion like `vec![1, 2, 3]` in `let ref _ = vec![1, 2, 3];` - let sugg_init = if init.span.from_expansion() && !local.span.from_expansion() { - Sugg::hir_with_macro_callsite(cx, init, "..") - } else { - Sugg::hir(cx, init, "..") - }; + let ctxt = local.span.ctxt(); + let mut app = Applicability::MachineApplicable; + let sugg_init = Sugg::hir_with_context(cx, init, ctxt, "..", &mut app); let (mutopt, initref) = if mutabl == Mutability::Mut { ("mut ", sugg_init.mut_addr()) } else { ("", sugg_init.addr()) }; let tyopt = if let Some(ty) = local.ty { - format!(": &{mutopt}{ty}", ty=snippet(cx, ty.span, "..")) + let ty_snip = snippet_with_context(cx, ty.span, ctxt, "_", &mut app).0; + format!(": &{mutopt}{ty_snip}") } else { String::new() }; @@ -212,7 +209,7 @@ impl<'tcx> LateLintPass<'tcx> for LintPass { "let {name}{tyopt} = {initref};", name=snippet(cx, name.span, ".."), ), - Applicability::MachineApplicable, + app, ); } ); diff --git a/clippy_lints/src/needless_bool.rs b/clippy_lints/src/needless_bool.rs index a4eec95b371..c87059bf61d 100644 --- a/clippy_lints/src/needless_bool.rs +++ b/clippy_lints/src/needless_bool.rs @@ -340,18 +340,11 @@ fn suggest_bool_comparison<'a, 'tcx>( cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, expr: &Expr<'_>, - mut applicability: Applicability, + mut app: Applicability, message: &str, conv_hint: impl FnOnce(Sugg<'a>) -> Sugg<'a>, ) { - let hint = if expr.span.from_expansion() { - if applicability != Applicability::Unspecified { - applicability = Applicability::MaybeIncorrect; - } - Sugg::hir_with_macro_callsite(cx, expr, "..") - } else { - Sugg::hir_with_applicability(cx, expr, "..", &mut applicability) - }; + let hint = Sugg::hir_with_context(cx, expr, e.span.ctxt(), "..", &mut app); span_lint_and_sugg( cx, BOOL_COMPARISON, @@ -359,7 +352,7 @@ fn suggest_bool_comparison<'a, 'tcx>( message, "try simplifying it as shown", conv_hint(hint).to_string(), - applicability, + app, ); } diff --git a/clippy_lints/src/option_if_let_else.rs b/clippy_lints/src/option_if_let_else.rs index c5ea09590d3..bbbcda069c5 100644 --- a/clippy_lints/src/option_if_let_else.rs +++ b/clippy_lints/src/option_if_let_else.rs @@ -12,6 +12,7 @@ use rustc_hir::{ }; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::SyntaxContext; declare_clippy_lint! { /// ### What it does @@ -95,10 +96,10 @@ struct OptionOccurrence { none_expr: String, } -fn format_option_in_sugg(cx: &LateContext<'_>, cond_expr: &Expr<'_>, as_ref: bool, as_mut: bool) -> String { +fn format_option_in_sugg(cond_sugg: Sugg<'_>, as_ref: bool, as_mut: bool) -> String { format!( "{}{}", - Sugg::hir_with_macro_callsite(cx, cond_expr, "..").maybe_par(), + cond_sugg.maybe_par(), if as_mut { ".as_mut()" } else if as_ref { @@ -111,6 +112,7 @@ fn format_option_in_sugg(cx: &LateContext<'_>, cond_expr: &Expr<'_>, as_ref: boo fn try_get_option_occurrence<'tcx>( cx: &LateContext<'tcx>, + ctxt: SyntaxContext, pat: &Pat<'tcx>, expr: &Expr<'_>, if_then: &'tcx Expr<'_>, @@ -160,11 +162,23 @@ fn try_get_option_occurrence<'tcx>( } } + let mut app = Applicability::Unspecified; return Some(OptionOccurrence { - option: format_option_in_sugg(cx, cond_expr, as_ref, as_mut), + option: format_option_in_sugg( + Sugg::hir_with_context(cx, cond_expr, ctxt, "..", &mut app), + as_ref, + as_mut, + ), method_sugg: method_sugg.to_string(), - some_expr: format!("|{capture_mut}{capture_name}| {}", Sugg::hir_with_macro_callsite(cx, some_body, "..")), - none_expr: format!("{}{}", if method_sugg == "map_or" { "" } else { "|| " }, Sugg::hir_with_macro_callsite(cx, none_body, "..")), + some_expr: format!( + "|{capture_mut}{capture_name}| {}", + Sugg::hir_with_context(cx, some_body, ctxt, "..", &mut app), + ), + none_expr: format!( + "{}{}", + if method_sugg == "map_or" { "" } else { "|| " }, + Sugg::hir_with_context(cx, none_body, ctxt, "..", &mut app), + ), }); } } @@ -194,7 +208,7 @@ fn detect_option_if_let_else<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> }) = higher::IfLet::hir(cx, expr) { if !is_else_clause(cx.tcx, expr) { - return try_get_option_occurrence(cx, let_pat, let_expr, if_then, if_else); + return try_get_option_occurrence(cx, expr.span.ctxt(), let_pat, let_expr, if_then, if_else); } } None @@ -203,7 +217,7 @@ fn detect_option_if_let_else<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> fn detect_option_match<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> Option { if let ExprKind::Match(ex, arms, MatchSource::Normal) = expr.kind { if let Some((let_pat, if_then, if_else)) = try_convert_match(cx, arms) { - return try_get_option_occurrence(cx, let_pat, ex, if_then, if_else); + return try_get_option_occurrence(cx, expr.span.ctxt(), let_pat, ex, if_then, if_else); } } None diff --git a/clippy_lints/src/semicolon_if_nothing_returned.rs b/clippy_lints/src/semicolon_if_nothing_returned.rs index 66638eed998..355f907e257 100644 --- a/clippy_lints/src/semicolon_if_nothing_returned.rs +++ b/clippy_lints/src/semicolon_if_nothing_returned.rs @@ -1,7 +1,6 @@ use crate::rustc_lint::LintContext; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::source::snippet_with_macro_callsite; -use clippy_utils::sugg; +use clippy_utils::source::snippet_with_context; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::{Block, ExprKind}; @@ -44,7 +43,8 @@ impl<'tcx> LateLintPass<'tcx> for SemicolonIfNothingReturned { if let Some(expr) = block.expr; let t_expr = cx.typeck_results().expr_ty(expr); if t_expr.is_unit(); - if let snippet = snippet_with_macro_callsite(cx, expr.span, "}"); + let mut app = Applicability::MaybeIncorrect; + if let snippet = snippet_with_context(cx, expr.span, block.span.ctxt(), "}", &mut app).0; if !snippet.ends_with('}') && !snippet.ends_with(';'); if cx.sess().source_map().is_multiline(block.span); then { @@ -52,17 +52,14 @@ impl<'tcx> LateLintPass<'tcx> for SemicolonIfNothingReturned { if let ExprKind::DropTemps(..) = &expr.kind { return; } - - let sugg = sugg::Sugg::hir_with_macro_callsite(cx, expr, ".."); - let suggestion = format!("{sugg};"); span_lint_and_sugg( cx, SEMICOLON_IF_NOTHING_RETURNED, expr.span.source_callsite(), "consider adding a `;` to the last statement for consistent formatting", "add a `;` here", - suggestion, - Applicability::MaybeIncorrect, + format!("{snippet};"), + app, ); } } diff --git a/clippy_lints/src/unit_types/let_unit_value.rs b/clippy_lints/src/unit_types/let_unit_value.rs index d6167a62169..a0164fdfc1e 100644 --- a/clippy_lints/src/unit_types/let_unit_value.rs +++ b/clippy_lints/src/unit_types/let_unit_value.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::get_parent_node; -use clippy_utils::source::snippet_with_macro_callsite; +use clippy_utils::source::snippet_with_context; use clippy_utils::visitors::{for_each_local_assignment, for_each_value_source}; use core::ops::ControlFlow; use rustc_errors::Applicability; @@ -48,12 +48,13 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, local: &'tcx Local<'_>) { "this let-binding has unit value", |diag| { if let Some(expr) = &local.init { - let snip = snippet_with_macro_callsite(cx, expr.span, "()"); + let mut app = Applicability::MachineApplicable; + let snip = snippet_with_context(cx, expr.span, local.span.ctxt(), "()", &mut app).0; diag.span_suggestion( local.span, "omit the `let` binding", format!("{snip};"), - Applicability::MachineApplicable, // snippet + app, ); } }, diff --git a/clippy_lints/src/useless_conversion.rs b/clippy_lints/src/useless_conversion.rs index a95e7b61374..47f19557e58 100644 --- a/clippy_lints/src/useless_conversion.rs +++ b/clippy_lints/src/useless_conversion.rs @@ -1,5 +1,5 @@ use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg}; -use clippy_utils::source::{snippet, snippet_with_macro_callsite}; +use clippy_utils::source::{snippet, snippet_with_context}; use clippy_utils::sugg::Sugg; use clippy_utils::ty::{is_copy, is_type_diagnostic_item, same_type_and_consts}; use clippy_utils::{get_parent_expr, is_trait_method, match_def_path, path_to_local, paths}; @@ -68,15 +68,16 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion { let a = cx.typeck_results().expr_ty(e); let b = cx.typeck_results().expr_ty(recv); if same_type_and_consts(a, b) { - let sugg = snippet_with_macro_callsite(cx, recv.span, "").to_string(); + let mut app = Applicability::MachineApplicable; + let sugg = snippet_with_context(cx, recv.span, e.span.ctxt(), "", &mut app).0; span_lint_and_sugg( cx, USELESS_CONVERSION, e.span, &format!("useless conversion to the same type: `{b}`"), "consider removing `.into()`", - sugg, - Applicability::MachineApplicable, // snippet + sugg.into_owned(), + app, ); } } @@ -165,7 +166,8 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion { if same_type_and_consts(a, b); then { - let sugg = Sugg::hir_with_macro_callsite(cx, arg, "").maybe_par(); + let mut app = Applicability::MachineApplicable; + let sugg = Sugg::hir_with_context(cx, arg, e.span.ctxt(), "", &mut app).maybe_par(); let sugg_msg = format!("consider removing `{}()`", snippet(cx, path.span, "From::from")); span_lint_and_sugg( @@ -175,7 +177,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion { &format!("useless conversion to the same type: `{b}`"), &sugg_msg, sugg.to_string(), - Applicability::MachineApplicable, // snippet + app, ); } } diff --git a/clippy_utils/src/source.rs b/clippy_utils/src/source.rs index cd5dcfdaca3..62fa37660fa 100644 --- a/clippy_utils/src/source.rs +++ b/clippy_utils/src/source.rs @@ -12,24 +12,21 @@ use rustc_span::{BytePos, Pos, Span, SpanData, SyntaxContext, DUMMY_SP}; use std::borrow::Cow; /// Like `snippet_block`, but add braces if the expr is not an `ExprKind::Block`. -/// Also takes an `Option` which can be put inside the braces. -pub fn expr_block<'a, T: LintContext>( +pub fn expr_block( cx: &T, expr: &Expr<'_>, - option: Option, - default: &'a str, + outer: SyntaxContext, + default: &str, indent_relative_to: Option, -) -> Cow<'a, str> { - let code = snippet_block(cx, expr.span, default, indent_relative_to); - let string = option.unwrap_or_default(); - if expr.span.from_expansion() { - Cow::Owned(format!("{{ {} }}", snippet_with_macro_callsite(cx, expr.span, default))) + app: &mut Applicability, +) -> String { + let (code, from_macro) = snippet_block_with_context(cx, expr.span, outer, default, indent_relative_to, app); + if from_macro { + format!("{{ {code} }}") } else if let ExprKind::Block(_, _) = expr.kind { - Cow::Owned(format!("{code}{string}")) - } else if string.is_empty() { - Cow::Owned(format!("{{ {code} }}")) + format!("{code}") } else { - Cow::Owned(format!("{{\n{code};\n{string}\n}}")) + format!("{{ {code} }}") } } @@ -229,12 +226,6 @@ fn snippet_with_applicability_sess<'a>( ) } -/// Same as `snippet`, but should only be used when it's clear that the input span is -/// not a macro argument. -pub fn snippet_with_macro_callsite<'a, T: LintContext>(cx: &T, span: Span, default: &'a str) -> Cow<'a, str> { - snippet(cx, span.source_callsite(), default) -} - /// Converts a span to a code snippet. Returns `None` if not available. pub fn snippet_opt(cx: &impl LintContext, span: Span) -> Option { snippet_opt_sess(cx.sess(), span) @@ -303,6 +294,19 @@ pub fn snippet_block_with_applicability<'a>( reindent_multiline(snip, true, indent) } +pub fn snippet_block_with_context<'a>( + cx: &impl LintContext, + span: Span, + outer: SyntaxContext, + default: &'a str, + indent_relative_to: Option, + app: &mut Applicability, +) -> (Cow<'a, str>, bool) { + let (snip, from_macro) = snippet_with_context(cx, span, outer, default, app); + let indent = indent_relative_to.and_then(|s| indent_of(cx, s)); + (reindent_multiline(snip, true, indent), from_macro) +} + /// Same as `snippet_with_applicability`, but first walks the span up to the given context. This /// will result in the macro call, rather then the expansion, if the span is from a child context. /// If the span is not from a child context, it will be used directly instead. diff --git a/clippy_utils/src/sugg.rs b/clippy_utils/src/sugg.rs index 51e270d330c..8e3ee22a765 100644 --- a/clippy_utils/src/sugg.rs +++ b/clippy_utils/src/sugg.rs @@ -1,9 +1,7 @@ //! Contains utility functions to generate suggestions. #![deny(clippy::missing_docs_in_private_items)] -use crate::source::{ - snippet, snippet_opt, snippet_with_applicability, snippet_with_context, snippet_with_macro_callsite, -}; +use crate::source::{snippet, snippet_opt, snippet_with_applicability, snippet_with_context}; use crate::ty::expr_sig; use crate::{get_parent_expr_for_hir, higher}; use rustc_ast::util::parser::AssocOp; @@ -89,12 +87,6 @@ impl<'a> Sugg<'a> { }) } - /// Same as `hir`, but will use the pre expansion span if the `expr` was in a macro. - pub fn hir_with_macro_callsite(cx: &LateContext<'_>, expr: &hir::Expr<'_>, default: &'a str) -> Self { - let get_snippet = |span| snippet_with_macro_callsite(cx, span, default); - Self::hir_from_snippet(expr, get_snippet) - } - /// Same as `hir`, but first walks the span up to the given context. This will result in the /// macro call, rather then the expansion, if the span is from a child context. If the span is /// not from a child context, it will be used directly instead. diff --git a/tests/ui/redundant_pattern_matching_result.fixed b/tests/ui/redundant_pattern_matching_result.fixed index b88c5d0bec8..42348df4480 100644 --- a/tests/ui/redundant_pattern_matching_result.fixed +++ b/tests/ui/redundant_pattern_matching_result.fixed @@ -69,8 +69,8 @@ fn issue5504() { } fn try_result_opt() -> Result { - while (r#try!(result_opt())).is_some() {} - if (r#try!(result_opt())).is_some() {} + while r#try!(result_opt()).is_some() {} + if r#try!(result_opt()).is_some() {} Ok(42) } diff --git a/tests/ui/redundant_pattern_matching_result.stderr b/tests/ui/redundant_pattern_matching_result.stderr index e6afe9eb78e..d6a46babb77 100644 --- a/tests/ui/redundant_pattern_matching_result.stderr +++ b/tests/ui/redundant_pattern_matching_result.stderr @@ -88,13 +88,13 @@ error: redundant pattern matching, consider using `is_some()` --> $DIR/redundant_pattern_matching_result.rs:84:19 | LL | while let Some(_) = r#try!(result_opt()) {} - | ----------^^^^^^^----------------------- help: try this: `while (r#try!(result_opt())).is_some()` + | ----------^^^^^^^----------------------- help: try this: `while r#try!(result_opt()).is_some()` error: redundant pattern matching, consider using `is_some()` --> $DIR/redundant_pattern_matching_result.rs:85:16 | LL | if let Some(_) = r#try!(result_opt()) {} - | -------^^^^^^^----------------------- help: try this: `if (r#try!(result_opt())).is_some()` + | -------^^^^^^^----------------------- help: try this: `if r#try!(result_opt()).is_some()` error: redundant pattern matching, consider using `is_some()` --> $DIR/redundant_pattern_matching_result.rs:91:12 From 90afb207eb14e22cc60cea3591509ae568d41c62 Mon Sep 17 00:00:00 2001 From: Arpad Borsos Date: Thu, 24 Nov 2022 17:58:32 +0100 Subject: [PATCH 015/346] Remove `identity_future` indirection This was previously needed because the indirection used to hide some unexplained lifetime errors, which it turned out were related to the `min_choice` algorithm. Removing the indirection also solves a couple of cycle errors, large moves and makes async blocks support the `#[track_caller]` annotation. --- clippy_lints/src/manual_async_fn.rs | 9 +-------- clippy_utils/src/lib.rs | 11 +---------- tests/ui/author/blocks.stdout | 6 +----- 3 files changed, 3 insertions(+), 23 deletions(-) diff --git a/clippy_lints/src/manual_async_fn.rs b/clippy_lints/src/manual_async_fn.rs index 3778eb4c732..f97c6bcb5d1 100644 --- a/clippy_lints/src/manual_async_fn.rs +++ b/clippy_lints/src/manual_async_fn.rs @@ -1,5 +1,4 @@ use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::match_function_call_with_def_id; use clippy_utils::source::{position_before_rarrow, snippet_block, snippet_opt}; use if_chain::if_chain; use rustc_errors::Applicability; @@ -175,16 +174,10 @@ fn captures_all_lifetimes(inputs: &[Ty<'_>], output_lifetimes: &[LifetimeName]) fn desugared_async_block<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) -> Option<&'tcx Body<'tcx>> { if_chain! { if let Some(block_expr) = block.expr; - if let Some(args) = cx - .tcx - .lang_items() - .identity_future_fn() - .and_then(|def_id| match_function_call_with_def_id(cx, block_expr, def_id)); - if args.len() == 1; if let Expr { kind: ExprKind::Closure(&Closure { body, .. }), .. - } = args[0]; + } = block_expr; let closure_body = cx.tcx.hir().body(body); if closure_body.generator_kind == Some(GeneratorKind::Async(AsyncGeneratorKind::Block)); then { diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index f02f8ecb43d..8edfd2eff72 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -1904,16 +1904,7 @@ pub fn is_async_fn(kind: FnKind<'_>) -> bool { /// Peels away all the compiler generated code surrounding the body of an async function, pub fn get_async_fn_body<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'_>) -> Option<&'tcx Expr<'tcx>> { - if let ExprKind::Call( - _, - &[ - Expr { - kind: ExprKind::Closure(&Closure { body, .. }), - .. - }, - ], - ) = body.value.kind - { + if let ExprKind::Closure(&Closure { body, .. }) = body.value.kind { if let ExprKind::Block( Block { stmts: [], diff --git a/tests/ui/author/blocks.stdout b/tests/ui/author/blocks.stdout index c6acf24c21e..eb3e5189c82 100644 --- a/tests/ui/author/blocks.stdout +++ b/tests/ui/author/blocks.stdout @@ -43,11 +43,7 @@ if let ExprKind::Block(block, None) = expr.kind if let ExprKind::Closure(CaptureBy::Value, fn_decl, body_id, _, None) = expr.kind && let FnRetTy::DefaultReturn(_) = fn_decl.output && expr1 = &cx.tcx.hir().body(body_id).value - && let ExprKind::Call(func, args) = expr1.kind - && let ExprKind::Path(ref qpath) = func.kind - && matches!(qpath, QPath::LangItem(LangItem::IdentityFuture, _)) - && args.len() == 1 - && let ExprKind::Closure(CaptureBy::Value, fn_decl1, body_id1, _, Some(Movability::Static)) = args[0].kind + && let ExprKind::Closure(CaptureBy::Value, fn_decl1, body_id1, _, Some(Movability::Static)) = expr1.kind && let FnRetTy::DefaultReturn(_) = fn_decl1.output && expr2 = &cx.tcx.hir().body(body_id1).value && let ExprKind::Block(block, None) = expr2.kind From e66e918bd316c407c605d541343255f0d66e7a7b Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 7 Mar 2023 17:51:48 +0000 Subject: [PATCH 016/346] Fortify clippy tests. --- tests/ui/erasing_op.rs | 8 +++++--- tests/ui/erasing_op.stderr | 10 +++++----- tests/ui/integer_arithmetic.rs | 2 +- tests/ui/overflow_check_conditional.rs | 9 +++++---- tests/ui/overflow_check_conditional.stderr | 16 ++++++++-------- 5 files changed, 24 insertions(+), 21 deletions(-) diff --git a/tests/ui/erasing_op.rs b/tests/ui/erasing_op.rs index ae2fad0086d..74985029e00 100644 --- a/tests/ui/erasing_op.rs +++ b/tests/ui/erasing_op.rs @@ -31,9 +31,7 @@ impl core::ops::Mul for Vec1 { #[allow(clippy::no_effect)] #[warn(clippy::erasing_op)] -fn main() { - let x: u8 = 0; - +fn test(x: u8) { x * 0; 0 & x; 0 / x; @@ -41,3 +39,7 @@ fn main() { 0 * Vec1 { x: 5 }; Vec1 { x: 5 } * 0; } + +fn main() { + test(0) +} diff --git a/tests/ui/erasing_op.stderr b/tests/ui/erasing_op.stderr index 165ed9bfe58..97941252355 100644 --- a/tests/ui/erasing_op.stderr +++ b/tests/ui/erasing_op.stderr @@ -1,5 +1,5 @@ error: this operation will always return zero. This is likely not the intended outcome - --> $DIR/erasing_op.rs:37:5 + --> $DIR/erasing_op.rs:35:5 | LL | x * 0; | ^^^^^ @@ -7,25 +7,25 @@ LL | x * 0; = note: `-D clippy::erasing-op` implied by `-D warnings` error: this operation will always return zero. This is likely not the intended outcome - --> $DIR/erasing_op.rs:38:5 + --> $DIR/erasing_op.rs:36:5 | LL | 0 & x; | ^^^^^ error: this operation will always return zero. This is likely not the intended outcome - --> $DIR/erasing_op.rs:39:5 + --> $DIR/erasing_op.rs:37:5 | LL | 0 / x; | ^^^^^ error: this operation will always return zero. This is likely not the intended outcome - --> $DIR/erasing_op.rs:41:5 + --> $DIR/erasing_op.rs:39:5 | LL | 0 * Vec1 { x: 5 }; | ^^^^^^^^^^^^^^^^^ error: this operation will always return zero. This is likely not the intended outcome - --> $DIR/erasing_op.rs:42:5 + --> $DIR/erasing_op.rs:40:5 | LL | Vec1 { x: 5 } * 0; | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/integer_arithmetic.rs b/tests/ui/integer_arithmetic.rs index 67f24b4548a..8dfdee662b9 100644 --- a/tests/ui/integer_arithmetic.rs +++ b/tests/ui/integer_arithmetic.rs @@ -4,7 +4,7 @@ #[rustfmt::skip] fn main() { let mut i = 1i32; - let mut var1 = 0i32; + let mut var1 = 13i32; let mut var2 = -1i32; 1 + i; i * 2; diff --git a/tests/ui/overflow_check_conditional.rs b/tests/ui/overflow_check_conditional.rs index 5db75f5291b..e1e30114081 100644 --- a/tests/ui/overflow_check_conditional.rs +++ b/tests/ui/overflow_check_conditional.rs @@ -1,9 +1,6 @@ #![warn(clippy::overflow_check_conditional)] -fn main() { - let a: u32 = 1; - let b: u32 = 2; - let c: u32 = 3; +fn test(a: u32, b: u32, c: u32) { if a + b < a {} if a > a + b {} if a + b < b {} @@ -23,3 +20,7 @@ fn main() { if i > i + j {} if i - j < i {} } + +fn main() { + test(1, 2, 3) +} diff --git a/tests/ui/overflow_check_conditional.stderr b/tests/ui/overflow_check_conditional.stderr index 1b8b146b60a..92d1d8ef911 100644 --- a/tests/ui/overflow_check_conditional.stderr +++ b/tests/ui/overflow_check_conditional.stderr @@ -1,5 +1,5 @@ error: you are trying to use classic C overflow conditions that will fail in Rust - --> $DIR/overflow_check_conditional.rs:7:8 + --> $DIR/overflow_check_conditional.rs:4:8 | LL | if a + b < a {} | ^^^^^^^^^ @@ -7,43 +7,43 @@ LL | if a + b < a {} = note: `-D clippy::overflow-check-conditional` implied by `-D warnings` error: you are trying to use classic C overflow conditions that will fail in Rust - --> $DIR/overflow_check_conditional.rs:8:8 + --> $DIR/overflow_check_conditional.rs:5:8 | LL | if a > a + b {} | ^^^^^^^^^ error: you are trying to use classic C overflow conditions that will fail in Rust - --> $DIR/overflow_check_conditional.rs:9:8 + --> $DIR/overflow_check_conditional.rs:6:8 | LL | if a + b < b {} | ^^^^^^^^^ error: you are trying to use classic C overflow conditions that will fail in Rust - --> $DIR/overflow_check_conditional.rs:10:8 + --> $DIR/overflow_check_conditional.rs:7:8 | LL | if b > a + b {} | ^^^^^^^^^ error: you are trying to use classic C underflow conditions that will fail in Rust - --> $DIR/overflow_check_conditional.rs:11:8 + --> $DIR/overflow_check_conditional.rs:8:8 | LL | if a - b > b {} | ^^^^^^^^^ error: you are trying to use classic C underflow conditions that will fail in Rust - --> $DIR/overflow_check_conditional.rs:12:8 + --> $DIR/overflow_check_conditional.rs:9:8 | LL | if b < a - b {} | ^^^^^^^^^ error: you are trying to use classic C underflow conditions that will fail in Rust - --> $DIR/overflow_check_conditional.rs:13:8 + --> $DIR/overflow_check_conditional.rs:10:8 | LL | if a - b > a {} | ^^^^^^^^^ error: you are trying to use classic C underflow conditions that will fail in Rust - --> $DIR/overflow_check_conditional.rs:14:8 + --> $DIR/overflow_check_conditional.rs:11:8 | LL | if a < a - b {} | ^^^^^^^^^ From 3d229d535c416787a9541bb26cb5f928d4a38a0d Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Tue, 15 Nov 2022 12:09:31 +0100 Subject: [PATCH 017/346] avoid reuse tripping over copyright notices --- COPYRIGHT | 4 ++++ README.md | 4 ++++ rustc_tools_util/README.md | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/COPYRIGHT b/COPYRIGHT index a6be75b5e31..82703b18fd7 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -1,3 +1,5 @@ +// REUSE-IgnoreStart + Copyright 2014-2022 The Rust Project Developers Licensed under the Apache License, Version 2.0 or the MIT license , at your option. All files in the project carrying such notice may not be copied, modified, or distributed except according to those terms. + +// REUSE-IgnoreEnd diff --git a/README.md b/README.md index 3e7379ace7e..b69ed8900a4 100644 --- a/README.md +++ b/README.md @@ -275,6 +275,8 @@ If you want to contribute to Clippy, you can find more information in [CONTRIBUT ## License + + Copyright 2014-2022 The Rust Project Developers Licensed under the Apache License, Version 2.0 , at your option. Files in the project may not be copied, modified, or distributed except according to those terms. + + diff --git a/rustc_tools_util/README.md b/rustc_tools_util/README.md index eefc661f963..e197ea048a0 100644 --- a/rustc_tools_util/README.md +++ b/rustc_tools_util/README.md @@ -49,6 +49,8 @@ The changelog for `rustc_tools_util` is available under: ## License + + Copyright 2014-2022 The Rust Project Developers Licensed under the Apache License, Version 2.0 or the MIT license , at your option. All files in the project carrying such notice may not be copied, modified, or distributed except according to those terms. + + From 27910cbcbdf76afb93e769ac66efa76271f964b0 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 6 Sep 2022 18:41:01 +0200 Subject: [PATCH 018/346] Introduce a no-op PlaceMention statement for `let _ =`. --- clippy_utils/src/qualify_min_const_fn.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/clippy_utils/src/qualify_min_const_fn.rs b/clippy_utils/src/qualify_min_const_fn.rs index c00800291db..24403e8b6f3 100644 --- a/clippy_utils/src/qualify_min_const_fn.rs +++ b/clippy_utils/src/qualify_min_const_fn.rs @@ -241,6 +241,7 @@ fn check_statement<'tcx>( | StatementKind::StorageDead(_) | StatementKind::Retag { .. } | StatementKind::AscribeUserType(..) + | StatementKind::PlaceMention(..) | StatementKind::Coverage(..) | StatementKind::ConstEvalCounter | StatementKind::Nop => Ok(()), From cf8a67d9ad81547895ec986f8bcb17e912037c38 Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Fri, 10 Mar 2023 10:53:50 +0100 Subject: [PATCH 019/346] Merge commit '3c06e0b1ce003912f8fe0536d3a7fe22558e38cf' into clippyup --- CHANGELOG.md | 153 +++++++++- Cargo.toml | 2 +- .../proposals/syntax-tree-patterns.md | 14 +- clippy_lints/Cargo.toml | 2 +- clippy_lints/src/almost_complete_range.rs | 2 +- .../src/casts/cast_slice_from_raw_parts.rs | 8 +- clippy_lints/src/collection_is_never_read.rs | 122 ++++++++ clippy_lints/src/declared_lints.rs | 4 + .../src/default_instead_of_iter_empty.rs | 16 +- clippy_lints/src/dereference.rs | 8 +- clippy_lints/src/derivable_impls.rs | 21 +- clippy_lints/src/exit.rs | 2 +- clippy_lints/src/fn_null_check.rs | 2 +- clippy_lints/src/format.rs | 6 +- .../src/functions/impl_trait_in_params.rs | 4 +- .../src/functions/misnamed_getters.rs | 2 +- clippy_lints/src/functions/mod.rs | 2 +- clippy_lints/src/implicit_saturating_add.rs | 16 +- clippy_lints/src/instant_subtraction.rs | 13 +- clippy_lints/src/len_zero.rs | 125 ++++++-- clippy_lints/src/let_underscore.rs | 2 +- clippy_lints/src/let_with_type_underscore.rs | 45 +++ clippy_lints/src/lib.rs | 9 + clippy_lints/src/manual_bits.rs | 11 +- clippy_lints/src/manual_is_ascii_check.rs | 15 +- clippy_lints/src/manual_rem_euclid.rs | 8 +- clippy_lints/src/match_result_ok.rs | 25 +- clippy_lints/src/matches/mod.rs | 2 +- clippy_lints/src/methods/mod.rs | 5 +- clippy_lints/src/missing_assert_message.rs | 82 +++++ clippy_lints/src/missing_doc.rs | 10 +- .../src/multiple_unsafe_ops_per_block.rs | 37 +-- clippy_lints/src/neg_multiply.rs | 6 +- .../src/non_octal_unix_permissions.rs | 2 + .../src/operators/arithmetic_side_effects.rs | 13 +- .../src/permissions_set_readonly_false.rs | 2 +- clippy_lints/src/redundant_async_block.rs | 84 +++++ clippy_lints/src/size_of_ref.rs | 2 +- clippy_lints/src/swap.rs | 111 ++++--- clippy_lints/src/transmute/mod.rs | 2 +- clippy_lints/src/unit_types/let_unit_value.rs | 6 +- clippy_lints/src/use_self.rs | 15 +- clippy_lints/src/utils/author.rs | 2 +- .../src/utils/format_args_collector.rs | 23 ++ .../internal_lints/metadata_collector.rs | 7 +- clippy_lints/src/utils/mod.rs | 1 + clippy_lints/src/write.rs | 148 +++++---- clippy_utils/Cargo.toml | 2 +- clippy_utils/src/lib.rs | 2 +- clippy_utils/src/macros.rs | 117 ++++++- clippy_utils/src/ty.rs | 6 +- declare_clippy_lint/Cargo.toml | 2 +- lintcheck/Cargo.toml | 14 +- lintcheck/README.md | 9 + lintcheck/src/config.rs | 160 ++++------ lintcheck/src/popular-crates.rs | 65 ++++ rust-toolchain | 2 +- src/driver.rs | 2 +- src/main.rs | 2 +- tests/dogfood.rs | 19 +- tests/ui/arithmetic_side_effects.rs | 28 ++ tests/ui/arithmetic_side_effects.stderr | 288 ++++++++++-------- tests/ui/async_yields_async.fixed | 1 + tests/ui/async_yields_async.rs | 1 + tests/ui/async_yields_async.stderr | 12 +- tests/ui/collection_is_never_read.rs | 165 ++++++++++ tests/ui/collection_is_never_read.stderr | 52 ++++ tests/ui/crashes/ice-10148.rs | 9 + tests/ui/crashes/ice-10148.stderr | 12 + tests/ui/crashes/ice-6179.rs | 2 +- tests/ui/crashes/ice-rust-107877.rs | 17 ++ tests/ui/default_numeric_fallback_f64.fixed | 3 +- tests/ui/default_numeric_fallback_f64.rs | 3 +- tests/ui/default_numeric_fallback_f64.stderr | 48 +-- tests/ui/default_numeric_fallback_i32.fixed | 3 +- tests/ui/default_numeric_fallback_i32.rs | 3 +- tests/ui/default_numeric_fallback_i32.stderr | 52 ++-- tests/ui/derivable_impls.fixed | 37 +++ tests/ui/derivable_impls.rs | 37 +++ tests/ui/format.fixed | 6 - tests/ui/format.rs | 6 - tests/ui/format.stderr | 30 +- tests/ui/impl_trait_in_params.stderr | 4 +- tests/ui/implicit_clone.fixed | 2 +- tests/ui/implicit_clone.rs | 2 +- tests/ui/len_without_is_empty.rs | 92 ++++++ tests/ui/len_without_is_empty.stderr | 20 +- tests/ui/let_unit.fixed | 4 + tests/ui/let_unit.rs | 4 + tests/ui/let_with_type_underscore.rs | 19 ++ tests/ui/let_with_type_underscore.stderr | 39 +++ tests/ui/manual_rem_euclid.fixed | 1 + tests/ui/manual_rem_euclid.rs | 1 + tests/ui/manual_rem_euclid.stderr | 20 +- tests/ui/match_result_ok.fixed | 2 +- tests/ui/match_result_ok.stderr | 2 +- tests/ui/missing_assert_message.rs | 84 +++++ tests/ui/missing_assert_message.stderr | 131 ++++++++ tests/ui/missing_doc.stderr | 70 +---- tests/ui/missing_doc_impl.stderr | 56 +--- tests/ui/multiple_unsafe_ops_per_block.rs | 28 ++ tests/ui/multiple_unsafe_ops_per_block.stderr | 62 +++- tests/ui/new_ret_no_self.rs | 2 +- tests/ui/redundant_async_block.fixed | 64 ++++ tests/ui/redundant_async_block.rs | 64 ++++ tests/ui/redundant_async_block.stderr | 28 ++ tests/ui/redundant_closure_call_fixable.fixed | 1 + tests/ui/redundant_closure_call_fixable.rs | 1 + .../ui/redundant_closure_call_fixable.stderr | 12 +- tests/ui/swap.fixed | 6 +- tests/ui/swap.stderr | 24 +- tests/ui/trailing_empty_array.rs | 2 - tests/ui/use_self.fixed | 10 + tests/ui/use_self.rs | 10 + 114 files changed, 2508 insertions(+), 775 deletions(-) create mode 100644 clippy_lints/src/collection_is_never_read.rs create mode 100644 clippy_lints/src/let_with_type_underscore.rs create mode 100644 clippy_lints/src/missing_assert_message.rs create mode 100644 clippy_lints/src/redundant_async_block.rs create mode 100644 clippy_lints/src/utils/format_args_collector.rs create mode 100644 lintcheck/src/popular-crates.rs create mode 100644 tests/ui/collection_is_never_read.rs create mode 100644 tests/ui/collection_is_never_read.stderr create mode 100644 tests/ui/crashes/ice-10148.rs create mode 100644 tests/ui/crashes/ice-10148.stderr create mode 100644 tests/ui/crashes/ice-rust-107877.rs create mode 100644 tests/ui/let_with_type_underscore.rs create mode 100644 tests/ui/let_with_type_underscore.stderr create mode 100644 tests/ui/missing_assert_message.rs create mode 100644 tests/ui/missing_assert_message.stderr create mode 100644 tests/ui/redundant_async_block.fixed create mode 100644 tests/ui/redundant_async_block.rs create mode 100644 tests/ui/redundant_async_block.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index 765826ed867..0abe234fc8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,11 +6,156 @@ document. ## Unreleased / Beta / In Rust Nightly -[d822110d...master](https://github.com/rust-lang/rust-clippy/compare/d822110d...master) +[7f27e2e7...master](https://github.com/rust-lang/rust-clippy/compare/7f27e2e7...master) + +## Rust 1.68 + +Current stable, released 2023-03-09 + +[d822110d...7f27e2e7](https://github.com/rust-lang/rust-clippy/compare/d822110d...7f27e2e7) + +### New Lints + +* [`permissions_set_readonly_false`] + [#10063](https://github.com/rust-lang/rust-clippy/pull/10063) +* [`almost_complete_range`] + [#10043](https://github.com/rust-lang/rust-clippy/pull/10043) +* [`size_of_ref`] + [#10098](https://github.com/rust-lang/rust-clippy/pull/10098) +* [`semicolon_outside_block`] + [#9826](https://github.com/rust-lang/rust-clippy/pull/9826) +* [`semicolon_inside_block`] + [#9826](https://github.com/rust-lang/rust-clippy/pull/9826) +* [`transmute_null_to_fn`] + [#10099](https://github.com/rust-lang/rust-clippy/pull/10099) +* [`fn_null_check`] + [#10099](https://github.com/rust-lang/rust-clippy/pull/10099) + +### Moves and Deprecations + +* Moved [`manual_clamp`] to `nursery` (Now allow-by-default) + [#10101](https://github.com/rust-lang/rust-clippy/pull/10101) +* Moved [`mutex_atomic`] to `restriction` + [#10115](https://github.com/rust-lang/rust-clippy/pull/10115) +* Renamed `derive_hash_xor_eq` to [`derived_hash_with_manual_eq`] + [#10184](https://github.com/rust-lang/rust-clippy/pull/10184) + +### Enhancements + +* [`collapsible_str_replace`]: Now takes MSRV into consideration. The minimal version is 1.58 + [#10047](https://github.com/rust-lang/rust-clippy/pull/10047) +* [`unused_self`]: No longer lints, if the method body contains a `todo!()` call + [#10166](https://github.com/rust-lang/rust-clippy/pull/10166) +* [`derivable_impls`]: Now suggests deriving `Default` for enums with default unit variants + [#10161](https://github.com/rust-lang/rust-clippy/pull/10161) +* [`arithmetic_side_effects`]: Added two new config values + `arithmetic-side-effects-allowed-binary` and `arithmetic-side-effects-allowed-unary` + to allow operation on user types + [#9840](https://github.com/rust-lang/rust-clippy/pull/9840) +* [`large_const_arrays`], [`large_stack_arrays`]: avoid integer overflow when calculating + total array size + [#10103](https://github.com/rust-lang/rust-clippy/pull/10103) +* [`indexing_slicing`]: add new config `suppress-restriction-lint-in-const` to enable + restriction lints, even if the suggestion might not be applicable + [#9920](https://github.com/rust-lang/rust-clippy/pull/9920) +* [`needless_borrow`], [`redundant_clone`]: Now track references better and detect more cases + [#9701](https://github.com/rust-lang/rust-clippy/pull/9701) +* [`derived_hash_with_manual_eq`]: Now allows `#[derive(PartialEq)]` with custom `Hash` + implementations + [#10184](https://github.com/rust-lang/rust-clippy/pull/10184) +* [`manual_is_ascii_check`]: Now detects ranges with `.contains()` calls + [#10053](https://github.com/rust-lang/rust-clippy/pull/10053) +* [`transmuting_null`]: Now detects `const` pointers to all types + [#10099](https://github.com/rust-lang/rust-clippy/pull/10099) +* [`needless_return`]: Now detects more cases for returns of owned values + [#10110](https://github.com/rust-lang/rust-clippy/pull/10110) + +### False Positive Fixes + +* [`field_reassign_with_default`]: No longer lints cases, where values are initializes from + closures capturing struct values + [#10143](https://github.com/rust-lang/rust-clippy/pull/10143) +* [`seek_to_start_instead_of_rewind`]: No longer lints, if the return of `seek` is used. + [#10096](https://github.com/rust-lang/rust-clippy/pull/10096) +* [`manual_filter`]: Now ignores if expressions where the else branch has side effects or + doesn't return `None` + [#10091](https://github.com/rust-lang/rust-clippy/pull/10091) +* [`implicit_clone`]: No longer lints if the type doesn't implement clone + [#10022](https://github.com/rust-lang/rust-clippy/pull/10022) +* [`match_wildcard_for_single_variants`]: No longer lints on wildcards with a guard + [#10056](https://github.com/rust-lang/rust-clippy/pull/10056) +* [`drop_ref`]: No longer lints idiomatic expression in `match` arms + [#10142](https://github.com/rust-lang/rust-clippy/pull/10142) +* [`arithmetic_side_effects`]: No longer lints on corner cases with negative number literals + [#9867](https://github.com/rust-lang/rust-clippy/pull/9867) +* [`string_lit_as_bytes`]: No longer lints in scrutinies of `match` statements + [#10012](https://github.com/rust-lang/rust-clippy/pull/10012) +* [`manual_assert`]: No longer lints in `else if` statements + [#10013](https://github.com/rust-lang/rust-clippy/pull/10013) +* [`needless_return`]: don't lint when using `do yeet` + [#10109](https://github.com/rust-lang/rust-clippy/pull/10109) +* All lints: No longer lint in enum discriminant values when the suggestion won't work in a + const context + [#10008](https://github.com/rust-lang/rust-clippy/pull/10008) +* [`single_element_loop`]: No longer lints, if the loop contains a `break` or `continue` + [#10162](https://github.com/rust-lang/rust-clippy/pull/10162) +* [`uninlined_format_args`]: No longer suggests inlining arguments in `assert!` and + `debug_assert!` macros before 2021 edition + [#10055](https://github.com/rust-lang/rust-clippy/pull/10055) +* [`explicit_counter_loop`]: No longer ignores counter changes after `continue` expressions + [#10094](https://github.com/rust-lang/rust-clippy/pull/10094) +* [`from_over_into`]: No longer lints on opaque types + [#9982](https://github.com/rust-lang/rust-clippy/pull/9982) +* [`expl_impl_clone_on_copy`]: No longer lints on `#[repr(packed)]` structs with generic + parameters + [#10189](https://github.com/rust-lang/rust-clippy/pull/10189) + +### Suggestion Fixes/Improvements + +* [`zero_ptr`]: Now suggests `core::` paths for `no_std` crates + [#10023](https://github.com/rust-lang/rust-clippy/pull/10023) +* [`useless_conversion`]: Now suggests removing calls to `into_iter()` on an expression + implementing `Iterator` + [#10020](https://github.com/rust-lang/rust-clippy/pull/10020) +* [`box_default`]: The suggestion now uses short paths + [#10153](https://github.com/rust-lang/rust-clippy/pull/10153) +* [`default_trait_access`], [`clone_on_copy`]: The suggestion now uses short paths + [#10160](https://github.com/rust-lang/rust-clippy/pull/10160) +* [`comparison_to_empty`]: The suggestion now removes unused deref operations + [#9962](https://github.com/rust-lang/rust-clippy/pull/9962) +* [`manual_let_else`]: Suggestions for or-patterns now include required brackets. + [#9966](https://github.com/rust-lang/rust-clippy/pull/9966) +* [`match_single_binding`]: suggestion no longer introduces unneeded semicolons + [#10060](https://github.com/rust-lang/rust-clippy/pull/10060) +* [`case_sensitive_file_extension_comparisons`]: Now displays a suggestion with `Path` + [#10107](https://github.com/rust-lang/rust-clippy/pull/10107) +* [`empty_structs_with_brackets`]: The suggestion is no longer machine applicable, to avoid + errors when accessing struct fields + [#10141](https://github.com/rust-lang/rust-clippy/pull/10141) +* [`identity_op`]: Removes borrows in the suggestion when needed + [#10004](https://github.com/rust-lang/rust-clippy/pull/10004) +* [`suboptimal_flops`]: The suggestion now includes parentheses when required + [#10113](https://github.com/rust-lang/rust-clippy/pull/10113) +* [`iter_kv_map`]: Now handles `mut` and reference annotations in the suggestion + [#10159](https://github.com/rust-lang/rust-clippy/pull/10159) +* [`redundant_static_lifetimes`]: The suggestion no longer removes `mut` from references + [#10006](https://github.com/rust-lang/rust-clippy/pull/10006) + +### ICE Fixes + +* [`new_ret_no_self`]: Now avoids a stack overflow for `impl Trait` types + [#10086](https://github.com/rust-lang/rust-clippy/pull/10086) +* [`unnecessary_to_owned`]: Now handles compiler generated notes better + [#10027](https://github.com/rust-lang/rust-clippy/pull/10027) + +### Others + +* `SYSROOT` and `--sysroot` can now be set at the same time + [#10149](https://github.com/rust-lang/rust-clippy/pull/10149) ## Rust 1.67 -Current stable, released 2023-01-26 +Released 2023-01-26 [4f142aa1...d822110d](https://github.com/rust-lang/rust-clippy/compare/4f142aa1...d822110d) @@ -4307,6 +4452,7 @@ Released 2018-09-13 [`collapsible_if`]: https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_if [`collapsible_match`]: https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_match [`collapsible_str_replace`]: https://rust-lang.github.io/rust-clippy/master/index.html#collapsible_str_replace +[`collection_is_never_read`]: https://rust-lang.github.io/rust-clippy/master/index.html#collection_is_never_read [`comparison_chain`]: https://rust-lang.github.io/rust-clippy/master/index.html#comparison_chain [`comparison_to_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#comparison_to_empty [`const_static_lifetime`]: https://rust-lang.github.io/rust-clippy/master/index.html#const_static_lifetime @@ -4497,6 +4643,7 @@ Released 2018-09-13 [`let_underscore_must_use`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_must_use [`let_underscore_untyped`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped [`let_unit_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_unit_value +[`let_with_type_underscore`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_with_type_underscore [`linkedlist`]: https://rust-lang.github.io/rust-clippy/master/index.html#linkedlist [`logic_bug`]: https://rust-lang.github.io/rust-clippy/master/index.html#logic_bug [`lossy_float_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#lossy_float_literal @@ -4560,6 +4707,7 @@ Released 2018-09-13 [`mismatching_type_param_order`]: https://rust-lang.github.io/rust-clippy/master/index.html#mismatching_type_param_order [`misnamed_getters`]: https://rust-lang.github.io/rust-clippy/master/index.html#misnamed_getters [`misrefactored_assign_op`]: https://rust-lang.github.io/rust-clippy/master/index.html#misrefactored_assign_op +[`missing_assert_message`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_assert_message [`missing_const_for_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_const_for_fn [`missing_docs_in_private_items`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_docs_in_private_items [`missing_enforced_import_renames`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_enforced_import_renames @@ -4689,6 +4837,7 @@ Released 2018-09-13 [`read_zero_byte_vec`]: https://rust-lang.github.io/rust-clippy/master/index.html#read_zero_byte_vec [`recursive_format_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#recursive_format_impl [`redundant_allocation`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_allocation +[`redundant_async_block`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_async_block [`redundant_clone`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_clone [`redundant_closure`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure [`redundant_closure_call`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure_call diff --git a/Cargo.toml b/Cargo.toml index 70d1268090f..c35dfcbd8c4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy" -version = "0.1.69" +version = "0.1.70" description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" readme = "README.md" diff --git a/book/src/development/proposals/syntax-tree-patterns.md b/book/src/development/proposals/syntax-tree-patterns.md index c5587c4bf90..ea4978011b1 100644 --- a/book/src/development/proposals/syntax-tree-patterns.md +++ b/book/src/development/proposals/syntax-tree-patterns.md @@ -68,13 +68,13 @@ The second part of the motivation is clippy's dependence on unstable compiler-internal data structures. Clippy lints are currently written against the compiler's AST / HIR which means that even small changes in these data structures might break a lot of lints. The second goal of this RFC is to **make -lints independant of the compiler's AST / HIR data structures**. +lints independent of the compiler's AST / HIR data structures**. # Approach A lot of complexity in writing lints currently seems to come from having to manually implement the matching logic (see code samples above). It's an -imparative style that describes *how* to match a syntax tree node instead of +imperative style that describes *how* to match a syntax tree node instead of specifying *what* should be matched against declaratively. In other areas, it's common to use declarative patterns to describe desired information and let the implementation do the actual matching. A well-known example of this approach are @@ -270,7 +270,7 @@ pattern!{ // matches if expressions that **may or may not** have an else block // Attn: `If(_, _, _)` matches only ifs that **have** an else block // - // | if with else block | if witout else block + // | if with else block | if without else block // If(_, _, _) | match | no match // If(_, _, _?) | match | match // If(_, _, ()) | no match | match @@ -568,7 +568,7 @@ another example, `Array( Lit(_)* )` is a valid pattern because the parameter of ## The IsMatch Trait -The pattern syntax and the *PatternTree* are independant of specific syntax tree +The pattern syntax and the *PatternTree* are independent of specific syntax tree implementations (rust ast / hir, syn, ...). When looking at the different pattern examples in the previous sections, it can be seen that the patterns don't contain any information specific to a certain syntax tree implementation. @@ -717,7 +717,7 @@ if false { #### Problems Extending Rust syntax (which is quite complex by itself) with additional syntax -needed for specifying patterns (alternations, sequences, repetisions, named +needed for specifying patterns (alternations, sequences, repetitions, named submatches, ...) might become difficult to read and really hard to parse properly. @@ -858,7 +858,7 @@ would be evaluated as soon as the `Block(_)#then` was matched. Another idea in this area would be to introduce a syntax for backreferences. They could be used to require that multiple parts of a pattern should match the same value. For example, the `assign_op_pattern` lint that searches for `a = a -op b` and recommends changing it to `a op= b` requires that both occurrances of +op b` and recommends changing it to `a op= b` requires that both occurrences of `a` are the same. Using `=#...` as syntax for backreferences, the lint could be implemented like this: @@ -882,7 +882,7 @@ least two return statements" could be a practical addition. For patterns like "a literal that is not a boolean literal" one currently needs to list all alternatives except the boolean case. Introducing a negation operator that allows to write `Lit(!Bool(_))` might be a good idea. This pattern -would be eqivalent to `Lit( Char(_) | Int(_) )` (given that currently only three +would be equivalent to `Lit( Char(_) | Int(_) )` (given that currently only three literal types are implemented). #### Functional composition diff --git a/clippy_lints/Cargo.toml b/clippy_lints/Cargo.toml index 796f1ff1695..0b3846c1316 100644 --- a/clippy_lints/Cargo.toml +++ b/clippy_lints/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_lints" -version = "0.1.69" +version = "0.1.70" description = "A bunch of helpful lints to avoid common pitfalls in Rust" repository = "https://github.com/rust-lang/rust-clippy" readme = "README.md" diff --git a/clippy_lints/src/almost_complete_range.rs b/clippy_lints/src/almost_complete_range.rs index 42e14b5cd94..32d80f42e7e 100644 --- a/clippy_lints/src/almost_complete_range.rs +++ b/clippy_lints/src/almost_complete_range.rs @@ -24,7 +24,7 @@ declare_clippy_lint! { /// ```rust /// let _ = 'a'..='z'; /// ``` - #[clippy::version = "1.63.0"] + #[clippy::version = "1.68.0"] pub ALMOST_COMPLETE_RANGE, suspicious, "almost complete range" diff --git a/clippy_lints/src/casts/cast_slice_from_raw_parts.rs b/clippy_lints/src/casts/cast_slice_from_raw_parts.rs index 627b795d6ed..1233c632a79 100644 --- a/clippy_lints/src/casts/cast_slice_from_raw_parts.rs +++ b/clippy_lints/src/casts/cast_slice_from_raw_parts.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::msrvs::{self, Msrv}; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::snippet_with_context; use clippy_utils::{match_def_path, paths}; use if_chain::if_chain; use rustc_errors::Applicability; @@ -34,6 +34,8 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, if let ExprKind::Path(ref qpath) = fun.kind; if let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id(); if let Some(rpk) = raw_parts_kind(cx, fun_def_id); + let ctxt = expr.span.ctxt(); + if cast_expr.span.ctxt() == ctxt; then { let func = match rpk { RawPartsKind::Immutable => "from_raw_parts", @@ -41,8 +43,8 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, }; let span = expr.span; let mut applicability = Applicability::MachineApplicable; - let ptr = snippet_with_applicability(cx, ptr_arg.span, "ptr", &mut applicability); - let len = snippet_with_applicability(cx, len_arg.span, "len", &mut applicability); + let ptr = snippet_with_context(cx, ptr_arg.span, ctxt, "ptr", &mut applicability).0; + let len = snippet_with_context(cx, len_arg.span, ctxt, "len", &mut applicability).0; span_lint_and_sugg( cx, CAST_SLICE_FROM_RAW_PARTS, diff --git a/clippy_lints/src/collection_is_never_read.rs b/clippy_lints/src/collection_is_never_read.rs new file mode 100644 index 00000000000..10f2bef268a --- /dev/null +++ b/clippy_lints/src/collection_is_never_read.rs @@ -0,0 +1,122 @@ +use clippy_utils::diagnostics::span_lint; +use clippy_utils::ty::is_type_diagnostic_item; +use clippy_utils::visitors::for_each_expr_with_closures; +use clippy_utils::{get_enclosing_block, get_parent_node, path_to_local_id}; +use core::ops::ControlFlow; +use rustc_hir::{Block, ExprKind, HirId, Local, Node, PatKind}; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::symbol::sym; +use rustc_span::Symbol; + +declare_clippy_lint! { + /// ### What it does + /// Checks for collections that are never queried. + /// + /// ### Why is this bad? + /// Putting effort into constructing a collection but then never querying it might indicate that + /// the author forgot to do whatever they intended to do with the collection. Example: Clone + /// a vector, sort it for iteration, but then mistakenly iterate the original vector + /// instead. + /// + /// ### Example + /// ```rust + /// # let samples = vec![3, 1, 2]; + /// let mut sorted_samples = samples.clone(); + /// sorted_samples.sort(); + /// for sample in &samples { // Oops, meant to use `sorted_samples`. + /// println!("{sample}"); + /// } + /// ``` + /// Use instead: + /// ```rust + /// # let samples = vec![3, 1, 2]; + /// let mut sorted_samples = samples.clone(); + /// sorted_samples.sort(); + /// for sample in &sorted_samples { + /// println!("{sample}"); + /// } + /// ``` + #[clippy::version = "1.69.0"] + pub COLLECTION_IS_NEVER_READ, + nursery, + "a collection is never queried" +} +declare_lint_pass!(CollectionIsNeverRead => [COLLECTION_IS_NEVER_READ]); + +static COLLECTIONS: [Symbol; 10] = [ + sym::BTreeMap, + sym::BTreeSet, + sym::BinaryHeap, + sym::HashMap, + sym::HashSet, + sym::LinkedList, + sym::Option, + sym::String, + sym::Vec, + sym::VecDeque, +]; + +impl<'tcx> LateLintPass<'tcx> for CollectionIsNeverRead { + fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>) { + // Look for local variables whose type is a container. Search surrounding bock for read access. + let ty = cx.typeck_results().pat_ty(local.pat); + if COLLECTIONS.iter().any(|&sym| is_type_diagnostic_item(cx, ty, sym)) + && let PatKind::Binding(_, local_id, _, _) = local.pat.kind + && let Some(enclosing_block) = get_enclosing_block(cx, local.hir_id) + && has_no_read_access(cx, local_id, enclosing_block) + { + span_lint(cx, COLLECTION_IS_NEVER_READ, local.span, "collection is never read"); + } + } +} + +fn has_no_read_access<'tcx>(cx: &LateContext<'tcx>, id: HirId, block: &'tcx Block<'tcx>) -> bool { + let mut has_access = false; + let mut has_read_access = false; + + // Inspect all expressions and sub-expressions in the block. + for_each_expr_with_closures(cx, block, |expr| { + // Ignore expressions that are not simply `id`. + if !path_to_local_id(expr, id) { + return ControlFlow::Continue(()); + } + + // `id` is being accessed. Investigate if it's a read access. + has_access = true; + + // `id` appearing in the left-hand side of an assignment is not a read access: + // + // id = ...; // Not reading `id`. + if let Some(Node::Expr(parent)) = get_parent_node(cx.tcx, expr.hir_id) + && let ExprKind::Assign(lhs, ..) = parent.kind + && path_to_local_id(lhs, id) + { + return ControlFlow::Continue(()); + } + + // Method call on `id` in a statement ignores any return value, so it's not a read access: + // + // id.foo(...); // Not reading `id`. + // + // Only assuming this for "official" methods defined on the type. For methods defined in extension + // traits (identified as local, based on the orphan rule), pessimistically assume that they might + // have side effects, so consider them a read. + if let Some(Node::Expr(parent)) = get_parent_node(cx.tcx, expr.hir_id) + && let ExprKind::MethodCall(_, receiver, _, _) = parent.kind + && path_to_local_id(receiver, id) + && let Some(Node::Stmt(..)) = get_parent_node(cx.tcx, parent.hir_id) + && let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(parent.hir_id) + && !method_def_id.is_local() + { + return ControlFlow::Continue(()); + } + + // Any other access to `id` is a read access. Stop searching. + has_read_access = true; + ControlFlow::Break(()) + }); + + // Ignore collections that have no access at all. Other lints should catch them. + has_access && !has_read_access +} diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index cd5dd7a5706..cc6024b87cd 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -92,6 +92,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::cognitive_complexity::COGNITIVE_COMPLEXITY_INFO, crate::collapsible_if::COLLAPSIBLE_ELSE_IF_INFO, crate::collapsible_if::COLLAPSIBLE_IF_INFO, + crate::collection_is_never_read::COLLECTION_IS_NEVER_READ_INFO, crate::comparison_chain::COMPARISON_CHAIN_INFO, crate::copies::BRANCHES_SHARING_CODE_INFO, crate::copies::IFS_SAME_COND_INFO, @@ -226,6 +227,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::let_underscore::LET_UNDERSCORE_LOCK_INFO, crate::let_underscore::LET_UNDERSCORE_MUST_USE_INFO, crate::let_underscore::LET_UNDERSCORE_UNTYPED_INFO, + crate::let_with_type_underscore::LET_WITH_TYPE_UNDERSCORE_INFO, crate::lifetimes::EXTRA_UNUSED_LIFETIMES_INFO, crate::lifetimes::NEEDLESS_LIFETIMES_INFO, crate::literal_representation::DECIMAL_LITERAL_REPRESENTATION_INFO, @@ -416,6 +418,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::misc_early::UNSEPARATED_LITERAL_SUFFIX_INFO, crate::misc_early::ZERO_PREFIXED_LITERAL_INFO, crate::mismatching_type_param_order::MISMATCHING_TYPE_PARAM_ORDER_INFO, + crate::missing_assert_message::MISSING_ASSERT_MESSAGE_INFO, crate::missing_const_for_fn::MISSING_CONST_FOR_FN_INFO, crate::missing_doc::MISSING_DOCS_IN_PRIVATE_ITEMS_INFO, crate::missing_enforced_import_rename::MISSING_ENFORCED_IMPORT_RENAMES_INFO, @@ -517,6 +520,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::ranges::REVERSED_EMPTY_RANGES_INFO, crate::rc_clone_in_vec_init::RC_CLONE_IN_VEC_INIT_INFO, crate::read_zero_byte_vec::READ_ZERO_BYTE_VEC_INFO, + crate::redundant_async_block::REDUNDANT_ASYNC_BLOCK_INFO, crate::redundant_clone::REDUNDANT_CLONE_INFO, crate::redundant_closure_call::REDUNDANT_CLOSURE_CALL_INFO, crate::redundant_else::REDUNDANT_ELSE_INFO, diff --git a/clippy_lints/src/default_instead_of_iter_empty.rs b/clippy_lints/src/default_instead_of_iter_empty.rs index 1ad929864b2..f296b80d283 100644 --- a/clippy_lints/src/default_instead_of_iter_empty.rs +++ b/clippy_lints/src/default_instead_of_iter_empty.rs @@ -1,11 +1,12 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::last_path_segment; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::snippet_with_context; use clippy_utils::{match_def_path, paths}; use rustc_errors::Applicability; use rustc_hir::{def, Expr, ExprKind, GenericArg, QPath, TyKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::SyntaxContext; declare_clippy_lint! { /// ### What it does @@ -38,9 +39,11 @@ impl<'tcx> LateLintPass<'tcx> for DefaultIterEmpty { && let QPath::Resolved(None, path) = ty_path && let def::Res::Def(_, def_id) = &path.res && match_def_path(cx, *def_id, &paths::ITER_EMPTY) + && let ctxt = expr.span.ctxt() + && ty.span.ctxt() == ctxt { let mut applicability = Applicability::MachineApplicable; - let sugg = make_sugg(cx, ty_path, &mut applicability); + let sugg = make_sugg(cx, ty_path, ctxt, &mut applicability); span_lint_and_sugg( cx, DEFAULT_INSTEAD_OF_ITER_EMPTY, @@ -54,14 +57,19 @@ impl<'tcx> LateLintPass<'tcx> for DefaultIterEmpty { } } -fn make_sugg(cx: &LateContext<'_>, ty_path: &rustc_hir::QPath<'_>, applicability: &mut Applicability) -> String { +fn make_sugg( + cx: &LateContext<'_>, + ty_path: &rustc_hir::QPath<'_>, + ctxt: SyntaxContext, + applicability: &mut Applicability, +) -> String { if let Some(last) = last_path_segment(ty_path).args && let Some(iter_ty) = last.args.iter().find_map(|arg| match arg { GenericArg::Type(ty) => Some(ty), _ => None, }) { - format!("std::iter::empty::<{}>()", snippet_with_applicability(cx, iter_ty.span, "..", applicability)) + format!("std::iter::empty::<{}>()", snippet_with_context(cx, iter_ty.span, ctxt, "..", applicability).0) } else { "std::iter::empty()".to_owned() } diff --git a/clippy_lints/src/dereference.rs b/clippy_lints/src/dereference.rs index 47501980e66..7f3f26bed7c 100644 --- a/clippy_lints/src/dereference.rs +++ b/clippy_lints/src/dereference.rs @@ -1357,10 +1357,10 @@ fn replace_types<'tcx>( && let Some(term_ty) = projection_predicate.term.ty() && let ty::Param(term_param_ty) = term_ty.kind() { - let item_def_id = projection_predicate.projection_ty.def_id; - let assoc_item = cx.tcx.associated_item(item_def_id); - let projection = cx.tcx - .mk_projection(assoc_item.def_id, cx.tcx.mk_substs_trait(new_ty, [])); + let projection = cx.tcx.mk_ty_from_kind(ty::Alias( + ty::Projection, + projection_predicate.projection_ty.with_self_ty(cx.tcx, new_ty), + )); if let Ok(projected_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, projection) && substs[term_param_ty.index as usize] != ty::GenericArg::from(projected_ty) diff --git a/clippy_lints/src/derivable_impls.rs b/clippy_lints/src/derivable_impls.rs index c5f4e943f4f..8a5a28c6b3d 100644 --- a/clippy_lints/src/derivable_impls.rs +++ b/clippy_lints/src/derivable_impls.rs @@ -8,7 +8,7 @@ use rustc_hir::{ Body, Expr, ExprKind, GenericArg, Impl, ImplItemKind, Item, ItemKind, Node, PathSegment, QPath, Ty, TyKind, }; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::AdtDef; +use rustc_middle::ty::{Adt, AdtDef, SubstsRef}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::sym; @@ -81,13 +81,18 @@ fn check_struct<'tcx>( self_ty: &Ty<'_>, func_expr: &Expr<'_>, adt_def: AdtDef<'_>, + substs: SubstsRef<'_>, ) { if let TyKind::Path(QPath::Resolved(_, p)) = self_ty.kind { - if let Some(PathSegment { args: Some(a), .. }) = p.segments.last() { - for arg in a.args { - if !matches!(arg, GenericArg::Lifetime(_)) { - return; - } + if let Some(PathSegment { args, .. }) = p.segments.last() { + let args = args.map(|a| a.args).unwrap_or(&[]); + + // substs contains the generic parameters of the type declaration, while args contains the arguments + // used at instantiation time. If both len are not equal, it means that some parameters were not + // provided (which means that the default values were used); in this case we will not risk + // suggesting too broad a rewrite. We won't either if any argument is a type or a const. + if substs.len() != args.len() || args.iter().any(|arg| !matches!(arg, GenericArg::Lifetime(_))) { + return; } } } @@ -184,7 +189,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls { if let Some(Node::ImplItem(impl_item)) = cx.tcx.hir().find(impl_item_hir); if let ImplItemKind::Fn(_, b) = &impl_item.kind; if let Body { value: func_expr, .. } = cx.tcx.hir().body(*b); - if let Some(adt_def) = cx.tcx.type_of(item.owner_id).subst_identity().ty_adt_def(); + if let &Adt(adt_def, substs) = cx.tcx.type_of(item.owner_id).subst_identity().kind(); if let attrs = cx.tcx.hir().attrs(item.hir_id()); if !attrs.iter().any(|attr| attr.doc_str().is_some()); if let child_attrs = cx.tcx.hir().attrs(impl_item_hir); @@ -192,7 +197,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls { then { if adt_def.is_struct() { - check_struct(cx, item, self_ty, func_expr, adt_def); + check_struct(cx, item, self_ty, func_expr, adt_def, substs); } else if adt_def.is_enum() && self.msrv.meets(msrvs::DEFAULT_ENUM_ATTRIBUTE) { check_enum(cx, item, func_expr, adt_def); } diff --git a/clippy_lints/src/exit.rs b/clippy_lints/src/exit.rs index 9c8b0d076df..8ba6a9e4876 100644 --- a/clippy_lints/src/exit.rs +++ b/clippy_lints/src/exit.rs @@ -11,7 +11,7 @@ declare_clippy_lint! { /// /// ### Why is this bad? /// Exit terminates the program at the location it is called. For unrecoverable - /// errors `panics` should be used to provide a stacktrace and potentualy other + /// errors `panics` should be used to provide a stacktrace and potentially other /// information. A normal termination or one with an error code should happen in /// the main function. /// diff --git a/clippy_lints/src/fn_null_check.rs b/clippy_lints/src/fn_null_check.rs index 91c8c340ce2..d8f4a5fe221 100644 --- a/clippy_lints/src/fn_null_check.rs +++ b/clippy_lints/src/fn_null_check.rs @@ -25,7 +25,7 @@ declare_clippy_lint! { /// /// if fn_ptr.is_none() { ... } /// ``` - #[clippy::version = "1.67.0"] + #[clippy::version = "1.68.0"] pub FN_NULL_CHECK, correctness, "`fn()` type assumed to be nullable" diff --git a/clippy_lints/src/format.rs b/clippy_lints/src/format.rs index d0fab694960..8040938c626 100644 --- a/clippy_lints/src/format.rs +++ b/clippy_lints/src/format.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::macros::{root_macro_call_first_node, FormatArgsExpn}; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::snippet_with_context; use clippy_utils::sugg::Sugg; use if_chain::if_chain; use rustc_errors::Applicability; @@ -84,9 +84,9 @@ impl<'tcx> LateLintPass<'tcx> for UselessFormat { _ => false, }; let sugg = if is_new_string { - snippet_with_applicability(cx, value.span, "..", &mut applicability).into_owned() + snippet_with_context(cx, value.span, call_site.ctxt(), "..", &mut applicability).0.into_owned() } else { - let sugg = Sugg::hir_with_applicability(cx, value, "", &mut applicability); + let sugg = Sugg::hir_with_context(cx, value, call_site.ctxt(), "", &mut applicability); format!("{}.to_string()", sugg.maybe_par()) }; span_useless_format(cx, call_site, sugg, applicability); diff --git a/clippy_lints/src/functions/impl_trait_in_params.rs b/clippy_lints/src/functions/impl_trait_in_params.rs index 2811a73f6c1..d3d0d91c1be 100644 --- a/clippy_lints/src/functions/impl_trait_in_params.rs +++ b/clippy_lints/src/functions/impl_trait_in_params.rs @@ -22,7 +22,7 @@ pub(super) fn check_fn<'tcx>(cx: &LateContext<'_>, kind: &'tcx FnKind<'_>, body: if let Some(gen_span) = generics.span_for_param_suggestion() { diag.span_suggestion_with_style( gen_span, - "add a type paremeter", + "add a type parameter", format!(", {{ /* Generic name */ }}: {}", ¶m.name.ident().as_str()[5..]), rustc_errors::Applicability::HasPlaceholders, rustc_errors::SuggestionStyle::ShowAlways, @@ -35,7 +35,7 @@ pub(super) fn check_fn<'tcx>(cx: &LateContext<'_>, kind: &'tcx FnKind<'_>, body: ident.span.ctxt(), ident.span.parent(), ), - "add a type paremeter", + "add a type parameter", format!("<{{ /* Generic name */ }}: {}>", ¶m.name.ident().as_str()[5..]), rustc_errors::Applicability::HasPlaceholders, rustc_errors::SuggestionStyle::ShowAlways, diff --git a/clippy_lints/src/functions/misnamed_getters.rs b/clippy_lints/src/functions/misnamed_getters.rs index 8b53ee68ebd..e5945939e60 100644 --- a/clippy_lints/src/functions/misnamed_getters.rs +++ b/clippy_lints/src/functions/misnamed_getters.rs @@ -97,7 +97,7 @@ pub fn check_fn(cx: &LateContext<'_>, kind: FnKind<'_>, decl: &FnDecl<'_>, body: let Some(correct_field) = correct_field else { // There is no field corresponding to the getter name. - // FIXME: This can be a false positive if the correct field is reachable trought deeper autodereferences than used_field is + // FIXME: This can be a false positive if the correct field is reachable through deeper autodereferences than used_field is return; }; diff --git a/clippy_lints/src/functions/mod.rs b/clippy_lints/src/functions/mod.rs index d2852b4acad..7c5e44bb7dc 100644 --- a/clippy_lints/src/functions/mod.rs +++ b/clippy_lints/src/functions/mod.rs @@ -185,7 +185,7 @@ declare_clippy_lint! { /// ### Examples /// ```rust /// // this could be annotated with `#[must_use]`. - /// fn id(t: T) -> T { t } + /// pub fn id(t: T) -> T { t } /// ``` #[clippy::version = "1.40.0"] pub MUST_USE_CANDIDATE, diff --git a/clippy_lints/src/implicit_saturating_add.rs b/clippy_lints/src/implicit_saturating_add.rs index 6e19343931e..57e6caa8711 100644 --- a/clippy_lints/src/implicit_saturating_add.rs +++ b/clippy_lints/src/implicit_saturating_add.rs @@ -1,7 +1,7 @@ use clippy_utils::consts::{constant, Constant}; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::get_parent_expr; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::snippet_with_context; use if_chain::if_chain; use rustc_ast::ast::{LitIntType, LitKind}; use rustc_errors::Applicability; @@ -55,6 +55,9 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingAdd { if let ExprKind::AssignOp(op1, target, value) = ex.kind; let ty = cx.typeck_results().expr_ty(target); if Some(c) == get_int_max(ty); + let ctxt = expr.span.ctxt(); + if ex.span.ctxt() == ctxt; + if expr1.span.ctxt() == ctxt; if clippy_utils::SpanlessEq::new(cx).eq_expr(l, target); if BinOpKind::Add == op1.node; if let ExprKind::Lit(ref lit) = value.kind; @@ -62,8 +65,15 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingAdd { if block.expr.is_none(); then { let mut app = Applicability::MachineApplicable; - let code = snippet_with_applicability(cx, target.span, "_", &mut app); - let sugg = if let Some(parent) = get_parent_expr(cx, expr) && let ExprKind::If(_cond, _then, Some(else_)) = parent.kind && else_.hir_id == expr.hir_id {format!("{{{code} = {code}.saturating_add(1); }}")} else {format!("{code} = {code}.saturating_add(1);")}; + let code = snippet_with_context(cx, target.span, ctxt, "_", &mut app).0; + let sugg = if let Some(parent) = get_parent_expr(cx, expr) + && let ExprKind::If(_cond, _then, Some(else_)) = parent.kind + && else_.hir_id == expr.hir_id + { + format!("{{{code} = {code}.saturating_add(1); }}") + } else { + format!("{code} = {code}.saturating_add(1);") + }; span_lint_and_sugg(cx, IMPLICIT_SATURATING_ADD, expr.span, "manual saturating add detected", "use instead", sugg, app); } } diff --git a/clippy_lints/src/instant_subtraction.rs b/clippy_lints/src/instant_subtraction.rs index 668110c7cc0..34e9991582c 100644 --- a/clippy_lints/src/instant_subtraction.rs +++ b/clippy_lints/src/instant_subtraction.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::{self, span_lint_and_sugg}; use clippy_utils::msrvs::{self, Msrv}; -use clippy_utils::source; +use clippy_utils::source::snippet_with_context; use clippy_utils::sugg::Sugg; use clippy_utils::ty; use rustc_errors::Applicability; @@ -161,14 +161,9 @@ fn print_unchecked_duration_subtraction_sugg( ) { let mut applicability = Applicability::MachineApplicable; - let left_expr = - source::snippet_with_applicability(cx, left_expr.span, "std::time::Instant::now()", &mut applicability); - let right_expr = source::snippet_with_applicability( - cx, - right_expr.span, - "std::time::Duration::from_secs(1)", - &mut applicability, - ); + let ctxt = expr.span.ctxt(); + let left_expr = snippet_with_context(cx, left_expr.span, ctxt, "", &mut applicability).0; + let right_expr = snippet_with_context(cx, right_expr.span, ctxt, "", &mut applicability).0; diagnostics::span_lint_and_sugg( cx, diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs index e13bc47973b..0805b4b1979 100644 --- a/clippy_lints/src/len_zero.rs +++ b/clippy_lints/src/len_zero.rs @@ -1,13 +1,14 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then}; -use clippy_utils::source::snippet_with_applicability; -use clippy_utils::{get_item_name, get_parent_as_impl, is_lint_allowed, peel_ref_operators}; +use clippy_utils::source::snippet_with_context; +use clippy_utils::{get_item_name, get_parent_as_impl, is_lint_allowed, peel_ref_operators, sugg::Sugg}; use if_chain::if_chain; use rustc_ast::ast::LitKind; use rustc_errors::Applicability; use rustc_hir::def_id::DefIdSet; use rustc_hir::{ - def_id::DefId, AssocItemKind, BinOpKind, Expr, ExprKind, FnRetTy, ImplItem, ImplItemKind, ImplicitSelfKind, Item, - ItemKind, Mutability, Node, TraitItemRef, TyKind, UnOp, + def::Res, def_id::DefId, lang_items::LangItem, AssocItemKind, BinOpKind, Expr, ExprKind, FnRetTy, GenericArg, + GenericBound, ImplItem, ImplItemKind, ImplicitSelfKind, Item, ItemKind, Mutability, Node, PathSegment, PrimTy, + QPath, TraitItemRef, TyKind, TypeBindingKind, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::{self, AssocKind, FnSig, Ty}; @@ -16,7 +17,6 @@ use rustc_span::{ source_map::{Span, Spanned, Symbol}, symbol::sym, }; -use std::borrow::Cow; declare_clippy_lint! { /// ### What it does @@ -251,33 +251,98 @@ fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, trait_items } #[derive(Debug, Clone, Copy)] -enum LenOutput<'tcx> { +enum LenOutput { Integral, Option(DefId), - Result(DefId, Ty<'tcx>), + Result(DefId), } -fn parse_len_output<'tcx>(cx: &LateContext<'_>, sig: FnSig<'tcx>) -> Option> { + +fn extract_future_output<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<&'tcx PathSegment<'tcx>> { + if let ty::Alias(_, alias_ty) = ty.kind() && + let Some(Node::Item(item)) = cx.tcx.hir().get_if_local(alias_ty.def_id) && + let Item { kind: ItemKind::OpaqueTy(opaque), .. } = item && + opaque.bounds.len() == 1 && + let GenericBound::LangItemTrait(LangItem::Future, _, _, generic_args) = &opaque.bounds[0] && + generic_args.bindings.len() == 1 && + let TypeBindingKind::Equality { + term: rustc_hir::Term::Ty(rustc_hir::Ty {kind: TyKind::Path(QPath::Resolved(_, path)), .. }), + } = &generic_args.bindings[0].kind && + path.segments.len() == 1 { + return Some(&path.segments[0]); + } + + None +} + +fn is_first_generic_integral<'tcx>(segment: &'tcx PathSegment<'tcx>) -> bool { + if let Some(generic_args) = segment.args { + if generic_args.args.is_empty() { + return false; + } + let arg = &generic_args.args[0]; + if let GenericArg::Type(rustc_hir::Ty { + kind: TyKind::Path(QPath::Resolved(_, path)), + .. + }) = arg + { + let segments = &path.segments; + let segment = &segments[0]; + let res = &segment.res; + if matches!(res, Res::PrimTy(PrimTy::Uint(_))) || matches!(res, Res::PrimTy(PrimTy::Int(_))) { + return true; + } + } + } + + false +} + +fn parse_len_output<'tcx>(cx: &LateContext<'tcx>, sig: FnSig<'tcx>) -> Option { + if let Some(segment) = extract_future_output(cx, sig.output()) { + let res = segment.res; + + if matches!(res, Res::PrimTy(PrimTy::Uint(_))) || matches!(res, Res::PrimTy(PrimTy::Int(_))) { + return Some(LenOutput::Integral); + } + + if let Res::Def(_, def_id) = res { + if cx.tcx.is_diagnostic_item(sym::Option, def_id) && is_first_generic_integral(segment) { + return Some(LenOutput::Option(def_id)); + } else if cx.tcx.is_diagnostic_item(sym::Result, def_id) && is_first_generic_integral(segment) { + return Some(LenOutput::Result(def_id)); + } + } + + return None; + } + match *sig.output().kind() { ty::Int(_) | ty::Uint(_) => Some(LenOutput::Integral), ty::Adt(adt, subs) if cx.tcx.is_diagnostic_item(sym::Option, adt.did()) => { subs.type_at(0).is_integral().then(|| LenOutput::Option(adt.did())) }, - ty::Adt(adt, subs) if cx.tcx.is_diagnostic_item(sym::Result, adt.did()) => subs - .type_at(0) - .is_integral() - .then(|| LenOutput::Result(adt.did(), subs.type_at(1))), + ty::Adt(adt, subs) if cx.tcx.is_diagnostic_item(sym::Result, adt.did()) => { + subs.type_at(0).is_integral().then(|| LenOutput::Result(adt.did())) + }, _ => None, } } -impl<'tcx> LenOutput<'tcx> { - fn matches_is_empty_output(self, ty: Ty<'tcx>) -> bool { +impl LenOutput { + fn matches_is_empty_output<'tcx>(self, cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { + if let Some(segment) = extract_future_output(cx, ty) { + return match (self, segment.res) { + (_, Res::PrimTy(PrimTy::Bool)) => true, + (Self::Option(_), Res::Def(_, def_id)) if cx.tcx.is_diagnostic_item(sym::Option, def_id) => true, + (Self::Result(_), Res::Def(_, def_id)) if cx.tcx.is_diagnostic_item(sym::Result, def_id) => true, + _ => false, + }; + } + match (self, ty.kind()) { (_, &ty::Bool) => true, (Self::Option(id), &ty::Adt(adt, subs)) if id == adt.did() => subs.type_at(0).is_bool(), - (Self::Result(id, err_ty), &ty::Adt(adt, subs)) if id == adt.did() => { - subs.type_at(0).is_bool() && subs.type_at(1) == err_ty - }, + (Self::Result(id), &ty::Adt(adt, subs)) if id == adt.did() => subs.type_at(0).is_bool(), _ => false, } } @@ -301,9 +366,14 @@ impl<'tcx> LenOutput<'tcx> { } /// Checks if the given signature matches the expectations for `is_empty` -fn check_is_empty_sig<'tcx>(sig: FnSig<'tcx>, self_kind: ImplicitSelfKind, len_output: LenOutput<'tcx>) -> bool { +fn check_is_empty_sig<'tcx>( + cx: &LateContext<'tcx>, + sig: FnSig<'tcx>, + self_kind: ImplicitSelfKind, + len_output: LenOutput, +) -> bool { match &**sig.inputs_and_output { - [arg, res] if len_output.matches_is_empty_output(*res) => { + [arg, res] if len_output.matches_is_empty_output(cx, *res) => { matches!( (arg.kind(), self_kind), (ty::Ref(_, _, Mutability::Not), ImplicitSelfKind::ImmRef) @@ -315,11 +385,11 @@ fn check_is_empty_sig<'tcx>(sig: FnSig<'tcx>, self_kind: ImplicitSelfKind, len_o } /// Checks if the given type has an `is_empty` method with the appropriate signature. -fn check_for_is_empty<'tcx>( - cx: &LateContext<'tcx>, +fn check_for_is_empty( + cx: &LateContext<'_>, span: Span, self_kind: ImplicitSelfKind, - output: LenOutput<'tcx>, + output: LenOutput, impl_ty: DefId, item_name: Symbol, item_kind: &str, @@ -352,6 +422,7 @@ fn check_for_is_empty<'tcx>( Some(is_empty) if !(is_empty.fn_has_self_parameter && check_is_empty_sig( + cx, cx.tcx.fn_sig(is_empty.def_id).subst_identity().skip_binder(), self_kind, output, @@ -431,7 +502,7 @@ fn check_len( &format!("using `{op}is_empty` is clearer and more explicit"), format!( "{op}{}.is_empty()", - snippet_with_applicability(cx, receiver.span, "_", &mut applicability) + snippet_with_context(cx, receiver.span, span.ctxt(), "_", &mut applicability).0, ), applicability, ); @@ -444,13 +515,7 @@ fn check_empty_expr(cx: &LateContext<'_>, span: Span, lit1: &Expr<'_>, lit2: &Ex let mut applicability = Applicability::MachineApplicable; let lit1 = peel_ref_operators(cx, lit1); - let mut lit_str = snippet_with_applicability(cx, lit1.span, "_", &mut applicability); - - // Wrap the expression in parentheses if it's a deref expression. Otherwise operator precedence will - // cause the code to dereference boolean(won't compile). - if let ExprKind::Unary(UnOp::Deref, _) = lit1.kind { - lit_str = Cow::from(format!("({lit_str})")); - } + let lit_str = Sugg::hir_with_context(cx, lit1, span.ctxt(), "_", &mut applicability).maybe_par(); span_lint_and_sugg( cx, diff --git a/clippy_lints/src/let_underscore.rs b/clippy_lints/src/let_underscore.rs index 7600777fab9..51b5de27de8 100644 --- a/clippy_lints/src/let_underscore.rs +++ b/clippy_lints/src/let_underscore.rs @@ -124,7 +124,7 @@ declare_clippy_lint! { /// ``` #[clippy::version = "1.69.0"] pub LET_UNDERSCORE_UNTYPED, - pedantic, + restriction, "non-binding `let` without a type annotation" } diff --git a/clippy_lints/src/let_with_type_underscore.rs b/clippy_lints/src/let_with_type_underscore.rs new file mode 100644 index 00000000000..ba51973f2f9 --- /dev/null +++ b/clippy_lints/src/let_with_type_underscore.rs @@ -0,0 +1,45 @@ +use clippy_utils::diagnostics::span_lint_and_help; +use rustc_hir::*; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::lint::in_external_macro; +use rustc_session::{declare_lint_pass, declare_tool_lint}; + +declare_clippy_lint! { + /// ### What it does + /// Detects when a variable is declared with an explicit type of `_`. + /// ### Why is this bad? + /// It adds noise, `: _` provides zero clarity or utility. + /// ### Example + /// ```rust,ignore + /// let my_number: _ = 1; + /// ``` + /// Use instead: + /// ```rust,ignore + /// let my_number = 1; + /// ``` + #[clippy::version = "1.69.0"] + pub LET_WITH_TYPE_UNDERSCORE, + complexity, + "unneeded underscore type (`_`) in a variable declaration" +} +declare_lint_pass!(UnderscoreTyped => [LET_WITH_TYPE_UNDERSCORE]); + +impl LateLintPass<'_> for UnderscoreTyped { + fn check_local<'tcx>(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>) { + if_chain! { + if !in_external_macro(cx.tcx.sess, local.span); + if let Some(ty) = local.ty; // Ensure that it has a type defined + if let TyKind::Infer = &ty.kind; // that type is '_' + if local.span.ctxt() == ty.span.ctxt(); + then { + span_lint_and_help(cx, + LET_WITH_TYPE_UNDERSCORE, + local.span, + "variable declared with type underscore", + Some(ty.span.with_lo(local.pat.span.hi())), + "remove the explicit type `_` declaration" + ) + } + }; + } +} diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index c626e0bd998..491732be208 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -87,6 +87,7 @@ mod casts; mod checked_conversions; mod cognitive_complexity; mod collapsible_if; +mod collection_is_never_read; mod comparison_chain; mod copies; mod copy_iterator; @@ -166,6 +167,7 @@ mod large_stack_arrays; mod len_zero; mod let_if_seq; mod let_underscore; +mod let_with_type_underscore; mod lifetimes; mod literal_representation; mod loops; @@ -192,6 +194,7 @@ mod minmax; mod misc; mod misc_early; mod mismatching_type_param_order; +mod missing_assert_message; mod missing_const_for_fn; mod missing_doc; mod missing_enforced_import_rename; @@ -249,6 +252,7 @@ mod question_mark_used; mod ranges; mod rc_clone_in_vec_init; mod read_zero_byte_vec; +mod redundant_async_block; mod redundant_clone; mod redundant_closure_call; mod redundant_else; @@ -533,6 +537,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: .collect(), )) }); + store.register_early_pass(|| Box::new(utils::format_args_collector::FormatArgsCollector)); store.register_late_pass(|_| Box::new(utils::dump_hir::DumpHir)); store.register_late_pass(|_| Box::new(utils::author::Author)); let await_holding_invalid_types = conf.await_holding_invalid_types.clone(); @@ -924,6 +929,10 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: )) }); store.register_late_pass(|_| Box::new(no_mangle_with_rust_abi::NoMangleWithRustAbi)); + store.register_late_pass(|_| Box::new(collection_is_never_read::CollectionIsNeverRead)); + store.register_late_pass(|_| Box::new(missing_assert_message::MissingAssertMessage)); + store.register_early_pass(|| Box::new(redundant_async_block::RedundantAsyncBlock)); + store.register_late_pass(|_| Box::new(let_with_type_underscore::UnderscoreTyped)); // add lints here, do not remove this comment, it's used in `new_lint` } diff --git a/clippy_lints/src/manual_bits.rs b/clippy_lints/src/manual_bits.rs index 462d73cf0b9..bc815dc4a26 100644 --- a/clippy_lints/src/manual_bits.rs +++ b/clippy_lints/src/manual_bits.rs @@ -1,11 +1,12 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::get_parent_expr; use clippy_utils::msrvs::{self, Msrv}; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::snippet_with_context; use rustc_ast::ast::LitKind; use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Expr, ExprKind, GenericArg, QPath}; -use rustc_lint::{LateContext, LateLintPass}; +use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_middle::lint::in_external_macro; use rustc_middle::ty::{self, Ty}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::sym; @@ -55,13 +56,17 @@ impl<'tcx> LateLintPass<'tcx> for ManualBits { if_chain! { if let ExprKind::Binary(bin_op, left_expr, right_expr) = expr.kind; if let BinOpKind::Mul = &bin_op.node; + if !in_external_macro(cx.sess(), expr.span); + let ctxt = expr.span.ctxt(); + if left_expr.span.ctxt() == ctxt; + if right_expr.span.ctxt() == ctxt; if let Some((real_ty, resolved_ty, other_expr)) = get_one_size_of_ty(cx, left_expr, right_expr); if matches!(resolved_ty.kind(), ty::Int(_) | ty::Uint(_)); if let ExprKind::Lit(lit) = &other_expr.kind; if let LitKind::Int(8, _) = lit.node; then { let mut app = Applicability::MachineApplicable; - let ty_snip = snippet_with_applicability(cx, real_ty.span, "..", &mut app); + let ty_snip = snippet_with_context(cx, real_ty.span, ctxt, "..", &mut app).0; let sugg = create_sugg(cx, expr, format!("{ty_snip}::BITS")); span_lint_and_sugg( diff --git a/clippy_lints/src/manual_is_ascii_check.rs b/clippy_lints/src/manual_is_ascii_check.rs index 2fd32c009ea..31264261f5d 100644 --- a/clippy_lints/src/manual_is_ascii_check.rs +++ b/clippy_lints/src/manual_is_ascii_check.rs @@ -1,5 +1,5 @@ use clippy_utils::msrvs::{self, Msrv}; -use clippy_utils::{diagnostics::span_lint_and_sugg, higher, in_constant, macros::root_macro_call, source::snippet}; +use clippy_utils::{diagnostics::span_lint_and_sugg, higher, in_constant, macros::root_macro_call, sugg::Sugg}; use rustc_ast::ast::RangeLimits; use rustc_ast::LitKind::{Byte, Char}; use rustc_errors::Applicability; @@ -115,15 +115,8 @@ fn check_is_ascii(cx: &LateContext<'_>, span: Span, recv: &Expr<'_>, range: &Cha CharRange::Otherwise => None, } { let default_snip = ".."; - // `snippet_with_applicability` may set applicability to `MaybeIncorrect` for - // macro span, so we check applicability manually by comparing `recv` is not default. - let recv = snippet(cx, recv.span, default_snip); - - let applicability = if recv == default_snip { - Applicability::HasPlaceholders - } else { - Applicability::MachineApplicable - }; + let mut app = Applicability::MachineApplicable; + let recv = Sugg::hir_with_context(cx, recv, span.ctxt(), default_snip, &mut app).maybe_par(); span_lint_and_sugg( cx, @@ -132,7 +125,7 @@ fn check_is_ascii(cx: &LateContext<'_>, span: Span, recv: &Expr<'_>, range: &Cha "manual check for common ascii range", "try", format!("{recv}.{sugg}()"), - applicability, + app, ); } } diff --git a/clippy_lints/src/manual_rem_euclid.rs b/clippy_lints/src/manual_rem_euclid.rs index 38f41d077c1..aafee92713f 100644 --- a/clippy_lints/src/manual_rem_euclid.rs +++ b/clippy_lints/src/manual_rem_euclid.rs @@ -1,7 +1,7 @@ use clippy_utils::consts::{constant_full_int, FullInt}; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::msrvs::{self, Msrv}; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::snippet_with_context; use clippy_utils::{in_constant, path_to_local}; use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Expr, ExprKind, Node, TyKind}; @@ -60,12 +60,16 @@ impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid { return; } + // (x % c + c) % c if let ExprKind::Binary(op1, expr1, right) = expr.kind && op1.node == BinOpKind::Rem + && let ctxt = expr.span.ctxt() + && expr1.span.ctxt() == ctxt && let Some(const1) = check_for_unsigned_int_constant(cx, right) && let ExprKind::Binary(op2, left, right) = expr1.kind && op2.node == BinOpKind::Add && let Some((const2, expr2)) = check_for_either_unsigned_int_constant(cx, left, right) + && expr2.span.ctxt() == ctxt && let ExprKind::Binary(op3, expr3, right) = expr2.kind && op3.node == BinOpKind::Rem && let Some(const3) = check_for_unsigned_int_constant(cx, right) @@ -86,7 +90,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid { }; let mut app = Applicability::MachineApplicable; - let rem_of = snippet_with_applicability(cx, expr3.span, "_", &mut app); + let rem_of = snippet_with_context(cx, expr3.span, ctxt, "_", &mut app).0; span_lint_and_sugg( cx, MANUAL_REM_EUCLID, diff --git a/clippy_lints/src/match_result_ok.rs b/clippy_lints/src/match_result_ok.rs index a020282d234..6ec9784038c 100644 --- a/clippy_lints/src/match_result_ok.rs +++ b/clippy_lints/src/match_result_ok.rs @@ -1,11 +1,11 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::higher; -use clippy_utils::method_chain_args; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::is_res_lang_ctor; +use clippy_utils::source::snippet_with_context; use clippy_utils::ty::is_type_diagnostic_item; use if_chain::if_chain; use rustc_errors::Applicability; -use rustc_hir::{Expr, ExprKind, PatKind, QPath}; +use rustc_hir::{Expr, ExprKind, LangItem, PatKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::sym; @@ -58,17 +58,18 @@ impl<'tcx> LateLintPass<'tcx> for MatchResultOk { }; if_chain! { - if let ExprKind::MethodCall(ok_path, result_types_0, ..) = let_expr.kind; //check is expr.ok() has type Result.ok(, _) - if let PatKind::TupleStruct(QPath::Resolved(_, x), y, _) = let_pat.kind; //get operation - if method_chain_args(let_expr, &["ok"]).is_some(); //test to see if using ok() method use std::marker::Sized; - if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(result_types_0), sym::Result); - if rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| s.print_path(x, false)) == "Some"; - + if let ExprKind::MethodCall(ok_path, recv, [], ..) = let_expr.kind; //check is expr.ok() has type Result.ok(, _) + if let PatKind::TupleStruct(ref pat_path, [ok_pat], _) = let_pat.kind; //get operation + if ok_path.ident.as_str() == "ok"; + if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Result); + if is_res_lang_ctor(cx, cx.qpath_res(pat_path, let_pat.hir_id), LangItem::OptionSome); + let ctxt = expr.span.ctxt(); + if let_expr.span.ctxt() == ctxt; + if let_pat.span.ctxt() == ctxt; then { - let mut applicability = Applicability::MachineApplicable; - let some_expr_string = snippet_with_applicability(cx, y[0].span, "", &mut applicability); - let trimmed_ok = snippet_with_applicability(cx, let_expr.span.until(ok_path.ident.span), "", &mut applicability); + let some_expr_string = snippet_with_context(cx, ok_pat.span, ctxt, "", &mut applicability).0; + let trimmed_ok = snippet_with_context(cx, recv.span, ctxt, "", &mut applicability).0; let sugg = format!( "{ifwhile} let Ok({some_expr_string}) = {}", trimmed_ok.trim().trim_end_matches('.'), diff --git a/clippy_lints/src/matches/mod.rs b/clippy_lints/src/matches/mod.rs index 7b15a307fec..97ecca450fa 100644 --- a/clippy_lints/src/matches/mod.rs +++ b/clippy_lints/src/matches/mod.rs @@ -925,7 +925,7 @@ declare_clippy_lint! { #[clippy::version = "1.66.0"] pub MANUAL_FILTER, complexity, - "reimplentation of `filter`" + "reimplementation of `filter`" } #[derive(Default)] diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs index 702df4b282b..56e3988bf09 100644 --- a/clippy_lints/src/methods/mod.rs +++ b/clippy_lints/src/methods/mod.rs @@ -340,8 +340,9 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for methods with certain name prefixes and which - /// doesn't match how self is taken. The actual rules are: + /// Checks for methods with certain name prefixes or suffixes, and which + /// do not adhere to standard conventions regarding how `self` is taken. + /// The actual rules are: /// /// |Prefix |Postfix |`self` taken | `self` type | /// |-------|------------|-------------------------------|--------------| diff --git a/clippy_lints/src/missing_assert_message.rs b/clippy_lints/src/missing_assert_message.rs new file mode 100644 index 00000000000..2214a568d9c --- /dev/null +++ b/clippy_lints/src/missing_assert_message.rs @@ -0,0 +1,82 @@ +use clippy_utils::diagnostics::span_lint_and_help; +use clippy_utils::macros::{find_assert_args, find_assert_eq_args, root_macro_call_first_node, PanicExpn}; +use clippy_utils::{is_in_cfg_test, is_in_test_function}; +use rustc_hir::Expr; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_span::sym; + +declare_clippy_lint! { + /// ### What it does + /// Checks assertions without a custom panic message. + /// + /// ### Why is this bad? + /// Without a good custom message, it'd be hard to understand what went wrong when the assertion fails. + /// A good custom message should be more about why the failure of the assertion is problematic + /// and not what is failed because the assertion already conveys that. + /// + /// ### Known problems + /// This lint cannot check the quality of the custom panic messages. + /// Hence, you can suppress this lint simply by adding placeholder messages + /// like "assertion failed". However, we recommend coming up with good messages + /// that provide useful information instead of placeholder messages that + /// don't provide any extra information. + /// + /// ### Example + /// ```rust + /// # struct Service { ready: bool } + /// fn call(service: Service) { + /// assert!(service.ready); + /// } + /// ``` + /// Use instead: + /// ```rust + /// # struct Service { ready: bool } + /// fn call(service: Service) { + /// assert!(service.ready, "`service.poll_ready()` must be called first to ensure that service is ready to receive requests"); + /// } + /// ``` + #[clippy::version = "1.69.0"] + pub MISSING_ASSERT_MESSAGE, + restriction, + "checks assertions without a custom panic message" +} + +declare_lint_pass!(MissingAssertMessage => [MISSING_ASSERT_MESSAGE]); + +impl<'tcx> LateLintPass<'tcx> for MissingAssertMessage { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { + let Some(macro_call) = root_macro_call_first_node(cx, expr) else { return }; + let single_argument = match cx.tcx.get_diagnostic_name(macro_call.def_id) { + Some(sym::assert_macro | sym::debug_assert_macro) => true, + Some( + sym::assert_eq_macro | sym::assert_ne_macro | sym::debug_assert_eq_macro | sym::debug_assert_ne_macro, + ) => false, + _ => return, + }; + + // This lint would be very noisy in tests, so just ignore if we're in test context + if is_in_test_function(cx.tcx, expr.hir_id) || is_in_cfg_test(cx.tcx, expr.hir_id) { + return; + } + + let panic_expn = if single_argument { + let Some((_, panic_expn)) = find_assert_args(cx, expr, macro_call.expn) else { return }; + panic_expn + } else { + let Some((_, _, panic_expn)) = find_assert_eq_args(cx, expr, macro_call.expn) else { return }; + panic_expn + }; + + if let PanicExpn::Empty = panic_expn { + span_lint_and_help( + cx, + MISSING_ASSERT_MESSAGE, + macro_call.span, + "assert without any message", + None, + "consider describing why the failing assert is problematic", + ); + } + } +} diff --git a/clippy_lints/src/missing_doc.rs b/clippy_lints/src/missing_doc.rs index 5b1f03fc16c..f2773cad400 100644 --- a/clippy_lints/src/missing_doc.rs +++ b/clippy_lints/src/missing_doc.rs @@ -8,10 +8,10 @@ use clippy_utils::attrs::is_doc_hidden; use clippy_utils::diagnostics::span_lint; use clippy_utils::is_from_proc_macro; -use hir::def_id::LocalDefId; use if_chain::if_chain; use rustc_ast::ast::{self, MetaItem, MetaItemKind}; use rustc_hir as hir; +use rustc_hir::def_id::LocalDefId; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::ty::Visibility; use rustc_session::{declare_tool_lint, impl_lint_pass}; @@ -21,8 +21,7 @@ use rustc_span::sym; declare_clippy_lint! { /// ### What it does - /// Warns if there is missing doc for any documentable item - /// (public or private). + /// Warns if there is missing doc for any private documentable item /// /// ### Why is this bad? /// Doc is good. *rustc* has a `MISSING_DOCS` @@ -32,7 +31,7 @@ declare_clippy_lint! { #[clippy::version = "pre 1.29.0"] pub MISSING_DOCS_IN_PRIVATE_ITEMS, restriction, - "detects missing documentation for public and private members" + "detects missing documentation for private members" } pub struct MissingDoc { @@ -107,11 +106,14 @@ impl MissingDoc { if vis == Visibility::Public || vis != Visibility::Restricted(CRATE_DEF_ID.into()) { return; } + } else if def_id != CRATE_DEF_ID && cx.effective_visibilities.is_exported(def_id) { + return; } let has_doc = attrs .iter() .any(|a| a.doc_str().is_some() || Self::has_include(a.meta())); + if !has_doc { span_lint( cx, diff --git a/clippy_lints/src/multiple_unsafe_ops_per_block.rs b/clippy_lints/src/multiple_unsafe_ops_per_block.rs index 63c575fca30..5418616ded0 100644 --- a/clippy_lints/src/multiple_unsafe_ops_per_block.rs +++ b/clippy_lints/src/multiple_unsafe_ops_per_block.rs @@ -11,6 +11,7 @@ use rustc_ast::Mutability; use rustc_hir as hir; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::lint::in_external_macro; +use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::Span; @@ -120,33 +121,15 @@ fn collect_unsafe_exprs<'tcx>( unsafe_ops.push(("raw pointer dereference occurs here", expr.span)); }, - ExprKind::Call(path_expr, _) => match path_expr.kind { - ExprKind::Path(QPath::Resolved( - _, - hir::Path { - res: Res::Def(kind, def_id), - .. - }, - )) if kind.is_fn_like() => { - let sig = cx.tcx.fn_sig(*def_id); - if sig.0.unsafety() == Unsafety::Unsafe { - unsafe_ops.push(("unsafe function call occurs here", expr.span)); - } - }, - - ExprKind::Path(QPath::TypeRelative(..)) => { - if let Some(sig) = cx - .typeck_results() - .type_dependent_def_id(path_expr.hir_id) - .map(|def_id| cx.tcx.fn_sig(def_id)) - { - if sig.0.unsafety() == Unsafety::Unsafe { - unsafe_ops.push(("unsafe function call occurs here", expr.span)); - } - } - }, - - _ => {}, + ExprKind::Call(path_expr, _) => { + let sig = match *cx.typeck_results().expr_ty(path_expr).kind() { + ty::FnDef(id, _) => cx.tcx.fn_sig(id).skip_binder(), + ty::FnPtr(sig) => sig, + _ => return Continue(Descend::Yes), + }; + if sig.unsafety() == Unsafety::Unsafe { + unsafe_ops.push(("unsafe function call occurs here", expr.span)); + } }, ExprKind::MethodCall(..) => { diff --git a/clippy_lints/src/neg_multiply.rs b/clippy_lints/src/neg_multiply.rs index fb9a4abd0b4..ed3e2c6e7f4 100644 --- a/clippy_lints/src/neg_multiply.rs +++ b/clippy_lints/src/neg_multiply.rs @@ -1,6 +1,6 @@ use clippy_utils::consts::{self, Constant}; use clippy_utils::diagnostics::span_lint_and_sugg; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::snippet_with_context; use clippy_utils::sugg::has_enclosing_paren; use if_chain::if_chain; use rustc_ast::util::parser::PREC_PREFIX; @@ -60,8 +60,8 @@ fn check_mul(cx: &LateContext<'_>, span: Span, lit: &Expr<'_>, exp: &Expr<'_>) { then { let mut applicability = Applicability::MachineApplicable; - let snip = snippet_with_applicability(cx, exp.span, "..", &mut applicability); - let suggestion = if exp.precedence().order() < PREC_PREFIX && !has_enclosing_paren(&snip) { + let (snip, from_macro) = snippet_with_context(cx, exp.span, span.ctxt(), "..", &mut applicability); + let suggestion = if !from_macro && exp.precedence().order() < PREC_PREFIX && !has_enclosing_paren(&snip) { format!("-({snip})") } else { format!("-{snip}") diff --git a/clippy_lints/src/non_octal_unix_permissions.rs b/clippy_lints/src/non_octal_unix_permissions.rs index 2ecb0487484..e1de494eb41 100644 --- a/clippy_lints/src/non_octal_unix_permissions.rs +++ b/clippy_lints/src/non_octal_unix_permissions.rs @@ -53,6 +53,7 @@ impl<'tcx> LateLintPass<'tcx> for NonOctalUnixPermissions { || is_type_diagnostic_item(cx, obj_ty, sym::DirBuilder))) || (path.ident.name == sym!(set_mode) && match_type(cx, obj_ty, &paths::PERMISSIONS)); if let ExprKind::Lit(_) = param.kind; + if param.span.ctxt() == expr.span.ctxt(); then { let Some(snip) = snippet_opt(cx, param.span) else { @@ -71,6 +72,7 @@ impl<'tcx> LateLintPass<'tcx> for NonOctalUnixPermissions { if let Some(def_id) = cx.qpath_res(path, func.hir_id).opt_def_id(); if match_def_path(cx, def_id, &paths::PERMISSIONS_FROM_MODE); if let ExprKind::Lit(_) = param.kind; + if param.span.ctxt() == expr.span.ctxt(); if let Some(snip) = snippet_opt(cx, param.span); if !snip.starts_with("0o"); then { diff --git a/clippy_lints/src/operators/arithmetic_side_effects.rs b/clippy_lints/src/operators/arithmetic_side_effects.rs index 87a8a2ed12b..25e8de94863 100644 --- a/clippy_lints/src/operators/arithmetic_side_effects.rs +++ b/clippy_lints/src/operators/arithmetic_side_effects.rs @@ -143,6 +143,10 @@ impl ArithmeticSideEffects { return; } let has_valid_op = if Self::is_integral(lhs_ty) && Self::is_integral(rhs_ty) { + if let hir::BinOpKind::Shl | hir::BinOpKind::Shr = op.node { + // At least for integers, shifts are already handled by the CTFE + return; + } let (actual_lhs, lhs_ref_counter) = peel_hir_expr_refs(lhs); let (actual_rhs, rhs_ref_counter) = peel_hir_expr_refs(rhs); match ( @@ -151,10 +155,13 @@ impl ArithmeticSideEffects { ) { (None, None) => false, (None, Some(n)) | (Some(n), None) => match (&op.node, n) { - (hir::BinOpKind::Div | hir::BinOpKind::Rem, 0) => false, + // Division and module are always valid if applied to non-zero integers + (hir::BinOpKind::Div | hir::BinOpKind::Rem, local_n) if local_n != 0 => true, + // Addition or subtracting zeros is always a no-op (hir::BinOpKind::Add | hir::BinOpKind::Sub, 0) - | (hir::BinOpKind::Div | hir::BinOpKind::Rem, _) - | (hir::BinOpKind::Mul, 0 | 1) => true, + // Multiplication by 1 or 0 will never overflow + | (hir::BinOpKind::Mul, 0 | 1) + => true, _ => false, }, (Some(_), Some(_)) => { diff --git a/clippy_lints/src/permissions_set_readonly_false.rs b/clippy_lints/src/permissions_set_readonly_false.rs index e7095ec191f..664d44d6504 100644 --- a/clippy_lints/src/permissions_set_readonly_false.rs +++ b/clippy_lints/src/permissions_set_readonly_false.rs @@ -21,7 +21,7 @@ declare_clippy_lint! { /// let mut permissions = metadata.permissions(); /// permissions.set_readonly(false); /// ``` - #[clippy::version = "1.66.0"] + #[clippy::version = "1.68.0"] pub PERMISSIONS_SET_READONLY_FALSE, suspicious, "Checks for calls to `std::fs::Permissions.set_readonly` with argument `false`" diff --git a/clippy_lints/src/redundant_async_block.rs b/clippy_lints/src/redundant_async_block.rs new file mode 100644 index 00000000000..27ad4308637 --- /dev/null +++ b/clippy_lints/src/redundant_async_block.rs @@ -0,0 +1,84 @@ +use clippy_utils::{diagnostics::span_lint_and_sugg, source::snippet}; +use rustc_ast::ast::*; +use rustc_ast::visit::Visitor as AstVisitor; +use rustc_errors::Applicability; +use rustc_lint::{EarlyContext, EarlyLintPass}; +use rustc_session::{declare_lint_pass, declare_tool_lint}; + +declare_clippy_lint! { + /// ### What it does + /// Checks for `async` block that only returns `await` on a future. + /// + /// ### Why is this bad? + /// It is simpler and more efficient to use the future directly. + /// + /// ### Example + /// ```rust + /// async fn f() -> i32 { + /// 1 + 2 + /// } + /// + /// let fut = async { + /// f().await + /// }; + /// ``` + /// Use instead: + /// ```rust + /// async fn f() -> i32 { + /// 1 + 2 + /// } + /// + /// let fut = f(); + /// ``` + #[clippy::version = "1.69.0"] + pub REDUNDANT_ASYNC_BLOCK, + complexity, + "`async { future.await }` can be replaced by `future`" +} +declare_lint_pass!(RedundantAsyncBlock => [REDUNDANT_ASYNC_BLOCK]); + +impl EarlyLintPass for RedundantAsyncBlock { + fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { + if expr.span.from_expansion() { + return; + } + if let ExprKind::Async(_, _, block) = &expr.kind && block.stmts.len() == 1 && + let Some(Stmt { kind: StmtKind::Expr(last), .. }) = block.stmts.last() && + let ExprKind::Await(future) = &last.kind && + !future.span.from_expansion() && + !await_in_expr(future) + { + span_lint_and_sugg( + cx, + REDUNDANT_ASYNC_BLOCK, + expr.span, + "this async expression only awaits a single future", + "you can reduce it to", + snippet(cx, future.span, "..").into_owned(), + Applicability::MachineApplicable, + ); + } + } +} + +/// Check whether an expression contains `.await` +fn await_in_expr(expr: &Expr) -> bool { + let mut detector = AwaitDetector::default(); + detector.visit_expr(expr); + detector.await_found +} + +#[derive(Default)] +struct AwaitDetector { + await_found: bool, +} + +impl<'ast> AstVisitor<'ast> for AwaitDetector { + fn visit_expr(&mut self, ex: &'ast Expr) { + match (&ex.kind, self.await_found) { + (ExprKind::Await(_), _) => self.await_found = true, + (_, false) => rustc_ast::visit::walk_expr(self, ex), + _ => (), + } + } +} diff --git a/clippy_lints/src/size_of_ref.rs b/clippy_lints/src/size_of_ref.rs index 3fcdb4288ce..8abec06c641 100644 --- a/clippy_lints/src/size_of_ref.rs +++ b/clippy_lints/src/size_of_ref.rs @@ -45,7 +45,7 @@ declare_clippy_lint! { /// } /// } /// ``` - #[clippy::version = "1.67.0"] + #[clippy::version = "1.68.0"] pub SIZE_OF_REF, suspicious, "Argument to `std::mem::size_of_val()` is a double-reference, which is almost certainly unintended" diff --git a/clippy_lints/src/swap.rs b/clippy_lints/src/swap.rs index 0f062cecf88..1aeac724ab1 100644 --- a/clippy_lints/src/swap.rs +++ b/clippy_lints/src/swap.rs @@ -1,5 +1,5 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; -use clippy_utils::source::snippet_with_applicability; +use clippy_utils::source::snippet_with_context; use clippy_utils::sugg::Sugg; use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::{can_mut_borrow_both, eq_expr_value, in_constant, std_or_core}; @@ -10,6 +10,7 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Spanned; +use rustc_span::SyntaxContext; use rustc_span::{sym, symbol::Ident, Span}; declare_clippy_lint! { @@ -80,43 +81,45 @@ impl<'tcx> LateLintPass<'tcx> for Swap { } fn generate_swap_warning(cx: &LateContext<'_>, e1: &Expr<'_>, e2: &Expr<'_>, span: Span, is_xor_based: bool) { + let ctxt = span.ctxt(); let mut applicability = Applicability::MachineApplicable; if !can_mut_borrow_both(cx, e1, e2) { - if let ExprKind::Index(lhs1, idx1) = e1.kind { - if let ExprKind::Index(lhs2, idx2) = e2.kind { - if eq_expr_value(cx, lhs1, lhs2) { - let ty = cx.typeck_results().expr_ty(lhs1).peel_refs(); + if let ExprKind::Index(lhs1, idx1) = e1.kind + && let ExprKind::Index(lhs2, idx2) = e2.kind + && eq_expr_value(cx, lhs1, lhs2) + && e1.span.ctxt() == ctxt + && e2.span.ctxt() == ctxt + { + let ty = cx.typeck_results().expr_ty(lhs1).peel_refs(); - if matches!(ty.kind(), ty::Slice(_)) - || matches!(ty.kind(), ty::Array(_, _)) - || is_type_diagnostic_item(cx, ty, sym::Vec) - || is_type_diagnostic_item(cx, ty, sym::VecDeque) - { - let slice = Sugg::hir_with_applicability(cx, lhs1, "", &mut applicability); - span_lint_and_sugg( - cx, - MANUAL_SWAP, - span, - &format!("this looks like you are swapping elements of `{slice}` manually"), - "try", - format!( - "{}.swap({}, {})", - slice.maybe_par(), - snippet_with_applicability(cx, idx1.span, "..", &mut applicability), - snippet_with_applicability(cx, idx2.span, "..", &mut applicability), - ), - applicability, - ); - } - } + if matches!(ty.kind(), ty::Slice(_)) + || matches!(ty.kind(), ty::Array(_, _)) + || is_type_diagnostic_item(cx, ty, sym::Vec) + || is_type_diagnostic_item(cx, ty, sym::VecDeque) + { + let slice = Sugg::hir_with_applicability(cx, lhs1, "", &mut applicability); + span_lint_and_sugg( + cx, + MANUAL_SWAP, + span, + &format!("this looks like you are swapping elements of `{slice}` manually"), + "try", + format!( + "{}.swap({}, {});", + slice.maybe_par(), + snippet_with_context(cx, idx1.span, ctxt, "..", &mut applicability).0, + snippet_with_context(cx, idx2.span, ctxt, "..", &mut applicability).0, + ), + applicability, + ); } } return; } - let first = Sugg::hir_with_applicability(cx, e1, "..", &mut applicability); - let second = Sugg::hir_with_applicability(cx, e2, "..", &mut applicability); + let first = Sugg::hir_with_context(cx, e1, ctxt, "..", &mut applicability); + let second = Sugg::hir_with_context(cx, e2, ctxt, "..", &mut applicability); let Some(sugg) = std_or_core(cx) else { return }; span_lint_and_then( @@ -128,7 +131,7 @@ fn generate_swap_warning(cx: &LateContext<'_>, e1: &Expr<'_>, e2: &Expr<'_>, spa diag.span_suggestion( span, "try", - format!("{sugg}::mem::swap({}, {})", first.mut_addr(), second.mut_addr()), + format!("{sugg}::mem::swap({}, {});", first.mut_addr(), second.mut_addr()), applicability, ); if !is_xor_based { @@ -144,19 +147,19 @@ fn check_manual_swap(cx: &LateContext<'_>, block: &Block<'_>) { return; } - for w in block.stmts.windows(3) { + for [s1, s2, s3] in block.stmts.array_windows::<3>() { if_chain! { // let t = foo(); - if let StmtKind::Local(tmp) = w[0].kind; + if let StmtKind::Local(tmp) = s1.kind; if let Some(tmp_init) = tmp.init; if let PatKind::Binding(.., ident, None) = tmp.pat.kind; // foo() = bar(); - if let StmtKind::Semi(first) = w[1].kind; + if let StmtKind::Semi(first) = s2.kind; if let ExprKind::Assign(lhs1, rhs1, _) = first.kind; // bar() = t; - if let StmtKind::Semi(second) = w[2].kind; + if let StmtKind::Semi(second) = s3.kind; if let ExprKind::Assign(lhs2, rhs2, _) = second.kind; if let ExprKind::Path(QPath::Resolved(None, rhs2)) = rhs2.kind; if rhs2.segments.len() == 1; @@ -164,8 +167,15 @@ fn check_manual_swap(cx: &LateContext<'_>, block: &Block<'_>) { if ident.name == rhs2.segments[0].ident.name; if eq_expr_value(cx, tmp_init, lhs1); if eq_expr_value(cx, rhs1, lhs2); + + let ctxt = s1.span.ctxt(); + if s2.span.ctxt() == ctxt; + if s3.span.ctxt() == ctxt; + if first.span.ctxt() == ctxt; + if second.span.ctxt() == ctxt; + then { - let span = w[0].span.to(second.span); + let span = s1.span.to(s3.span); generate_swap_warning(cx, lhs1, lhs2, span, false); } } @@ -246,17 +256,20 @@ fn parse<'a, 'hir>(stmt: &'a Stmt<'hir>) -> Option<(ExprOrIdent<'hir>, &'a Expr< /// Implementation of the xor case for `MANUAL_SWAP` lint. fn check_xor_swap(cx: &LateContext<'_>, block: &Block<'_>) { - for window in block.stmts.windows(3) { + for [s1, s2, s3] in block.stmts.array_windows::<3>() { if_chain! { - if let Some((lhs0, rhs0)) = extract_sides_of_xor_assign(&window[0]); - if let Some((lhs1, rhs1)) = extract_sides_of_xor_assign(&window[1]); - if let Some((lhs2, rhs2)) = extract_sides_of_xor_assign(&window[2]); + let ctxt = s1.span.ctxt(); + if let Some((lhs0, rhs0)) = extract_sides_of_xor_assign(s1, ctxt); + if let Some((lhs1, rhs1)) = extract_sides_of_xor_assign(s2, ctxt); + if let Some((lhs2, rhs2)) = extract_sides_of_xor_assign(s3, ctxt); if eq_expr_value(cx, lhs0, rhs1); if eq_expr_value(cx, lhs2, rhs1); if eq_expr_value(cx, lhs1, rhs0); if eq_expr_value(cx, lhs1, rhs2); + if s2.span.ctxt() == ctxt; + if s3.span.ctxt() == ctxt; then { - let span = window[0].span.to(window[2].span); + let span = s1.span.to(s3.span); generate_swap_warning(cx, lhs0, rhs0, span, true); } }; @@ -264,9 +277,12 @@ fn check_xor_swap(cx: &LateContext<'_>, block: &Block<'_>) { } /// Returns the lhs and rhs of an xor assignment statement. -fn extract_sides_of_xor_assign<'a, 'hir>(stmt: &'a Stmt<'hir>) -> Option<(&'a Expr<'hir>, &'a Expr<'hir>)> { - if let StmtKind::Semi(expr) = stmt.kind { - if let ExprKind::AssignOp( +fn extract_sides_of_xor_assign<'a, 'hir>( + stmt: &'a Stmt<'hir>, + ctxt: SyntaxContext, +) -> Option<(&'a Expr<'hir>, &'a Expr<'hir>)> { + if let StmtKind::Semi(expr) = stmt.kind + && let ExprKind::AssignOp( Spanned { node: BinOpKind::BitXor, .. @@ -274,9 +290,10 @@ fn extract_sides_of_xor_assign<'a, 'hir>(stmt: &'a Stmt<'hir>) -> Option<(&'a Ex lhs, rhs, ) = expr.kind - { - return Some((lhs, rhs)); - } + && expr.span.ctxt() == ctxt + { + Some((lhs, rhs)) + } else { + None } - None } diff --git a/clippy_lints/src/transmute/mod.rs b/clippy_lints/src/transmute/mod.rs index c01cbe5090f..0dc30f7a935 100644 --- a/clippy_lints/src/transmute/mod.rs +++ b/clippy_lints/src/transmute/mod.rs @@ -458,7 +458,7 @@ declare_clippy_lint! { /// ```rust /// let null_fn: Option = None; /// ``` - #[clippy::version = "1.67.0"] + #[clippy::version = "1.68.0"] pub TRANSMUTE_NULL_TO_FN, correctness, "transmute results in a null function pointer, which is undefined behavior" diff --git a/clippy_lints/src/unit_types/let_unit_value.rs b/clippy_lints/src/unit_types/let_unit_value.rs index d6167a62169..3430b6e3734 100644 --- a/clippy_lints/src/unit_types/let_unit_value.rs +++ b/clippy_lints/src/unit_types/let_unit_value.rs @@ -5,7 +5,7 @@ use clippy_utils::visitors::{for_each_local_assignment, for_each_value_source}; use core::ops::ControlFlow; use rustc_errors::Applicability; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::{Expr, ExprKind, HirId, HirIdSet, Local, Node, PatKind, QPath, TyKind}; +use rustc_hir::{Expr, ExprKind, HirId, HirIdSet, Local, MatchSource, Node, PatKind, QPath, TyKind}; use rustc_lint::{LateContext, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_middle::ty; @@ -41,6 +41,10 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, local: &'tcx Local<'_>) { ); } } else { + if let ExprKind::Match(_, _, MatchSource::AwaitDesugar) = init.kind { + return + } + span_lint_and_then( cx, LET_UNIT_VALUE, diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs index e7c54000684..8ea5475fb25 100644 --- a/clippy_lints/src/use_self.rs +++ b/clippy_lints/src/use_self.rs @@ -10,8 +10,8 @@ use rustc_hir::{ def::{CtorOf, DefKind, Res}, def_id::LocalDefId, intravisit::{walk_inf, walk_ty, Visitor}, - Expr, ExprKind, FnRetTy, FnSig, GenericArg, HirId, Impl, ImplItemKind, Item, ItemKind, Pat, PatKind, Path, QPath, - TyKind, + Expr, ExprKind, FnRetTy, FnSig, GenericArg, GenericParam, GenericParamKind, HirId, Impl, ImplItemKind, Item, + ItemKind, Pat, PatKind, Path, QPath, Ty, TyKind, }; use rustc_hir_analysis::hir_ty_to_ty; use rustc_lint::{LateContext, LateLintPass}; @@ -96,7 +96,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { // avoid linting on nested items, we push `StackItem::NoCheck` on the stack to signal, that // we're in an `impl` or nested item, that we don't want to lint let stack_item = if_chain! { - if let ItemKind::Impl(Impl { self_ty, .. }) = item.kind; + if let ItemKind::Impl(Impl { self_ty, generics,.. }) = item.kind; if let TyKind::Path(QPath::Resolved(_, item_path)) = self_ty.kind; let parameters = &item_path.segments.last().expect(SEGMENTS_MSG).args; if parameters.as_ref().map_or(true, |params| { @@ -105,10 +105,17 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { if !item.span.from_expansion(); if !is_from_proc_macro(cx, item); // expensive, should be last check then { + // Self cannot be used inside const generic parameters + let types_to_skip = generics.params.iter().filter_map(|param| { + match param { + GenericParam { kind: GenericParamKind::Const { ty: Ty { hir_id, ..}, ..}, ..} => Some(*hir_id), + _ => None, + } + }).chain(std::iter::once(self_ty.hir_id)).collect(); StackItem::Check { impl_id: item.owner_id.def_id, in_body: 0, - types_to_skip: std::iter::once(self_ty.hir_id).collect(), + types_to_skip, } } else { StackItem::NoCheck diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs index c37e5bb6716..f31c3fdb095 100644 --- a/clippy_lints/src/utils/author.rs +++ b/clippy_lints/src/utils/author.rs @@ -588,7 +588,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { }, } }, - ExprKind::Err(_) => kind!("Err"), + ExprKind::Err(_) => kind!("Err(_)"), ExprKind::DropTemps(expr) => { bind!(self, expr); kind!("DropTemps({expr})"); diff --git a/clippy_lints/src/utils/format_args_collector.rs b/clippy_lints/src/utils/format_args_collector.rs new file mode 100644 index 00000000000..be56b842b98 --- /dev/null +++ b/clippy_lints/src/utils/format_args_collector.rs @@ -0,0 +1,23 @@ +use clippy_utils::macros::collect_ast_format_args; +use rustc_ast::{Expr, ExprKind}; +use rustc_lint::{EarlyContext, EarlyLintPass}; +use rustc_session::{declare_lint_pass, declare_tool_lint}; + +declare_clippy_lint! { + /// ### What it does + /// Collects [`rustc_ast::FormatArgs`] so that future late passes can call + /// [`clippy_utils::macros::find_format_args`] + pub FORMAT_ARGS_COLLECTOR, + internal_warn, + "collects `format_args` AST nodes for use in later lints" +} + +declare_lint_pass!(FormatArgsCollector => [FORMAT_ARGS_COLLECTOR]); + +impl EarlyLintPass for FormatArgsCollector { + fn check_expr(&mut self, _: &EarlyContext<'_>, expr: &Expr) { + if let ExprKind::FormatArgs(args) = &expr.kind { + collect_ast_format_args(expr.span, args); + } + } +} diff --git a/clippy_lints/src/utils/internal_lints/metadata_collector.rs b/clippy_lints/src/utils/internal_lints/metadata_collector.rs index b1b5164ffb3..3d0d4a52511 100644 --- a/clippy_lints/src/utils/internal_lints/metadata_collector.rs +++ b/clippy_lints/src/utils/internal_lints/metadata_collector.rs @@ -26,7 +26,7 @@ use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::symbol::Ident; use rustc_span::{sym, Loc, Span, Symbol}; use serde::{ser::SerializeStruct, Serialize, Serializer}; -use std::collections::BinaryHeap; +use std::collections::{BTreeSet, BinaryHeap}; use std::fmt; use std::fmt::Write as _; use std::fs::{self, OpenOptions}; @@ -264,6 +264,9 @@ struct LintMetadata { /// This field is only used in the output and will only be /// mapped shortly before the actual output. applicability: Option, + /// All the past names of lints which have been renamed. + #[serde(skip_serializing_if = "BTreeSet::is_empty")] + former_ids: BTreeSet, } impl LintMetadata { @@ -283,6 +286,7 @@ impl LintMetadata { version, docs, applicability: None, + former_ids: BTreeSet::new(), } } } @@ -901,6 +905,7 @@ fn collect_renames(lints: &mut Vec) { if name == lint_name; if let Some(past_name) = k.strip_prefix(CLIPPY_LINT_GROUP_PREFIX); then { + lint.former_ids.insert(past_name.to_owned()); writeln!(collected, "* `{past_name}`").unwrap(); names.push(past_name.to_string()); } diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 787e9fd982c..dc647af264c 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -1,5 +1,6 @@ pub mod author; pub mod conf; pub mod dump_hir; +pub mod format_args_collector; #[cfg(feature = "internal")] pub mod internal_lints; diff --git a/clippy_lints/src/write.rs b/clippy_lints/src/write.rs index df335038881..8114a8463fa 100644 --- a/clippy_lints/src/write.rs +++ b/clippy_lints/src/write.rs @@ -1,10 +1,11 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_then}; -use clippy_utils::macros::{root_macro_call_first_node, FormatArgsExpn, MacroCall}; +use clippy_utils::macros::{find_format_args, format_arg_removal_span, root_macro_call_first_node, MacroCall}; use clippy_utils::source::{expand_past_previous_comma, snippet_opt}; use clippy_utils::{is_in_cfg_test, is_in_test_function}; -use rustc_ast::LitKind; +use rustc_ast::token::LitKind; +use rustc_ast::{FormatArgPosition, FormatArgs, FormatArgsPiece, FormatOptions, FormatPlaceholder, FormatTrait}; use rustc_errors::Applicability; -use rustc_hir::{Expr, ExprKind, HirIdMap, Impl, Item, ItemKind}; +use rustc_hir::{Expr, Impl, Item, ItemKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::{sym, BytePos}; @@ -297,34 +298,40 @@ impl<'tcx> LateLintPass<'tcx> for Write { _ => return, } - let Some(format_args) = FormatArgsExpn::find_nested(cx, expr, macro_call.expn) else { return }; + find_format_args(cx, expr, macro_call.expn, |format_args| { + // ignore `writeln!(w)` and `write!(v, some_macro!())` + if format_args.span.from_expansion() { + return; + } - // ignore `writeln!(w)` and `write!(v, some_macro!())` - if format_args.format_string.span.from_expansion() { - return; - } + match diag_name { + sym::print_macro | sym::eprint_macro | sym::write_macro => { + check_newline(cx, format_args, ¯o_call, name); + }, + sym::println_macro | sym::eprintln_macro | sym::writeln_macro => { + check_empty_string(cx, format_args, ¯o_call, name); + }, + _ => {}, + } - match diag_name { - sym::print_macro | sym::eprint_macro | sym::write_macro => { - check_newline(cx, &format_args, ¯o_call, name); - }, - sym::println_macro | sym::eprintln_macro | sym::writeln_macro => { - check_empty_string(cx, &format_args, ¯o_call, name); - }, - _ => {}, - } + check_literal(cx, format_args, name); - check_literal(cx, &format_args, name); - - if !self.in_debug_impl { - for arg in &format_args.args { - if arg.format.r#trait == sym::Debug { - span_lint(cx, USE_DEBUG, arg.span, "use of `Debug`-based formatting"); + if !self.in_debug_impl { + for piece in &format_args.template { + if let &FormatArgsPiece::Placeholder(FormatPlaceholder { + span: Some(span), + format_trait: FormatTrait::Debug, + .. + }) = piece + { + span_lint(cx, USE_DEBUG, span, "use of `Debug`-based formatting"); + } } } - } + }); } } + fn is_debug_impl(cx: &LateContext<'_>, item: &Item<'_>) -> bool { if let ItemKind::Impl(Impl { of_trait: Some(trait_ref), .. }) = &item.kind && let Some(trait_id) = trait_ref.trait_def_id() @@ -335,16 +342,18 @@ fn is_debug_impl(cx: &LateContext<'_>, item: &Item<'_>) -> bool { } } -fn check_newline(cx: &LateContext<'_>, format_args: &FormatArgsExpn<'_>, macro_call: &MacroCall, name: &str) { - let format_string_parts = &format_args.format_string.parts; - let mut format_string_span = format_args.format_string.span; - - let Some(last) = format_string_parts.last() else { return }; +fn check_newline(cx: &LateContext<'_>, format_args: &FormatArgs, macro_call: &MacroCall, name: &str) { + let Some(FormatArgsPiece::Literal(last)) = format_args.template.last() else { return }; let count_vertical_whitespace = || { - format_string_parts + format_args + .template .iter() - .flat_map(|part| part.as_str().chars()) + .filter_map(|piece| match piece { + FormatArgsPiece::Literal(literal) => Some(literal), + FormatArgsPiece::Placeholder(_) => None, + }) + .flat_map(|literal| literal.as_str().chars()) .filter(|ch| matches!(ch, '\r' | '\n')) .count() }; @@ -352,10 +361,9 @@ fn check_newline(cx: &LateContext<'_>, format_args: &FormatArgsExpn<'_>, macro_c if last.as_str().ends_with('\n') // ignore format strings with other internal vertical whitespace && count_vertical_whitespace() == 1 - - // ignore trailing arguments: `print!("Issue\n{}", 1265);` - && format_string_parts.len() > format_args.args.len() { + let mut format_string_span = format_args.span; + let lint = if name == "write" { format_string_span = expand_past_previous_comma(cx, format_string_span); @@ -373,7 +381,7 @@ fn check_newline(cx: &LateContext<'_>, format_args: &FormatArgsExpn<'_>, macro_c let name_span = cx.sess().source_map().span_until_char(macro_call.span, '!'); let Some(format_snippet) = snippet_opt(cx, format_string_span) else { return }; - if format_string_parts.len() == 1 && last.as_str() == "\n" { + if format_args.template.len() == 1 && last.as_str() == "\n" { // print!("\n"), write!(f, "\n") diag.multipart_suggestion( @@ -398,11 +406,12 @@ fn check_newline(cx: &LateContext<'_>, format_args: &FormatArgsExpn<'_>, macro_c } } -fn check_empty_string(cx: &LateContext<'_>, format_args: &FormatArgsExpn<'_>, macro_call: &MacroCall, name: &str) { - if let [part] = &format_args.format_string.parts[..] - && let mut span = format_args.format_string.span - && part.as_str() == "\n" +fn check_empty_string(cx: &LateContext<'_>, format_args: &FormatArgs, macro_call: &MacroCall, name: &str) { + if let [FormatArgsPiece::Literal(literal)] = &format_args.template[..] + && literal.as_str() == "\n" { + let mut span = format_args.span; + let lint = if name == "writeln" { span = expand_past_previous_comma(cx, span); @@ -428,33 +437,43 @@ fn check_empty_string(cx: &LateContext<'_>, format_args: &FormatArgsExpn<'_>, ma } } -fn check_literal(cx: &LateContext<'_>, format_args: &FormatArgsExpn<'_>, name: &str) { - let mut counts = HirIdMap::::default(); - for param in format_args.params() { - *counts.entry(param.value.hir_id).or_default() += 1; +fn check_literal(cx: &LateContext<'_>, format_args: &FormatArgs, name: &str) { + let arg_index = |argument: &FormatArgPosition| argument.index.unwrap_or_else(|pos| pos); + + let mut counts = vec![0u32; format_args.arguments.all_args().len()]; + for piece in &format_args.template { + if let FormatArgsPiece::Placeholder(placeholder) = piece { + counts[arg_index(&placeholder.argument)] += 1; + } } - for arg in &format_args.args { - let value = arg.param.value; - - if counts[&value.hir_id] == 1 - && arg.format.is_default() - && let ExprKind::Lit(lit) = &value.kind - && !value.span.from_expansion() - && let Some(value_string) = snippet_opt(cx, value.span) - { - let (replacement, replace_raw) = match lit.node { - LitKind::Str(..) => extract_str_literal(&value_string), - LitKind::Char(ch) => ( - match ch { - '"' => "\\\"", - '\'' => "'", + for piece in &format_args.template { + if let FormatArgsPiece::Placeholder(FormatPlaceholder { + argument, + span: Some(placeholder_span), + format_trait: FormatTrait::Display, + format_options, + }) = piece + && *format_options == FormatOptions::default() + && let index = arg_index(argument) + && counts[index] == 1 + && let Some(arg) = format_args.arguments.by_index(index) + && let rustc_ast::ExprKind::Lit(lit) = &arg.expr.kind + && !arg.expr.span.from_expansion() + && let Some(value_string) = snippet_opt(cx, arg.expr.span) + { + let (replacement, replace_raw) = match lit.kind { + LitKind::Str | LitKind::StrRaw(_) => extract_str_literal(&value_string), + LitKind::Char => ( + match lit.symbol.as_str() { + "\"" => "\\\"", + "\\'" => "'", _ => &value_string[1..value_string.len() - 1], } .to_string(), false, ), - LitKind::Bool(b) => (b.to_string(), false), + LitKind::Bool => (lit.symbol.to_string(), false), _ => continue, }; @@ -464,7 +483,9 @@ fn check_literal(cx: &LateContext<'_>, format_args: &FormatArgsExpn<'_>, name: & PRINT_LITERAL }; - let format_string_is_raw = format_args.format_string.style.is_some(); + let Some(format_string_snippet) = snippet_opt(cx, format_args.span) else { continue }; + let format_string_is_raw = format_string_snippet.starts_with('r'); + let replacement = match (format_string_is_raw, replace_raw) { (false, false) => Some(replacement), (false, true) => Some(replacement.replace('"', "\\\"").replace('\\', "\\\\")), @@ -485,23 +506,24 @@ fn check_literal(cx: &LateContext<'_>, format_args: &FormatArgsExpn<'_>, name: & span_lint_and_then( cx, lint, - value.span, + arg.expr.span, "literal with an empty format string", |diag| { if let Some(replacement) = replacement // `format!("{}", "a")`, `format!("{named}", named = "b") // ~~~~~ ~~~~~~~~~~~~~ - && let Some(value_span) = format_args.value_with_prev_comma_span(value.hir_id) + && let Some(removal_span) = format_arg_removal_span(format_args, index) { let replacement = replacement.replace('{', "{{").replace('}', "}}"); diag.multipart_suggestion( "try this", - vec![(arg.span, replacement), (value_span, String::new())], + vec![(*placeholder_span, replacement), (removal_span, String::new())], Applicability::MachineApplicable, ); } }, ); + } } } diff --git a/clippy_utils/Cargo.toml b/clippy_utils/Cargo.toml index 173469f6cdc..124ebd164e6 100644 --- a/clippy_utils/Cargo.toml +++ b/clippy_utils/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy_utils" -version = "0.1.69" +version = "0.1.70" edition = "2021" publish = false diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs index bcfedd07ed1..44b6b9f7b0b 100644 --- a/clippy_utils/src/lib.rs +++ b/clippy_utils/src/lib.rs @@ -617,7 +617,7 @@ fn item_children_by_name(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Vec, def_id: DefId) -> bool { matches!(name, sym::assert_macro | sym::debug_assert_macro) } +#[derive(Debug)] pub enum PanicExpn<'a> { /// No arguments - `panic!()` Empty, @@ -226,10 +231,7 @@ pub enum PanicExpn<'a> { impl<'a> PanicExpn<'a> { pub fn parse(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option { - if !macro_backtrace(expr.span).any(|macro_call| is_panic(cx, macro_call.def_id)) { - return None; - } - let ExprKind::Call(callee, [arg]) = &expr.kind else { return None }; + let ExprKind::Call(callee, [arg, rest @ ..]) = &expr.kind else { return None }; let ExprKind::Path(QPath::Resolved(_, path)) = &callee.kind else { return None }; let result = match path.segments.last().unwrap().ident.as_str() { "panic" if arg.span.ctxt() == expr.span.ctxt() => Self::Empty, @@ -239,6 +241,21 @@ impl<'a> PanicExpn<'a> { Self::Display(e) }, "panic_fmt" => Self::Format(FormatArgsExpn::parse(cx, arg)?), + // Since Rust 1.52, `assert_{eq,ne}` macros expand to use: + // `core::panicking::assert_failed(.., left_val, right_val, None | Some(format_args!(..)));` + "assert_failed" => { + // It should have 4 arguments in total (we already matched with the first argument, + // so we're just checking for 3) + if rest.len() != 3 { + return None; + } + // `msg_arg` is either `None` (no custom message) or `Some(format_args!(..))` (custom message) + let msg_arg = &rest[2]; + match msg_arg.kind { + ExprKind::Call(_, [fmt_arg]) => Self::Format(FormatArgsExpn::parse(cx, fmt_arg)?), + _ => Self::Empty, + } + }, _ => return None, }; Some(result) @@ -251,7 +268,17 @@ pub fn find_assert_args<'a>( expr: &'a Expr<'a>, expn: ExpnId, ) -> Option<(&'a Expr<'a>, PanicExpn<'a>)> { - find_assert_args_inner(cx, expr, expn).map(|([e], p)| (e, p)) + find_assert_args_inner(cx, expr, expn).map(|([e], mut p)| { + // `assert!(..)` expands to `core::panicking::panic("assertion failed: ...")` (which we map to + // `PanicExpn::Str(..)`) and `assert!(.., "..")` expands to + // `core::panicking::panic_fmt(format_args!(".."))` (which we map to `PanicExpn::Format(..)`). + // So even we got `PanicExpn::Str(..)` that means there is no custom message provided + if let PanicExpn::Str(_) = p { + p = PanicExpn::Empty; + } + + (e, p) + }) } /// Finds the arguments of an `assert_eq!` or `debug_assert_eq!` macro call within the macro @@ -275,13 +302,12 @@ fn find_assert_args_inner<'a, const N: usize>( Some(inner_name) => find_assert_within_debug_assert(cx, expr, expn, Symbol::intern(inner_name))?, }; let mut args = ArrayVec::new(); - let mut panic_expn = None; - let _: Option = for_each_expr(expr, |e| { + let panic_expn = for_each_expr(expr, |e| { if args.is_full() { - if panic_expn.is_none() && e.span.ctxt() != expr.span.ctxt() { - panic_expn = PanicExpn::parse(cx, e); + match PanicExpn::parse(cx, e) { + Some(expn) => ControlFlow::Break(expn), + None => ControlFlow::Continue(Descend::Yes), } - ControlFlow::Continue(Descend::from(panic_expn.is_none())) } else if is_assert_arg(cx, e, expn) { args.push(e); ControlFlow::Continue(Descend::No) @@ -339,6 +365,77 @@ fn is_assert_arg(cx: &LateContext<'_>, expr: &Expr<'_>, assert_expn: ExpnId) -> } } +thread_local! { + /// We preserve the [`FormatArgs`] structs from the early pass for use in the late pass to be + /// able to access the many features of a [`LateContext`]. + /// + /// A thread local is used because [`FormatArgs`] is `!Send` and `!Sync`, we are making an + /// assumption that the early pass the populates the map and the later late passes will all be + /// running on the same thread. + static AST_FORMAT_ARGS: RefCell> = { + static CALLED: AtomicBool = AtomicBool::new(false); + debug_assert!( + !CALLED.swap(true, Ordering::SeqCst), + "incorrect assumption: `AST_FORMAT_ARGS` should only be accessed by a single thread", + ); + + RefCell::default() + }; +} + +/// Record [`rustc_ast::FormatArgs`] for use in late lint passes, this should only be called by +/// `FormatArgsCollector` +pub fn collect_ast_format_args(span: Span, format_args: &FormatArgs) { + AST_FORMAT_ARGS.with(|ast_format_args| { + ast_format_args.borrow_mut().insert(span, format_args.clone()); + }); +} + +/// Calls `callback` with an AST [`FormatArgs`] node if one is found +pub fn find_format_args(cx: &LateContext<'_>, start: &Expr<'_>, expn_id: ExpnId, callback: impl FnOnce(&FormatArgs)) { + let format_args_expr = for_each_expr(start, |expr| { + let ctxt = expr.span.ctxt(); + if ctxt == start.span.ctxt() { + ControlFlow::Continue(Descend::Yes) + } else if ctxt.outer_expn().is_descendant_of(expn_id) + && macro_backtrace(expr.span) + .map(|macro_call| cx.tcx.item_name(macro_call.def_id)) + .any(|name| matches!(name, sym::const_format_args | sym::format_args | sym::format_args_nl)) + { + ControlFlow::Break(expr) + } else { + ControlFlow::Continue(Descend::No) + } + }); + + if let Some(format_args_expr) = format_args_expr { + AST_FORMAT_ARGS.with(|ast_format_args| { + ast_format_args.borrow().get(&format_args_expr.span).map(callback); + }); + } +} + +/// Returns the [`Span`] of the value at `index` extended to the previous comma, e.g. for the value +/// `10` +/// +/// ```ignore +/// format("{}.{}", 10, 11) +/// // ^^^^ +/// ``` +pub fn format_arg_removal_span(format_args: &FormatArgs, index: usize) -> Option { + let ctxt = format_args.span.ctxt(); + + let current = hygiene::walk_chain(format_args.arguments.by_index(index)?.expr.span, ctxt); + + let prev = if index == 0 { + format_args.span + } else { + hygiene::walk_chain(format_args.arguments.by_index(index - 1)?.expr.span, ctxt) + }; + + Some(current.with_lo(prev.hi())) +} + /// The format string doesn't exist in the HIR, so we reassemble it from source code #[derive(Debug)] pub struct FormatString { diff --git a/clippy_utils/src/ty.rs b/clippy_utils/src/ty.rs index 41e34eba0ad..e0ea3952785 100644 --- a/clippy_utils/src/ty.rs +++ b/clippy_utils/src/ty.rs @@ -16,9 +16,9 @@ use rustc_infer::infer::{ use rustc_lint::LateContext; use rustc_middle::mir::interpret::{ConstValue, Scalar}; use rustc_middle::ty::{ - self, AdtDef, AliasTy, AssocKind, Binder, BoundRegion, FnSig, IntTy, List, ParamEnv, Predicate, - PredicateKind, Region, RegionKind, SubstsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, - TypeVisitor, UintTy, VariantDef, VariantDiscr, + self, AdtDef, AliasTy, AssocKind, Binder, BoundRegion, FnSig, IntTy, List, ParamEnv, Predicate, PredicateKind, + Region, RegionKind, SubstsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, + UintTy, VariantDef, VariantDiscr, }; use rustc_middle::ty::{GenericArg, GenericArgKind}; use rustc_span::symbol::Ident; diff --git a/declare_clippy_lint/Cargo.toml b/declare_clippy_lint/Cargo.toml index 80eee368178..5c9f76dbbc6 100644 --- a/declare_clippy_lint/Cargo.toml +++ b/declare_clippy_lint/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "declare_clippy_lint" -version = "0.1.69" +version = "0.1.70" edition = "2021" publish = false diff --git a/lintcheck/Cargo.toml b/lintcheck/Cargo.toml index 653121af54d..27d32f39003 100644 --- a/lintcheck/Cargo.toml +++ b/lintcheck/Cargo.toml @@ -8,12 +8,16 @@ repository = "https://github.com/rust-lang/rust-clippy" categories = ["development-tools"] edition = "2021" publish = false +default-run = "lintcheck" [dependencies] +anyhow = "1.0.69" cargo_metadata = "0.15.3" -clap = "4.1.4" +clap = { version = "4.1.8", features = ["derive", "env"] } +crates_io_api = "0.8.1" crossbeam-channel = "0.5.6" flate2 = "1.0" +indicatif = "0.17.3" rayon = "1.5.1" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.85" @@ -24,3 +28,11 @@ walkdir = "2.3" [features] deny-warnings = [] + +[[bin]] +name = "lintcheck" +path = "src/main.rs" + +[[bin]] +name = "popular-crates" +path = "src/popular-crates.rs" diff --git a/lintcheck/README.md b/lintcheck/README.md index 6142de5e313..e997eb47e32 100644 --- a/lintcheck/README.md +++ b/lintcheck/README.md @@ -25,6 +25,15 @@ the repo root. The results will then be saved to `lintcheck-logs/custom_logs.toml`. +The `custom.toml` file may be built using recently most +downloaded crates by using the `popular-crates` binary from the `lintcheck` +directory. For example, to retrieve the 100 recently most downloaded crates: + +``` +cargo run --release --bin popular-crates -- -n 100 custom.toml +``` + + ### Configuring the Crate Sources The sources to check are saved in a `toml` file. There are three types of diff --git a/lintcheck/src/config.rs b/lintcheck/src/config.rs index e0244ddcecb..3f01e9bb0a7 100644 --- a/lintcheck/src/config.rs +++ b/lintcheck/src/config.rs @@ -1,131 +1,79 @@ -use clap::{Arg, ArgAction, ArgMatches, Command}; -use std::env; -use std::path::PathBuf; +use clap::Parser; +use std::{num::NonZeroUsize, path::PathBuf}; -fn get_clap_config() -> ArgMatches { - Command::new("lintcheck") - .about("run clippy on a set of crates and check output") - .args([ - Arg::new("only") - .action(ArgAction::Set) - .value_name("CRATE") - .long("only") - .help("Only process a single crate of the list"), - Arg::new("crates-toml") - .action(ArgAction::Set) - .value_name("CRATES-SOURCES-TOML-PATH") - .long("crates-toml") - .help("Set the path for a crates.toml where lintcheck should read the sources from"), - Arg::new("threads") - .action(ArgAction::Set) - .value_name("N") - .value_parser(clap::value_parser!(usize)) - .short('j') - .long("jobs") - .help("Number of threads to use, 0 automatic choice"), - Arg::new("fix") - .long("fix") - .help("Runs cargo clippy --fix and checks if all suggestions apply"), - Arg::new("filter") - .long("filter") - .action(ArgAction::Append) - .value_name("clippy_lint_name") - .help("Apply a filter to only collect specified lints, this also overrides `allow` attributes"), - Arg::new("markdown") - .long("markdown") - .help("Change the reports table to use markdown links"), - Arg::new("recursive") - .long("recursive") - .help("Run clippy on the dependencies of crates specified in crates-toml") - .conflicts_with("threads") - .conflicts_with("fix"), - ]) - .get_matches() -} - -#[derive(Debug, Clone)] +#[derive(Clone, Debug, Parser)] pub(crate) struct LintcheckConfig { - /// max number of jobs to spawn (default 1) + /// Number of threads to use (default: all unless --fix or --recursive) + #[clap( + long = "jobs", + short = 'j', + value_name = "N", + default_value_t = 0, + hide_default_value = true + )] pub max_jobs: usize, - /// we read the sources to check from here + /// Set the path for a crates.toml where lintcheck should read the sources from + #[clap( + long = "crates-toml", + value_name = "CRATES-SOURCES-TOML-PATH", + default_value = "lintcheck/lintcheck_crates.toml", + hide_default_value = true, + env = "LINTCHECK_TOML", + hide_env = true + )] pub sources_toml_path: PathBuf, - /// we save the clippy lint results here - pub lintcheck_results_path: PathBuf, - /// Check only a specified package + /// File to save the clippy lint results here + #[clap(skip = "")] + pub lintcheck_results_path: PathBuf, // Overridden in new() + /// Only process a single crate on the list + #[clap(long, value_name = "CRATE")] pub only: Option, - /// whether to just run --fix and not collect all the warnings + /// Runs cargo clippy --fix and checks if all suggestions apply + #[clap(long, conflicts_with("max_jobs"))] pub fix: bool, - /// A list of lints that this lintcheck run should focus on + /// Apply a filter to only collect specified lints, this also overrides `allow` attributes + #[clap(long = "filter", value_name = "clippy_lint_name", use_value_delimiter = true)] pub lint_filter: Vec, - /// Indicate if the output should support markdown syntax + /// Change the reports table to use markdown links + #[clap(long)] pub markdown: bool, - /// Run clippy on the dependencies of crates + /// Run clippy on the dependencies of crates specified in crates-toml + #[clap(long, conflicts_with("max_jobs"))] pub recursive: bool, } impl LintcheckConfig { pub fn new() -> Self { - let clap_config = get_clap_config(); - - // first, check if we got anything passed via the LINTCHECK_TOML env var, - // if not, ask clap if we got any value for --crates-toml - // if not, use the default "lintcheck/lintcheck_crates.toml" - let sources_toml = env::var("LINTCHECK_TOML").unwrap_or_else(|_| { - clap_config - .get_one::("crates-toml") - .map_or("lintcheck/lintcheck_crates.toml", |s| &**s) - .into() - }); - - let markdown = clap_config.contains_id("markdown"); - let sources_toml_path = PathBuf::from(sources_toml); + let mut config = LintcheckConfig::parse(); // for the path where we save the lint results, get the filename without extension (so for // wasd.toml, use "wasd"...) - let filename: PathBuf = sources_toml_path.file_stem().unwrap().into(); - let lintcheck_results_path = PathBuf::from(format!( + let filename: PathBuf = config.sources_toml_path.file_stem().unwrap().into(); + config.lintcheck_results_path = PathBuf::from(format!( "lintcheck-logs/{}_logs.{}", filename.display(), - if markdown { "md" } else { "txt" } + if config.markdown { "md" } else { "txt" } )); - // look at the --threads arg, if 0 is passed, ask rayon rayon how many threads it would spawn and - // use half of that for the physical core count - // by default use a single thread - let max_jobs = match clap_config.get_one::("threads") { - Some(&0) => { - // automatic choice - // Rayon seems to return thread count so half that for core count - rayon::current_num_threads() / 2 - }, - Some(&threads) => threads, - // no -j passed, use a single thread - None => 1, + // look at the --threads arg, if 0 is passed, use the threads count + if config.max_jobs == 0 { + config.max_jobs = if config.fix || config.recursive { + 1 + } else { + std::thread::available_parallelism().map_or(1, NonZeroUsize::get) + }; }; - let lint_filter: Vec = clap_config - .get_many::("filter") - .map(|iter| { - iter.map(|lint_name| { - let mut filter = lint_name.replace('_', "-"); - if !filter.starts_with("clippy::") { - filter.insert_str(0, "clippy::"); - } - filter - }) - .collect() - }) - .unwrap_or_default(); - - LintcheckConfig { - max_jobs, - sources_toml_path, - lintcheck_results_path, - only: clap_config.get_one::("only").map(String::from), - fix: clap_config.contains_id("fix"), - lint_filter, - markdown, - recursive: clap_config.contains_id("recursive"), + for lint_name in &mut config.lint_filter { + *lint_name = format!( + "clippy::{}", + lint_name + .strip_prefix("clippy::") + .unwrap_or(lint_name) + .replace('_', "-") + ); } + + config } } diff --git a/lintcheck/src/popular-crates.rs b/lintcheck/src/popular-crates.rs new file mode 100644 index 00000000000..fdab984ad86 --- /dev/null +++ b/lintcheck/src/popular-crates.rs @@ -0,0 +1,65 @@ +#![deny(clippy::pedantic)] + +use clap::Parser; +use crates_io_api::{CratesQueryBuilder, Sort, SyncClient}; +use indicatif::ProgressBar; +use std::collections::HashSet; +use std::fs::File; +use std::io::{BufWriter, Write}; +use std::path::PathBuf; +use std::time::Duration; + +#[derive(Parser)] +struct Opts { + /// Output TOML file name + output: PathBuf, + /// Number of crate names to download + #[clap(short, long, default_value_t = 100)] + number: usize, + /// Do not output progress + #[clap(short, long)] + quiet: bool, +} + +fn main() -> anyhow::Result<()> { + let opts = Opts::parse(); + let mut output = BufWriter::new(File::create(opts.output)?); + output.write_all(b"[crates]\n")?; + let client = SyncClient::new( + "clippy/lintcheck (github.com/rust-lang/rust-clippy/)", + Duration::from_secs(1), + )?; + let mut seen_crates = HashSet::new(); + let pb = if opts.quiet { + None + } else { + Some(ProgressBar::new(opts.number as u64)) + }; + let mut query = CratesQueryBuilder::new() + .sort(Sort::RecentDownloads) + .page_size(100) + .build(); + while seen_crates.len() < opts.number { + let retrieved = client.crates(query.clone())?.crates; + if retrieved.is_empty() { + eprintln!("No more than {} crates available from API", seen_crates.len()); + break; + } + for c in retrieved { + if seen_crates.insert(c.name.clone()) { + output.write_all( + format!( + "{} = {{ name = '{}', versions = ['{}'] }}\n", + c.name, c.name, c.max_version + ) + .as_bytes(), + )?; + if let Some(pb) = &pb { + pb.inc(1); + } + } + } + query.set_page(query.page() + 1); + } + Ok(()) +} diff --git a/rust-toolchain b/rust-toolchain index cfe845ec78f..d788c6359d7 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-02-25" +channel = "nightly-2023-03-10" components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"] diff --git a/src/driver.rs b/src/driver.rs index dd183362f27..f08393c303e 100644 --- a/src/driver.rs +++ b/src/driver.rs @@ -176,7 +176,7 @@ Common options: --rustc Pass all args to rustc -V, --version Print version info and exit -Other options are the same as `cargo check`. +For the other options see `cargo check --help`. To allow or deny a lint from the command line you can use `cargo clippy --` with: diff --git a/src/main.rs b/src/main.rs index 82147eba33f..c5e9b96cf3f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,7 +18,7 @@ Common options: -V, --version Print version info and exit --explain LINT Print the documentation for a given lint -Other options are the same as `cargo check`. +For the other options see `cargo check --help`. To allow or deny a lint from the command line you can use `cargo clippy --` with: diff --git a/tests/dogfood.rs b/tests/dogfood.rs index 6d0022f7a5c..9643c2c9707 100644 --- a/tests/dogfood.rs +++ b/tests/dogfood.rs @@ -7,6 +7,7 @@ #![cfg_attr(feature = "deny-warnings", deny(warnings))] #![warn(rust_2018_idioms, unused_lifetimes)] +use itertools::Itertools; use std::path::PathBuf; use std::process::Command; use test_utils::IS_RUSTC_TEST_SUITE; @@ -19,8 +20,10 @@ fn dogfood_clippy() { return; } + let mut failed_packages = Vec::new(); + // "" is the root package - for package in &[ + for package in [ "", "clippy_dev", "clippy_lints", @@ -28,8 +31,16 @@ fn dogfood_clippy() { "lintcheck", "rustc_tools_util", ] { - run_clippy_for_package(package, &["-D", "clippy::all", "-D", "clippy::pedantic"]); + if !run_clippy_for_package(package, &["-D", "clippy::all", "-D", "clippy::pedantic"]) { + failed_packages.push(if package.is_empty() { "root" } else { package }); + } } + + assert!( + !failed_packages.is_empty(), + "Dogfood failed for packages `{}`", + failed_packages.iter().format(", "), + ) } #[test] @@ -71,7 +82,7 @@ fn run_metadata_collection_lint() { run_clippy_for_package("clippy_lints", &["-A", "unfulfilled_lint_expectations"]); } -fn run_clippy_for_package(project: &str, args: &[&str]) { +fn run_clippy_for_package(project: &str, args: &[&str]) -> bool { let root_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); let mut command = Command::new(&*test_utils::CARGO_CLIPPY_PATH); @@ -107,5 +118,5 @@ fn run_clippy_for_package(project: &str, args: &[&str]) { println!("stdout: {}", String::from_utf8_lossy(&output.stdout)); println!("stderr: {}", String::from_utf8_lossy(&output.stderr)); - assert!(output.status.success()); + output.status.success() } diff --git a/tests/ui/arithmetic_side_effects.rs b/tests/ui/arithmetic_side_effects.rs index 2611e3a785f..ee7d2ba444b 100644 --- a/tests/ui/arithmetic_side_effects.rs +++ b/tests/ui/arithmetic_side_effects.rs @@ -45,24 +45,32 @@ impl_arith!( Div, Custom, Custom, div; Mul, Custom, Custom, mul; Rem, Custom, Custom, rem; + Shl, Custom, Custom, shl; + Shr, Custom, Custom, shr; Sub, Custom, Custom, sub; Add, Custom, &Custom, add; Div, Custom, &Custom, div; Mul, Custom, &Custom, mul; Rem, Custom, &Custom, rem; + Shl, Custom, &Custom, shl; + Shr, Custom, &Custom, shr; Sub, Custom, &Custom, sub; Add, &Custom, Custom, add; Div, &Custom, Custom, div; Mul, &Custom, Custom, mul; Rem, &Custom, Custom, rem; + Shl, &Custom, Custom, shl; + Shr, &Custom, Custom, shr; Sub, &Custom, Custom, sub; Add, &Custom, &Custom, add; Div, &Custom, &Custom, div; Mul, &Custom, &Custom, mul; Rem, &Custom, &Custom, rem; + Shl, &Custom, &Custom, shl; + Shr, &Custom, &Custom, shr; Sub, &Custom, &Custom, sub; ); @@ -71,24 +79,32 @@ impl_assign_arith!( DivAssign, Custom, Custom, div_assign; MulAssign, Custom, Custom, mul_assign; RemAssign, Custom, Custom, rem_assign; + ShlAssign, Custom, Custom, shl_assign; + ShrAssign, Custom, Custom, shr_assign; SubAssign, Custom, Custom, sub_assign; AddAssign, Custom, &Custom, add_assign; DivAssign, Custom, &Custom, div_assign; MulAssign, Custom, &Custom, mul_assign; RemAssign, Custom, &Custom, rem_assign; + ShlAssign, Custom, &Custom, shl_assign; + ShrAssign, Custom, &Custom, shr_assign; SubAssign, Custom, &Custom, sub_assign; AddAssign, &Custom, Custom, add_assign; DivAssign, &Custom, Custom, div_assign; MulAssign, &Custom, Custom, mul_assign; RemAssign, &Custom, Custom, rem_assign; + ShlAssign, &Custom, Custom, shl_assign; + ShrAssign, &Custom, Custom, shr_assign; SubAssign, &Custom, Custom, sub_assign; AddAssign, &Custom, &Custom, add_assign; DivAssign, &Custom, &Custom, div_assign; MulAssign, &Custom, &Custom, mul_assign; RemAssign, &Custom, &Custom, rem_assign; + ShlAssign, &Custom, &Custom, shl_assign; + ShrAssign, &Custom, &Custom, shr_assign; SubAssign, &Custom, &Custom, sub_assign; ); @@ -297,6 +313,10 @@ pub fn unknown_ops_or_runtime_ops_that_can_overflow() { _custom %= &Custom; _custom *= Custom; _custom *= &Custom; + _custom >>= Custom; + _custom >>= &Custom; + _custom <<= Custom; + _custom <<= &Custom; _custom += -Custom; _custom += &-Custom; _custom -= -Custom; @@ -307,6 +327,10 @@ pub fn unknown_ops_or_runtime_ops_that_can_overflow() { _custom %= &-Custom; _custom *= -Custom; _custom *= &-Custom; + _custom >>= -Custom; + _custom >>= &-Custom; + _custom <<= -Custom; + _custom <<= &-Custom; // Binary _n = _n + 1; @@ -347,6 +371,10 @@ pub fn unknown_ops_or_runtime_ops_that_can_overflow() { _custom = Custom + &Custom; _custom = &Custom + Custom; _custom = &Custom + &Custom; + _custom = _custom >> _custom; + _custom = _custom >> &_custom; + _custom = Custom << _custom; + _custom = &Custom << _custom; // Unary _n = -_n; diff --git a/tests/ui/arithmetic_side_effects.stderr b/tests/ui/arithmetic_side_effects.stderr index 17a2448fbfc..3895f08964c 100644 --- a/tests/ui/arithmetic_side_effects.stderr +++ b/tests/ui/arithmetic_side_effects.stderr @@ -1,5 +1,5 @@ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:270:5 + --> $DIR/arithmetic_side_effects.rs:286:5 | LL | _n += 1; | ^^^^^^^ @@ -7,592 +7,640 @@ LL | _n += 1; = note: `-D clippy::arithmetic-side-effects` implied by `-D warnings` error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:271:5 + --> $DIR/arithmetic_side_effects.rs:287:5 | LL | _n += &1; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:272:5 + --> $DIR/arithmetic_side_effects.rs:288:5 | LL | _n -= 1; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:273:5 + --> $DIR/arithmetic_side_effects.rs:289:5 | LL | _n -= &1; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:274:5 + --> $DIR/arithmetic_side_effects.rs:290:5 | LL | _n /= 0; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:275:5 + --> $DIR/arithmetic_side_effects.rs:291:5 | LL | _n /= &0; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:276:5 + --> $DIR/arithmetic_side_effects.rs:292:5 | LL | _n %= 0; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:277:5 + --> $DIR/arithmetic_side_effects.rs:293:5 | LL | _n %= &0; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:278:5 + --> $DIR/arithmetic_side_effects.rs:294:5 | LL | _n *= 2; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:279:5 + --> $DIR/arithmetic_side_effects.rs:295:5 | LL | _n *= &2; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:280:5 + --> $DIR/arithmetic_side_effects.rs:296:5 | LL | _n += -1; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:281:5 + --> $DIR/arithmetic_side_effects.rs:297:5 | LL | _n += &-1; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:282:5 + --> $DIR/arithmetic_side_effects.rs:298:5 | LL | _n -= -1; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:283:5 + --> $DIR/arithmetic_side_effects.rs:299:5 | LL | _n -= &-1; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:284:5 + --> $DIR/arithmetic_side_effects.rs:300:5 | LL | _n /= -0; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:285:5 + --> $DIR/arithmetic_side_effects.rs:301:5 | LL | _n /= &-0; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:286:5 + --> $DIR/arithmetic_side_effects.rs:302:5 | LL | _n %= -0; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:287:5 + --> $DIR/arithmetic_side_effects.rs:303:5 | LL | _n %= &-0; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:288:5 + --> $DIR/arithmetic_side_effects.rs:304:5 | LL | _n *= -2; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:289:5 + --> $DIR/arithmetic_side_effects.rs:305:5 | LL | _n *= &-2; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:290:5 + --> $DIR/arithmetic_side_effects.rs:306:5 | LL | _custom += Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:291:5 + --> $DIR/arithmetic_side_effects.rs:307:5 | LL | _custom += &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:292:5 + --> $DIR/arithmetic_side_effects.rs:308:5 | LL | _custom -= Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:293:5 + --> $DIR/arithmetic_side_effects.rs:309:5 | LL | _custom -= &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:294:5 + --> $DIR/arithmetic_side_effects.rs:310:5 | LL | _custom /= Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:295:5 + --> $DIR/arithmetic_side_effects.rs:311:5 | LL | _custom /= &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:296:5 + --> $DIR/arithmetic_side_effects.rs:312:5 | LL | _custom %= Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:297:5 + --> $DIR/arithmetic_side_effects.rs:313:5 | LL | _custom %= &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:298:5 + --> $DIR/arithmetic_side_effects.rs:314:5 | LL | _custom *= Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:299:5 + --> $DIR/arithmetic_side_effects.rs:315:5 | LL | _custom *= &Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:300:5 + --> $DIR/arithmetic_side_effects.rs:316:5 + | +LL | _custom >>= Custom; + | ^^^^^^^^^^^^^^^^^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:317:5 + | +LL | _custom >>= &Custom; + | ^^^^^^^^^^^^^^^^^^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:318:5 + | +LL | _custom <<= Custom; + | ^^^^^^^^^^^^^^^^^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:319:5 + | +LL | _custom <<= &Custom; + | ^^^^^^^^^^^^^^^^^^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:320:5 | LL | _custom += -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:301:5 + --> $DIR/arithmetic_side_effects.rs:321:5 | LL | _custom += &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:302:5 + --> $DIR/arithmetic_side_effects.rs:322:5 | LL | _custom -= -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:303:5 + --> $DIR/arithmetic_side_effects.rs:323:5 | LL | _custom -= &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:304:5 + --> $DIR/arithmetic_side_effects.rs:324:5 | LL | _custom /= -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:305:5 + --> $DIR/arithmetic_side_effects.rs:325:5 | LL | _custom /= &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:306:5 + --> $DIR/arithmetic_side_effects.rs:326:5 | LL | _custom %= -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:307:5 + --> $DIR/arithmetic_side_effects.rs:327:5 | LL | _custom %= &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:308:5 + --> $DIR/arithmetic_side_effects.rs:328:5 | LL | _custom *= -Custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:309:5 + --> $DIR/arithmetic_side_effects.rs:329:5 | LL | _custom *= &-Custom; | ^^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:312:10 + --> $DIR/arithmetic_side_effects.rs:330:5 + | +LL | _custom >>= -Custom; + | ^^^^^^^^^^^^^^^^^^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:331:5 + | +LL | _custom >>= &-Custom; + | ^^^^^^^^^^^^^^^^^^^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:332:5 + | +LL | _custom <<= -Custom; + | ^^^^^^^^^^^^^^^^^^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:333:5 + | +LL | _custom <<= &-Custom; + | ^^^^^^^^^^^^^^^^^^^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:336:10 | LL | _n = _n + 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:313:10 + --> $DIR/arithmetic_side_effects.rs:337:10 | LL | _n = _n + &1; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:314:10 + --> $DIR/arithmetic_side_effects.rs:338:10 | LL | _n = 1 + _n; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:315:10 + --> $DIR/arithmetic_side_effects.rs:339:10 | LL | _n = &1 + _n; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:316:10 + --> $DIR/arithmetic_side_effects.rs:340:10 | LL | _n = _n - 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:317:10 + --> $DIR/arithmetic_side_effects.rs:341:10 | LL | _n = _n - &1; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:318:10 + --> $DIR/arithmetic_side_effects.rs:342:10 | LL | _n = 1 - _n; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:319:10 + --> $DIR/arithmetic_side_effects.rs:343:10 | LL | _n = &1 - _n; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:320:10 + --> $DIR/arithmetic_side_effects.rs:344:10 | LL | _n = _n / 0; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:321:10 + --> $DIR/arithmetic_side_effects.rs:345:10 | LL | _n = _n / &0; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:322:10 + --> $DIR/arithmetic_side_effects.rs:346:10 | LL | _n = _n % 0; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:323:10 + --> $DIR/arithmetic_side_effects.rs:347:10 | LL | _n = _n % &0; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:324:10 + --> $DIR/arithmetic_side_effects.rs:348:10 | LL | _n = _n * 2; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:325:10 + --> $DIR/arithmetic_side_effects.rs:349:10 | LL | _n = _n * &2; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:326:10 + --> $DIR/arithmetic_side_effects.rs:350:10 | LL | _n = 2 * _n; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:327:10 + --> $DIR/arithmetic_side_effects.rs:351:10 | LL | _n = &2 * _n; | ^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:328:10 + --> $DIR/arithmetic_side_effects.rs:352:10 | LL | _n = 23 + &85; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:329:10 + --> $DIR/arithmetic_side_effects.rs:353:10 | LL | _n = &23 + 85; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:330:10 + --> $DIR/arithmetic_side_effects.rs:354:10 | LL | _n = &23 + &85; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:331:15 + --> $DIR/arithmetic_side_effects.rs:355:15 | LL | _custom = _custom + _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:332:15 + --> $DIR/arithmetic_side_effects.rs:356:15 | LL | _custom = _custom + &_custom; | ^^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:333:15 + --> $DIR/arithmetic_side_effects.rs:357:15 | LL | _custom = Custom + _custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:334:15 + --> $DIR/arithmetic_side_effects.rs:358:15 | LL | _custom = &Custom + _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:335:15 + --> $DIR/arithmetic_side_effects.rs:359:15 | LL | _custom = _custom - Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:336:15 + --> $DIR/arithmetic_side_effects.rs:360:15 | LL | _custom = _custom - &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:337:15 + --> $DIR/arithmetic_side_effects.rs:361:15 | LL | _custom = Custom - _custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:338:15 + --> $DIR/arithmetic_side_effects.rs:362:15 | LL | _custom = &Custom - _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:339:15 + --> $DIR/arithmetic_side_effects.rs:363:15 | LL | _custom = _custom / Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:340:15 + --> $DIR/arithmetic_side_effects.rs:364:15 | LL | _custom = _custom / &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:341:15 + --> $DIR/arithmetic_side_effects.rs:365:15 | LL | _custom = _custom % Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:342:15 + --> $DIR/arithmetic_side_effects.rs:366:15 | LL | _custom = _custom % &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:343:15 + --> $DIR/arithmetic_side_effects.rs:367:15 | LL | _custom = _custom * Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:344:15 + --> $DIR/arithmetic_side_effects.rs:368:15 | LL | _custom = _custom * &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:345:15 + --> $DIR/arithmetic_side_effects.rs:369:15 | LL | _custom = Custom * _custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:346:15 + --> $DIR/arithmetic_side_effects.rs:370:15 | LL | _custom = &Custom * _custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:347:15 + --> $DIR/arithmetic_side_effects.rs:371:15 | LL | _custom = Custom + &Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:348:15 + --> $DIR/arithmetic_side_effects.rs:372:15 | LL | _custom = &Custom + Custom; | ^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:349:15 + --> $DIR/arithmetic_side_effects.rs:373:15 | LL | _custom = &Custom + &Custom; | ^^^^^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:352:10 + --> $DIR/arithmetic_side_effects.rs:374:15 + | +LL | _custom = _custom >> _custom; + | ^^^^^^^^^^^^^^^^^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:375:15 + | +LL | _custom = _custom >> &_custom; + | ^^^^^^^^^^^^^^^^^^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:376:15 + | +LL | _custom = Custom << _custom; + | ^^^^^^^^^^^^^^^^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:377:15 + | +LL | _custom = &Custom << _custom; + | ^^^^^^^^^^^^^^^^^^ + +error: arithmetic operation that can potentially result in unexpected side-effects + --> $DIR/arithmetic_side_effects.rs:380:10 | LL | _n = -_n; | ^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:353:10 + --> $DIR/arithmetic_side_effects.rs:381:10 | LL | _n = -&_n; | ^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:354:15 + --> $DIR/arithmetic_side_effects.rs:382:15 | LL | _custom = -_custom; | ^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:355:15 + --> $DIR/arithmetic_side_effects.rs:383:15 | LL | _custom = -&_custom; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:364:5 + --> $DIR/arithmetic_side_effects.rs:392:5 | LL | 1 + i; | ^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:365:5 + --> $DIR/arithmetic_side_effects.rs:393:5 | LL | i * 2; | ^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:367:5 + --> $DIR/arithmetic_side_effects.rs:395:5 | LL | i - 2 + 2 - i; | ^^^^^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:368:5 + --> $DIR/arithmetic_side_effects.rs:396:5 | LL | -i; | ^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:369:5 - | -LL | i >> 1; - | ^^^^^^ - -error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:370:5 - | -LL | i << 1; - | ^^^^^^ - -error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:379:5 + --> $DIR/arithmetic_side_effects.rs:407:5 | LL | i += 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:380:5 + --> $DIR/arithmetic_side_effects.rs:408:5 | LL | i -= 1; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:381:5 + --> $DIR/arithmetic_side_effects.rs:409:5 | LL | i *= 2; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:383:5 + --> $DIR/arithmetic_side_effects.rs:411:5 | LL | i /= 0; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:385:5 + --> $DIR/arithmetic_side_effects.rs:413:5 | LL | i /= var1; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:386:5 + --> $DIR/arithmetic_side_effects.rs:414:5 | LL | i /= var2; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:388:5 + --> $DIR/arithmetic_side_effects.rs:416:5 | LL | i %= 0; | ^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:390:5 + --> $DIR/arithmetic_side_effects.rs:418:5 | LL | i %= var1; | ^^^^^^^^^ error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:391:5 + --> $DIR/arithmetic_side_effects.rs:419:5 | LL | i %= var2; | ^^^^^^^^^ -error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:392:5 - | -LL | i <<= 3; - | ^^^^^^^ - -error: arithmetic operation that can potentially result in unexpected side-effects - --> $DIR/arithmetic_side_effects.rs:393:5 - | -LL | i >>= 2; - | ^^^^^^^ - -error: aborting due to 99 previous errors +error: aborting due to 107 previous errors diff --git a/tests/ui/async_yields_async.fixed b/tests/ui/async_yields_async.fixed index 3cf380d2b95..579a63ea477 100644 --- a/tests/ui/async_yields_async.fixed +++ b/tests/ui/async_yields_async.fixed @@ -2,6 +2,7 @@ #![feature(lint_reasons)] #![feature(async_closure)] #![warn(clippy::async_yields_async)] +#![allow(clippy::redundant_async_block)] use core::future::Future; use core::pin::Pin; diff --git a/tests/ui/async_yields_async.rs b/tests/ui/async_yields_async.rs index dd4131b60ab..5aec2fb50f6 100644 --- a/tests/ui/async_yields_async.rs +++ b/tests/ui/async_yields_async.rs @@ -2,6 +2,7 @@ #![feature(lint_reasons)] #![feature(async_closure)] #![warn(clippy::async_yields_async)] +#![allow(clippy::redundant_async_block)] use core::future::Future; use core::pin::Pin; diff --git a/tests/ui/async_yields_async.stderr b/tests/ui/async_yields_async.stderr index 22ce1c6f647..7f72534832b 100644 --- a/tests/ui/async_yields_async.stderr +++ b/tests/ui/async_yields_async.stderr @@ -1,5 +1,5 @@ error: an async construct yields a type which is itself awaitable - --> $DIR/async_yields_async.rs:39:9 + --> $DIR/async_yields_async.rs:40:9 | LL | let _h = async { | _____________________- @@ -19,7 +19,7 @@ LL + }.await | error: an async construct yields a type which is itself awaitable - --> $DIR/async_yields_async.rs:44:9 + --> $DIR/async_yields_async.rs:45:9 | LL | let _i = async { | ____________________- @@ -32,7 +32,7 @@ LL | | }; | |_____- outer async construct error: an async construct yields a type which is itself awaitable - --> $DIR/async_yields_async.rs:50:9 + --> $DIR/async_yields_async.rs:51:9 | LL | let _j = async || { | ________________________- @@ -51,7 +51,7 @@ LL + }.await | error: an async construct yields a type which is itself awaitable - --> $DIR/async_yields_async.rs:55:9 + --> $DIR/async_yields_async.rs:56:9 | LL | let _k = async || { | _______________________- @@ -64,7 +64,7 @@ LL | | }; | |_____- outer async construct error: an async construct yields a type which is itself awaitable - --> $DIR/async_yields_async.rs:57:23 + --> $DIR/async_yields_async.rs:58:23 | LL | let _l = async || CustomFutureType; | ^^^^^^^^^^^^^^^^ @@ -74,7 +74,7 @@ LL | let _l = async || CustomFutureType; | help: consider awaiting this value: `CustomFutureType.await` error: an async construct yields a type which is itself awaitable - --> $DIR/async_yields_async.rs:63:9 + --> $DIR/async_yields_async.rs:64:9 | LL | let _m = async || { | _______________________- diff --git a/tests/ui/collection_is_never_read.rs b/tests/ui/collection_is_never_read.rs new file mode 100644 index 00000000000..068a49486cf --- /dev/null +++ b/tests/ui/collection_is_never_read.rs @@ -0,0 +1,165 @@ +#![allow(unused)] +#![warn(clippy::collection_is_never_read)] + +use std::collections::{HashMap, HashSet}; + +fn main() {} + +fn not_a_collection() { + // TODO: Expand `collection_is_never_read` beyond collections? + let mut x = 10; // Ok + x += 1; +} + +fn no_access_at_all() { + // Other lints should catch this. + let x = vec![1, 2, 3]; // Ok +} + +fn write_without_read() { + // The main use case for `collection_is_never_read`. + let mut x = HashMap::new(); // WARNING + x.insert(1, 2); +} + +fn read_without_write() { + let mut x = vec![1, 2, 3]; // Ok + let _ = x.len(); +} + +fn write_and_read() { + let mut x = vec![1, 2, 3]; // Ok + x.push(4); + let _ = x.len(); +} + +fn write_after_read() { + // TODO: Warn here, but this requires more extensive data flow analysis. + let mut x = vec![1, 2, 3]; // Ok + let _ = x.len(); + x.push(4); // Pointless +} + +fn write_before_reassign() { + // TODO: Warn here, but this requires more extensive data flow analysis. + let mut x = HashMap::new(); // Ok + x.insert(1, 2); // Pointless + x = HashMap::new(); + let _ = x.len(); +} + +fn read_in_closure() { + let mut x = HashMap::new(); // Ok + x.insert(1, 2); + let _ = || { + let _ = x.len(); + }; +} + +fn write_in_closure() { + let mut x = vec![1, 2, 3]; // WARNING + let _ = || { + x.push(4); + }; +} + +fn read_in_format() { + let mut x = HashMap::new(); // Ok + x.insert(1, 2); + format!("{x:?}"); +} + +fn shadowing_1() { + let x = HashMap::::new(); // Ok + let _ = x.len(); + let mut x = HashMap::new(); // WARNING + x.insert(1, 2); +} + +fn shadowing_2() { + let mut x = HashMap::new(); // WARNING + x.insert(1, 2); + let x = HashMap::::new(); // Ok + let _ = x.len(); +} + +#[allow(clippy::let_unit_value)] +fn fake_read() { + let mut x = vec![1, 2, 3]; // Ok + x.reverse(); + // `collection_is_never_read` gets fooled, but other lints should catch this. + let _: () = x.clear(); +} + +fn assignment() { + let mut x = vec![1, 2, 3]; // WARNING + let y = vec![4, 5, 6]; // Ok + x = y; +} + +#[allow(clippy::self_assignment)] +fn self_assignment() { + let mut x = vec![1, 2, 3]; // WARNING + x = x; +} + +fn method_argument_but_not_target() { + struct MyStruct; + impl MyStruct { + fn my_method(&self, _argument: &[usize]) {} + } + let my_struct = MyStruct; + + let mut x = vec![1, 2, 3]; // Ok + x.reverse(); + my_struct.my_method(&x); +} + +fn insert_is_not_a_read() { + let mut x = HashSet::new(); // WARNING + x.insert(5); +} + +fn insert_is_a_read() { + let mut x = HashSet::new(); // Ok + if x.insert(5) { + println!("5 was inserted"); + } +} + +fn not_read_if_return_value_not_used() { + // `is_empty` does not modify the set, so it's a query. But since the return value is not used, the + // lint does not consider it a read here. + let x = vec![1, 2, 3]; // WARNING + x.is_empty(); +} + +fn extension_traits() { + trait VecExt { + fn method_with_side_effect(&self); + fn method_without_side_effect(&self); + } + + impl VecExt for Vec { + fn method_with_side_effect(&self) { + println!("my length: {}", self.len()); + } + fn method_without_side_effect(&self) {} + } + + let x = vec![1, 2, 3]; // Ok + x.method_with_side_effect(); + + let y = vec![1, 2, 3]; // Ok (false negative) + y.method_without_side_effect(); +} + +fn function_argument() { + #[allow(clippy::ptr_arg)] + fn foo(v: &Vec) -> usize { + v.len() + } + + let x = vec![1, 2, 3]; // Ok + foo(&x); +} diff --git a/tests/ui/collection_is_never_read.stderr b/tests/ui/collection_is_never_read.stderr new file mode 100644 index 00000000000..7654b74be3d --- /dev/null +++ b/tests/ui/collection_is_never_read.stderr @@ -0,0 +1,52 @@ +error: collection is never read + --> $DIR/collection_is_never_read.rs:21:5 + | +LL | let mut x = HashMap::new(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::collection-is-never-read` implied by `-D warnings` + +error: collection is never read + --> $DIR/collection_is_never_read.rs:60:5 + | +LL | let mut x = vec![1, 2, 3]; // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:75:5 + | +LL | let mut x = HashMap::new(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:80:5 + | +LL | let mut x = HashMap::new(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:95:5 + | +LL | let mut x = vec![1, 2, 3]; // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:102:5 + | +LL | let mut x = vec![1, 2, 3]; // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:119:5 + | +LL | let mut x = HashSet::new(); // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: collection is never read + --> $DIR/collection_is_never_read.rs:133:5 + | +LL | let x = vec![1, 2, 3]; // WARNING + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 8 previous errors + diff --git a/tests/ui/crashes/ice-10148.rs b/tests/ui/crashes/ice-10148.rs new file mode 100644 index 00000000000..af33b10c693 --- /dev/null +++ b/tests/ui/crashes/ice-10148.rs @@ -0,0 +1,9 @@ +// aux-build:../../auxiliary/proc_macro_with_span.rs + +extern crate proc_macro_with_span; + +use proc_macro_with_span::with_span; + +fn main() { + println!(with_span!(""something "")); +} diff --git a/tests/ui/crashes/ice-10148.stderr b/tests/ui/crashes/ice-10148.stderr new file mode 100644 index 00000000000..f23e4433f95 --- /dev/null +++ b/tests/ui/crashes/ice-10148.stderr @@ -0,0 +1,12 @@ +error: empty string literal in `println!` + --> $DIR/ice-10148.rs:8:5 + | +LL | println!(with_span!(""something "")); + | ^^^^^^^^^^^^^^^^^^^^-----------^^^^^ + | | + | help: remove the empty string + | + = note: `-D clippy::println-empty-string` implied by `-D warnings` + +error: aborting due to previous error + diff --git a/tests/ui/crashes/ice-6179.rs b/tests/ui/crashes/ice-6179.rs index 4fe92d356c4..ce1895851e2 100644 --- a/tests/ui/crashes/ice-6179.rs +++ b/tests/ui/crashes/ice-6179.rs @@ -2,7 +2,7 @@ //! The ICE is mainly caused by using `hir_ty_to_ty`. See the discussion in the PR for details. #![warn(clippy::use_self)] -#![allow(dead_code)] +#![allow(dead_code, clippy::let_with_type_underscore)] struct Foo; diff --git a/tests/ui/crashes/ice-rust-107877.rs b/tests/ui/crashes/ice-rust-107877.rs new file mode 100644 index 00000000000..7f5bae60d55 --- /dev/null +++ b/tests/ui/crashes/ice-rust-107877.rs @@ -0,0 +1,17 @@ +#![allow(dead_code)] + +struct Foo; + +impl<'a> std::convert::TryFrom<&'a String> for Foo { + type Error = std::convert::Infallible; + + fn try_from(_: &'a String) -> Result { + Ok(Foo) + } +} + +fn find(_: impl std::convert::TryInto) {} + +fn main() { + find(&String::new()); +} diff --git a/tests/ui/default_numeric_fallback_f64.fixed b/tests/ui/default_numeric_fallback_f64.fixed index a370ccc7696..a9e5fd159af 100644 --- a/tests/ui/default_numeric_fallback_f64.fixed +++ b/tests/ui/default_numeric_fallback_f64.fixed @@ -9,7 +9,8 @@ clippy::unnecessary_operation, clippy::branches_sharing_code, clippy::match_single_binding, - clippy::let_unit_value + clippy::let_unit_value, + clippy::let_with_type_underscore )] #[macro_use] diff --git a/tests/ui/default_numeric_fallback_f64.rs b/tests/ui/default_numeric_fallback_f64.rs index 2476fe95141..085f8f452b2 100644 --- a/tests/ui/default_numeric_fallback_f64.rs +++ b/tests/ui/default_numeric_fallback_f64.rs @@ -9,7 +9,8 @@ clippy::unnecessary_operation, clippy::branches_sharing_code, clippy::match_single_binding, - clippy::let_unit_value + clippy::let_unit_value, + clippy::let_with_type_underscore )] #[macro_use] diff --git a/tests/ui/default_numeric_fallback_f64.stderr b/tests/ui/default_numeric_fallback_f64.stderr index 5df2f642388..44c6f1a9bea 100644 --- a/tests/ui/default_numeric_fallback_f64.stderr +++ b/tests/ui/default_numeric_fallback_f64.stderr @@ -1,5 +1,5 @@ error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:21:17 + --> $DIR/default_numeric_fallback_f64.rs:22:17 | LL | let x = 0.12; | ^^^^ help: consider adding suffix: `0.12_f64` @@ -7,139 +7,139 @@ LL | let x = 0.12; = note: `-D clippy::default-numeric-fallback` implied by `-D warnings` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:22:18 + --> $DIR/default_numeric_fallback_f64.rs:23:18 | LL | let x = [1., 2., 3.]; | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:22:22 + --> $DIR/default_numeric_fallback_f64.rs:23:22 | LL | let x = [1., 2., 3.]; | ^^ help: consider adding suffix: `2.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:22:26 + --> $DIR/default_numeric_fallback_f64.rs:23:26 | LL | let x = [1., 2., 3.]; | ^^ help: consider adding suffix: `3.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:23:28 + --> $DIR/default_numeric_fallback_f64.rs:24:28 | LL | let x = if true { (1., 2.) } else { (3., 4.) }; | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:23:32 + --> $DIR/default_numeric_fallback_f64.rs:24:32 | LL | let x = if true { (1., 2.) } else { (3., 4.) }; | ^^ help: consider adding suffix: `2.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:23:46 + --> $DIR/default_numeric_fallback_f64.rs:24:46 | LL | let x = if true { (1., 2.) } else { (3., 4.) }; | ^^ help: consider adding suffix: `3.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:23:50 + --> $DIR/default_numeric_fallback_f64.rs:24:50 | LL | let x = if true { (1., 2.) } else { (3., 4.) }; | ^^ help: consider adding suffix: `4.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:24:23 + --> $DIR/default_numeric_fallback_f64.rs:25:23 | LL | let x = match 1. { | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:25:18 + --> $DIR/default_numeric_fallback_f64.rs:26:18 | LL | _ => 1., | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:44:21 + --> $DIR/default_numeric_fallback_f64.rs:45:21 | LL | let y = 1.; | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:52:21 + --> $DIR/default_numeric_fallback_f64.rs:53:21 | LL | let y = 1.; | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:58:21 + --> $DIR/default_numeric_fallback_f64.rs:59:21 | LL | let y = 1.; | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:66:21 + --> $DIR/default_numeric_fallback_f64.rs:67:21 | LL | let y = 1.; | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:78:9 + --> $DIR/default_numeric_fallback_f64.rs:79:9 | LL | 1. | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:84:27 + --> $DIR/default_numeric_fallback_f64.rs:85:27 | LL | let f = || -> _ { 1. }; | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:88:29 + --> $DIR/default_numeric_fallback_f64.rs:89:29 | LL | let f = || -> f64 { 1. }; | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:102:21 + --> $DIR/default_numeric_fallback_f64.rs:103:21 | LL | generic_arg(1.); | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:105:32 + --> $DIR/default_numeric_fallback_f64.rs:106:32 | LL | let x: _ = generic_arg(1.); | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:123:28 + --> $DIR/default_numeric_fallback_f64.rs:124:28 | LL | GenericStruct { x: 1. }; | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:126:36 + --> $DIR/default_numeric_fallback_f64.rs:127:36 | LL | let _ = GenericStruct { x: 1. }; | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:144:24 + --> $DIR/default_numeric_fallback_f64.rs:145:24 | LL | GenericEnum::X(1.); | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:164:23 + --> $DIR/default_numeric_fallback_f64.rs:165:23 | LL | s.generic_arg(1.); | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:171:21 + --> $DIR/default_numeric_fallback_f64.rs:172:21 | LL | let x = 22.; | ^^^ help: consider adding suffix: `22.0_f64` diff --git a/tests/ui/default_numeric_fallback_i32.fixed b/tests/ui/default_numeric_fallback_i32.fixed index 3f4994f0453..63ac4d5aeb6 100644 --- a/tests/ui/default_numeric_fallback_i32.fixed +++ b/tests/ui/default_numeric_fallback_i32.fixed @@ -9,7 +9,8 @@ clippy::no_effect, clippy::unnecessary_operation, clippy::branches_sharing_code, - clippy::let_unit_value + clippy::let_unit_value, + clippy::let_with_type_underscore )] #[macro_use] diff --git a/tests/ui/default_numeric_fallback_i32.rs b/tests/ui/default_numeric_fallback_i32.rs index 2df0e09787f..28e6eceb80e 100644 --- a/tests/ui/default_numeric_fallback_i32.rs +++ b/tests/ui/default_numeric_fallback_i32.rs @@ -9,7 +9,8 @@ clippy::no_effect, clippy::unnecessary_operation, clippy::branches_sharing_code, - clippy::let_unit_value + clippy::let_unit_value, + clippy::let_with_type_underscore )] #[macro_use] diff --git a/tests/ui/default_numeric_fallback_i32.stderr b/tests/ui/default_numeric_fallback_i32.stderr index 6f219c3fc2b..dd91574d5b3 100644 --- a/tests/ui/default_numeric_fallback_i32.stderr +++ b/tests/ui/default_numeric_fallback_i32.stderr @@ -1,5 +1,5 @@ error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:21:17 + --> $DIR/default_numeric_fallback_i32.rs:22:17 | LL | let x = 22; | ^^ help: consider adding suffix: `22_i32` @@ -7,151 +7,151 @@ LL | let x = 22; = note: `-D clippy::default-numeric-fallback` implied by `-D warnings` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:22:18 + --> $DIR/default_numeric_fallback_i32.rs:23:18 | LL | let x = [1, 2, 3]; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:22:21 + --> $DIR/default_numeric_fallback_i32.rs:23:21 | LL | let x = [1, 2, 3]; | ^ help: consider adding suffix: `2_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:22:24 + --> $DIR/default_numeric_fallback_i32.rs:23:24 | LL | let x = [1, 2, 3]; | ^ help: consider adding suffix: `3_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:23:28 + --> $DIR/default_numeric_fallback_i32.rs:24:28 | LL | let x = if true { (1, 2) } else { (3, 4) }; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:23:31 + --> $DIR/default_numeric_fallback_i32.rs:24:31 | LL | let x = if true { (1, 2) } else { (3, 4) }; | ^ help: consider adding suffix: `2_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:23:44 + --> $DIR/default_numeric_fallback_i32.rs:24:44 | LL | let x = if true { (1, 2) } else { (3, 4) }; | ^ help: consider adding suffix: `3_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:23:47 + --> $DIR/default_numeric_fallback_i32.rs:24:47 | LL | let x = if true { (1, 2) } else { (3, 4) }; | ^ help: consider adding suffix: `4_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:24:23 + --> $DIR/default_numeric_fallback_i32.rs:25:23 | LL | let x = match 1 { | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:25:13 + --> $DIR/default_numeric_fallback_i32.rs:26:13 | LL | 1 => 1, | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:25:18 + --> $DIR/default_numeric_fallback_i32.rs:26:18 | LL | 1 => 1, | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:26:18 + --> $DIR/default_numeric_fallback_i32.rs:27:18 | LL | _ => 2, | ^ help: consider adding suffix: `2_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:45:21 + --> $DIR/default_numeric_fallback_i32.rs:46:21 | LL | let y = 1; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:53:21 + --> $DIR/default_numeric_fallback_i32.rs:54:21 | LL | let y = 1; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:59:21 + --> $DIR/default_numeric_fallback_i32.rs:60:21 | LL | let y = 1; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:67:21 + --> $DIR/default_numeric_fallback_i32.rs:68:21 | LL | let y = 1; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:79:9 + --> $DIR/default_numeric_fallback_i32.rs:80:9 | LL | 1 | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:85:27 + --> $DIR/default_numeric_fallback_i32.rs:86:27 | LL | let f = || -> _ { 1 }; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:89:29 + --> $DIR/default_numeric_fallback_i32.rs:90:29 | LL | let f = || -> i32 { 1 }; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:103:21 + --> $DIR/default_numeric_fallback_i32.rs:104:21 | LL | generic_arg(1); | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:106:32 + --> $DIR/default_numeric_fallback_i32.rs:107:32 | LL | let x: _ = generic_arg(1); | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:124:28 + --> $DIR/default_numeric_fallback_i32.rs:125:28 | LL | GenericStruct { x: 1 }; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:127:36 + --> $DIR/default_numeric_fallback_i32.rs:128:36 | LL | let _ = GenericStruct { x: 1 }; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:145:24 + --> $DIR/default_numeric_fallback_i32.rs:146:24 | LL | GenericEnum::X(1); | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:165:23 + --> $DIR/default_numeric_fallback_i32.rs:166:23 | LL | s.generic_arg(1); | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:172:21 + --> $DIR/default_numeric_fallback_i32.rs:173:21 | LL | let x = 22; | ^^ help: consider adding suffix: `22_i32` diff --git a/tests/ui/derivable_impls.fixed b/tests/ui/derivable_impls.fixed index ee8456f5deb..89ec33a0d8f 100644 --- a/tests/ui/derivable_impls.fixed +++ b/tests/ui/derivable_impls.fixed @@ -231,4 +231,41 @@ impl Default for NonExhaustiveEnum { } } +// https://github.com/rust-lang/rust-clippy/issues/10396 + +#[derive(Default)] +struct DefaultType; + +struct GenericType { + t: T, +} + +impl Default for GenericType { + fn default() -> Self { + Self { t: Default::default() } + } +} + +struct InnerGenericType { + t: T, +} + +impl Default for InnerGenericType { + fn default() -> Self { + Self { t: Default::default() } + } +} + +struct OtherGenericType { + inner: InnerGenericType, +} + +impl Default for OtherGenericType { + fn default() -> Self { + Self { + inner: Default::default(), + } + } +} + fn main() {} diff --git a/tests/ui/derivable_impls.rs b/tests/ui/derivable_impls.rs index 14af419bcad..def6e41162f 100644 --- a/tests/ui/derivable_impls.rs +++ b/tests/ui/derivable_impls.rs @@ -267,4 +267,41 @@ impl Default for NonExhaustiveEnum { } } +// https://github.com/rust-lang/rust-clippy/issues/10396 + +#[derive(Default)] +struct DefaultType; + +struct GenericType { + t: T, +} + +impl Default for GenericType { + fn default() -> Self { + Self { t: Default::default() } + } +} + +struct InnerGenericType { + t: T, +} + +impl Default for InnerGenericType { + fn default() -> Self { + Self { t: Default::default() } + } +} + +struct OtherGenericType { + inner: InnerGenericType, +} + +impl Default for OtherGenericType { + fn default() -> Self { + Self { + inner: Default::default(), + } + } +} + fn main() {} diff --git a/tests/ui/format.fixed b/tests/ui/format.fixed index cd2f70ee8b0..beedf2c1db2 100644 --- a/tests/ui/format.fixed +++ b/tests/ui/format.fixed @@ -1,5 +1,4 @@ // run-rustfix -// aux-build: proc_macro_with_span.rs #![warn(clippy::useless_format)] #![allow( unused_tuple_struct_fields, @@ -10,8 +9,6 @@ clippy::uninlined_format_args )] -extern crate proc_macro_with_span; - struct Foo(pub String); macro_rules! foo { @@ -90,7 +87,4 @@ fn main() { let _ = abc.to_string(); let xx = "xx"; let _ = xx.to_string(); - - // Issue #10148 - println!(proc_macro_with_span::with_span!(""something "")); } diff --git a/tests/ui/format.rs b/tests/ui/format.rs index c22345a79d4..e805f181889 100644 --- a/tests/ui/format.rs +++ b/tests/ui/format.rs @@ -1,5 +1,4 @@ // run-rustfix -// aux-build: proc_macro_with_span.rs #![warn(clippy::useless_format)] #![allow( unused_tuple_struct_fields, @@ -10,8 +9,6 @@ clippy::uninlined_format_args )] -extern crate proc_macro_with_span; - struct Foo(pub String); macro_rules! foo { @@ -92,7 +89,4 @@ fn main() { let _ = format!("{abc}"); let xx = "xx"; let _ = format!("{xx}"); - - // Issue #10148 - println!(proc_macro_with_span::with_span!(""something "")); } diff --git a/tests/ui/format.stderr b/tests/ui/format.stderr index a0e5d5c8ad2..0ef0ac655d3 100644 --- a/tests/ui/format.stderr +++ b/tests/ui/format.stderr @@ -1,5 +1,5 @@ error: useless use of `format!` - --> $DIR/format.rs:22:5 + --> $DIR/format.rs:19:5 | LL | format!("foo"); | ^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"foo".to_string()` @@ -7,19 +7,19 @@ LL | format!("foo"); = note: `-D clippy::useless-format` implied by `-D warnings` error: useless use of `format!` - --> $DIR/format.rs:23:5 + --> $DIR/format.rs:20:5 | LL | format!("{{}}"); | ^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"{}".to_string()` error: useless use of `format!` - --> $DIR/format.rs:24:5 + --> $DIR/format.rs:21:5 | LL | format!("{{}} abc {{}}"); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"{} abc {}".to_string()` error: useless use of `format!` - --> $DIR/format.rs:25:5 + --> $DIR/format.rs:22:5 | LL | / format!( LL | | r##"foo {{}} @@ -34,67 +34,67 @@ LL ~ " bar"##.to_string(); | error: useless use of `format!` - --> $DIR/format.rs:30:13 + --> $DIR/format.rs:27:13 | LL | let _ = format!(""); | ^^^^^^^^^^^ help: consider using `String::new()`: `String::new()` error: useless use of `format!` - --> $DIR/format.rs:32:5 + --> $DIR/format.rs:29:5 | LL | format!("{}", "foo"); | ^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `"foo".to_string()` error: useless use of `format!` - --> $DIR/format.rs:40:5 + --> $DIR/format.rs:37:5 | LL | format!("{}", arg); | ^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `arg.to_string()` error: useless use of `format!` - --> $DIR/format.rs:70:5 + --> $DIR/format.rs:67:5 | LL | format!("{}", 42.to_string()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `42.to_string()` error: useless use of `format!` - --> $DIR/format.rs:72:5 + --> $DIR/format.rs:69:5 | LL | format!("{}", x.display().to_string()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.display().to_string()` error: useless use of `format!` - --> $DIR/format.rs:76:18 + --> $DIR/format.rs:73:18 | LL | let _ = Some(format!("{}", a + "bar")); | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `a + "bar"` error: useless use of `format!` - --> $DIR/format.rs:80:22 + --> $DIR/format.rs:77:22 | LL | let _s: String = format!("{}", &*v.join("/n")); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `(&*v.join("/n")).to_string()` error: useless use of `format!` - --> $DIR/format.rs:86:13 + --> $DIR/format.rs:83:13 | LL | let _ = format!("{x}"); | ^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.to_string()` error: useless use of `format!` - --> $DIR/format.rs:88:13 + --> $DIR/format.rs:85:13 | LL | let _ = format!("{y}", y = x); | ^^^^^^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `x.to_string()` error: useless use of `format!` - --> $DIR/format.rs:92:13 + --> $DIR/format.rs:89:13 | LL | let _ = format!("{abc}"); | ^^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `abc.to_string()` error: useless use of `format!` - --> $DIR/format.rs:94:13 + --> $DIR/format.rs:91:13 | LL | let _ = format!("{xx}"); | ^^^^^^^^^^^^^^^ help: consider using `.to_string()`: `xx.to_string()` diff --git a/tests/ui/impl_trait_in_params.stderr b/tests/ui/impl_trait_in_params.stderr index acfcc21445e..80383743525 100644 --- a/tests/ui/impl_trait_in_params.stderr +++ b/tests/ui/impl_trait_in_params.stderr @@ -5,7 +5,7 @@ LL | pub fn a(_: impl Trait) {} | ^^^^^^^^^^ | = note: `-D clippy::impl-trait-in-params` implied by `-D warnings` -help: add a type paremeter +help: add a type parameter | LL | pub fn a<{ /* Generic name */ }: Trait>(_: impl Trait) {} | +++++++++++++++++++++++++++++++ @@ -16,7 +16,7 @@ error: '`impl Trait` used as a function parameter' LL | pub fn c(_: C, _: impl Trait) {} | ^^^^^^^^^^ | -help: add a type paremeter +help: add a type parameter | LL | pub fn c(_: C, _: impl Trait) {} | +++++++++++++++++++++++++++++++ diff --git a/tests/ui/implicit_clone.fixed b/tests/ui/implicit_clone.fixed index 51b1afbe5ac..8ccc3da7b47 100644 --- a/tests/ui/implicit_clone.fixed +++ b/tests/ui/implicit_clone.fixed @@ -87,7 +87,7 @@ fn main() { let kitten = Kitten {}; let _ = kitten.clone(); let _ = own_same_from_ref(&kitten); - // this shouln't lint + // this shouldn't lint let _ = kitten.to_vec(); // we expect no lints for this diff --git a/tests/ui/implicit_clone.rs b/tests/ui/implicit_clone.rs index 8a9027433d9..59333312607 100644 --- a/tests/ui/implicit_clone.rs +++ b/tests/ui/implicit_clone.rs @@ -87,7 +87,7 @@ fn main() { let kitten = Kitten {}; let _ = kitten.to_owned(); let _ = own_same_from_ref(&kitten); - // this shouln't lint + // this shouldn't lint let _ = kitten.to_vec(); // we expect no lints for this diff --git a/tests/ui/len_without_is_empty.rs b/tests/ui/len_without_is_empty.rs index b5dec6c46bd..52aabefaed2 100644 --- a/tests/ui/len_without_is_empty.rs +++ b/tests/ui/len_without_is_empty.rs @@ -282,6 +282,87 @@ impl AsyncLen { } } +// issue #7232 +pub struct AsyncLenWithoutIsEmpty; +impl AsyncLenWithoutIsEmpty { + pub async fn async_task(&self) -> bool { + true + } + + pub async fn len(&self) -> usize { + usize::from(!self.async_task().await) + } +} + +// issue #7232 +pub struct AsyncOptionLenWithoutIsEmpty; +impl AsyncOptionLenWithoutIsEmpty { + async fn async_task(&self) -> bool { + true + } + + pub async fn len(&self) -> Option { + None + } +} + +// issue #7232 +pub struct AsyncOptionLenNonIntegral; +impl AsyncOptionLenNonIntegral { + // don't lint + pub async fn len(&self) -> Option { + None + } +} + +// issue #7232 +pub struct AsyncResultLenWithoutIsEmpty; +impl AsyncResultLenWithoutIsEmpty { + async fn async_task(&self) -> bool { + true + } + + pub async fn len(&self) -> Result { + Err(()) + } +} + +// issue #7232 +pub struct AsyncOptionLen; +impl AsyncOptionLen { + async fn async_task(&self) -> bool { + true + } + + pub async fn len(&self) -> Result { + Err(()) + } + + pub async fn is_empty(&self) -> bool { + true + } +} + +pub struct AsyncLenSyncIsEmpty; +impl AsyncLenSyncIsEmpty { + pub async fn len(&self) -> u32 { + 0 + } + + pub fn is_empty(&self) -> bool { + true + } +} + +// issue #9520 +pub struct NonStandardLen; +impl NonStandardLen { + // don't lint + pub fn len(&self, something: usize) -> usize { + something + } +} + // issue #9520 pub struct NonStandardLenAndIsEmptySignature; impl NonStandardLenAndIsEmptySignature { @@ -328,4 +409,15 @@ impl NonStandardSignatureWithGenerics { } } +pub struct DifferingErrors; +impl DifferingErrors { + pub fn len(&self) -> Result { + Ok(0) + } + + pub fn is_empty(&self) -> Result { + Ok(true) + } +} + fn main() {} diff --git a/tests/ui/len_without_is_empty.stderr b/tests/ui/len_without_is_empty.stderr index 8e890e2e259..1bce1734b81 100644 --- a/tests/ui/len_without_is_empty.stderr +++ b/tests/ui/len_without_is_empty.stderr @@ -119,5 +119,23 @@ LL | pub fn len(&self) -> Result { | = help: use a custom `Error` type instead -error: aborting due to 12 previous errors +error: struct `AsyncLenWithoutIsEmpty` has a public `len` method, but no `is_empty` method + --> $DIR/len_without_is_empty.rs:292:5 + | +LL | pub async fn len(&self) -> usize { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: struct `AsyncOptionLenWithoutIsEmpty` has a public `len` method, but no `is_empty` method + --> $DIR/len_without_is_empty.rs:304:5 + | +LL | pub async fn len(&self) -> Option { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: struct `AsyncResultLenWithoutIsEmpty` has a public `len` method, but no `is_empty` method + --> $DIR/len_without_is_empty.rs:325:5 + | +LL | pub async fn len(&self) -> Result { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 15 previous errors diff --git a/tests/ui/let_unit.fixed b/tests/ui/let_unit.fixed index 6343cff0f7f..76ff0645f41 100644 --- a/tests/ui/let_unit.fixed +++ b/tests/ui/let_unit.fixed @@ -175,3 +175,7 @@ fn attributes() { #[expect(clippy::let_unit_value)] let _ = f(); } + +async fn issue10433() { + let _pending: () = std::future::pending().await; +} diff --git a/tests/ui/let_unit.rs b/tests/ui/let_unit.rs index c9bb2849f5c..895ccfe366a 100644 --- a/tests/ui/let_unit.rs +++ b/tests/ui/let_unit.rs @@ -175,3 +175,7 @@ fn attributes() { #[expect(clippy::let_unit_value)] let _ = f(); } + +async fn issue10433() { + let _pending: () = std::future::pending().await; +} diff --git a/tests/ui/let_with_type_underscore.rs b/tests/ui/let_with_type_underscore.rs new file mode 100644 index 00000000000..175718b94c8 --- /dev/null +++ b/tests/ui/let_with_type_underscore.rs @@ -0,0 +1,19 @@ +#![allow(unused)] +#![warn(clippy::let_with_type_underscore)] +#![allow(clippy::let_unit_value)] + +fn func() -> &'static str { + "" +} + +fn main() { + // Will lint + let x: _ = 1; + let _: _ = 2; + let x: _ = func(); + + let x = 1; // Will not lint, Rust inferres this to an integer before Clippy + let x = func(); + let x: Vec<_> = Vec::::new(); + let x: [_; 1] = [1]; +} diff --git a/tests/ui/let_with_type_underscore.stderr b/tests/ui/let_with_type_underscore.stderr new file mode 100644 index 00000000000..16bf83c708f --- /dev/null +++ b/tests/ui/let_with_type_underscore.stderr @@ -0,0 +1,39 @@ +error: variable declared with type underscore + --> $DIR/let_with_type_underscore.rs:11:5 + | +LL | let x: _ = 1; + | ^^^^^^^^^^^^^ + | +help: remove the explicit type `_` declaration + --> $DIR/let_with_type_underscore.rs:11:10 + | +LL | let x: _ = 1; + | ^^^ + = note: `-D clippy::let-with-type-underscore` implied by `-D warnings` + +error: variable declared with type underscore + --> $DIR/let_with_type_underscore.rs:12:5 + | +LL | let _: _ = 2; + | ^^^^^^^^^^^^^ + | +help: remove the explicit type `_` declaration + --> $DIR/let_with_type_underscore.rs:12:10 + | +LL | let _: _ = 2; + | ^^^ + +error: variable declared with type underscore + --> $DIR/let_with_type_underscore.rs:13:5 + | +LL | let x: _ = func(); + | ^^^^^^^^^^^^^^^^^^ + | +help: remove the explicit type `_` declaration + --> $DIR/let_with_type_underscore.rs:13:10 + | +LL | let x: _ = func(); + | ^^^ + +error: aborting due to 3 previous errors + diff --git a/tests/ui/manual_rem_euclid.fixed b/tests/ui/manual_rem_euclid.fixed index 4cdc0546a74..6916a284a20 100644 --- a/tests/ui/manual_rem_euclid.fixed +++ b/tests/ui/manual_rem_euclid.fixed @@ -2,6 +2,7 @@ // aux-build:macro_rules.rs #![warn(clippy::manual_rem_euclid)] +#![allow(clippy::let_with_type_underscore)] #[macro_use] extern crate macro_rules; diff --git a/tests/ui/manual_rem_euclid.rs b/tests/ui/manual_rem_euclid.rs index 58a9e20f38b..412dbddb426 100644 --- a/tests/ui/manual_rem_euclid.rs +++ b/tests/ui/manual_rem_euclid.rs @@ -2,6 +2,7 @@ // aux-build:macro_rules.rs #![warn(clippy::manual_rem_euclid)] +#![allow(clippy::let_with_type_underscore)] #[macro_use] extern crate macro_rules; diff --git a/tests/ui/manual_rem_euclid.stderr b/tests/ui/manual_rem_euclid.stderr index e3122a588b6..6d06654638b 100644 --- a/tests/ui/manual_rem_euclid.stderr +++ b/tests/ui/manual_rem_euclid.stderr @@ -1,5 +1,5 @@ error: manual `rem_euclid` implementation - --> $DIR/manual_rem_euclid.rs:19:18 + --> $DIR/manual_rem_euclid.rs:20:18 | LL | let _: i32 = ((value % 4) + 4) % 4; | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)` @@ -7,31 +7,31 @@ LL | let _: i32 = ((value % 4) + 4) % 4; = note: `-D clippy::manual-rem-euclid` implied by `-D warnings` error: manual `rem_euclid` implementation - --> $DIR/manual_rem_euclid.rs:20:18 + --> $DIR/manual_rem_euclid.rs:21:18 | LL | let _: i32 = (4 + (value % 4)) % 4; | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)` error: manual `rem_euclid` implementation - --> $DIR/manual_rem_euclid.rs:21:18 + --> $DIR/manual_rem_euclid.rs:22:18 | LL | let _: i32 = (value % 4 + 4) % 4; | ^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)` error: manual `rem_euclid` implementation - --> $DIR/manual_rem_euclid.rs:22:18 + --> $DIR/manual_rem_euclid.rs:23:18 | LL | let _: i32 = (4 + value % 4) % 4; | ^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)` error: manual `rem_euclid` implementation - --> $DIR/manual_rem_euclid.rs:23:22 + --> $DIR/manual_rem_euclid.rs:24:22 | LL | let _: i32 = 1 + (4 + value % 4) % 4; | ^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)` error: manual `rem_euclid` implementation - --> $DIR/manual_rem_euclid.rs:12:22 + --> $DIR/manual_rem_euclid.rs:13:22 | LL | let _: i32 = ((value % 4) + 4) % 4; | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)` @@ -42,25 +42,25 @@ LL | internal_rem_euclid!(); = note: this error originates in the macro `internal_rem_euclid` (in Nightly builds, run with -Z macro-backtrace for more info) error: manual `rem_euclid` implementation - --> $DIR/manual_rem_euclid.rs:49:5 + --> $DIR/manual_rem_euclid.rs:50:5 | LL | ((num % 4) + 4) % 4 | ^^^^^^^^^^^^^^^^^^^ help: consider using: `num.rem_euclid(4)` error: manual `rem_euclid` implementation - --> $DIR/manual_rem_euclid.rs:54:5 + --> $DIR/manual_rem_euclid.rs:55:5 | LL | ((num % 4) + 4) % 4 | ^^^^^^^^^^^^^^^^^^^ help: consider using: `num.rem_euclid(4)` error: manual `rem_euclid` implementation - --> $DIR/manual_rem_euclid.rs:66:18 + --> $DIR/manual_rem_euclid.rs:67:18 | LL | let _: i32 = ((x % 4) + 4) % 4; | ^^^^^^^^^^^^^^^^^ help: consider using: `x.rem_euclid(4)` error: manual `rem_euclid` implementation - --> $DIR/manual_rem_euclid.rs:79:18 + --> $DIR/manual_rem_euclid.rs:80:18 | LL | let _: i32 = ((x % 4) + 4) % 4; | ^^^^^^^^^^^^^^^^^ help: consider using: `x.rem_euclid(4)` diff --git a/tests/ui/match_result_ok.fixed b/tests/ui/match_result_ok.fixed index 8b91b9854a0..10ae1ee5245 100644 --- a/tests/ui/match_result_ok.fixed +++ b/tests/ui/match_result_ok.fixed @@ -16,7 +16,7 @@ fn str_to_int_ok(x: &str) -> i32 { #[rustfmt::skip] fn strange_some_no_else(x: &str) -> i32 { { - if let Ok(y) = x . parse() { + if let Ok(y) = x . parse() { return y; }; 0 diff --git a/tests/ui/match_result_ok.stderr b/tests/ui/match_result_ok.stderr index 98a95705ca5..cbdc56aa28c 100644 --- a/tests/ui/match_result_ok.stderr +++ b/tests/ui/match_result_ok.stderr @@ -18,7 +18,7 @@ LL | if let Some(y) = x . parse() . ok () { | help: consider matching on `Ok(y)` and removing the call to `ok` instead | -LL | if let Ok(y) = x . parse() { +LL | if let Ok(y) = x . parse() { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: matching on `Some` with `ok()` is redundant diff --git a/tests/ui/missing_assert_message.rs b/tests/ui/missing_assert_message.rs new file mode 100644 index 00000000000..89404ca8827 --- /dev/null +++ b/tests/ui/missing_assert_message.rs @@ -0,0 +1,84 @@ +#![allow(unused)] +#![warn(clippy::missing_assert_message)] + +macro_rules! bar { + ($( $x:expr ),*) => { + foo() + }; +} + +fn main() {} + +// Should trigger warning +fn asserts_without_message() { + assert!(foo()); + assert_eq!(foo(), foo()); + assert_ne!(foo(), foo()); + debug_assert!(foo()); + debug_assert_eq!(foo(), foo()); + debug_assert_ne!(foo(), foo()); +} + +// Should trigger warning +fn asserts_without_message_but_with_macro_calls() { + assert!(bar!(true)); + assert!(bar!(true, false)); + assert_eq!(bar!(true), foo()); + assert_ne!(bar!(true, true), bar!(true)); +} + +// Should trigger warning +fn asserts_with_trailing_commas() { + assert!(foo(),); + assert_eq!(foo(), foo(),); + assert_ne!(foo(), foo(),); + debug_assert!(foo(),); + debug_assert_eq!(foo(), foo(),); + debug_assert_ne!(foo(), foo(),); +} + +// Should not trigger warning +fn asserts_with_message_and_with_macro_calls() { + assert!(bar!(true), "msg"); + assert!(bar!(true, false), "msg"); + assert_eq!(bar!(true), foo(), "msg"); + assert_ne!(bar!(true, true), bar!(true), "msg"); +} + +// Should not trigger warning +fn asserts_with_message() { + assert!(foo(), "msg"); + assert_eq!(foo(), foo(), "msg"); + assert_ne!(foo(), foo(), "msg"); + debug_assert!(foo(), "msg"); + debug_assert_eq!(foo(), foo(), "msg"); + debug_assert_ne!(foo(), foo(), "msg"); +} + +// Should not trigger warning +#[test] +fn asserts_without_message_but_inside_a_test_function() { + assert!(foo()); + assert_eq!(foo(), foo()); + assert_ne!(foo(), foo()); + debug_assert!(foo()); + debug_assert_eq!(foo(), foo()); + debug_assert_ne!(foo(), foo()); +} + +// Should not trigger warning +#[cfg(test)] +mod tests { + fn asserts_without_message_but_inside_a_test_module() { + assert!(foo()); + assert_eq!(foo(), foo()); + assert_ne!(foo(), foo()); + debug_assert!(foo()); + debug_assert_eq!(foo(), foo()); + debug_assert_ne!(foo(), foo()); + } +} + +fn foo() -> bool { + true +} diff --git a/tests/ui/missing_assert_message.stderr b/tests/ui/missing_assert_message.stderr new file mode 100644 index 00000000000..ecd03801277 --- /dev/null +++ b/tests/ui/missing_assert_message.stderr @@ -0,0 +1,131 @@ +error: assert without any message + --> $DIR/missing_assert_message.rs:14:5 + | +LL | assert!(foo()); + | ^^^^^^^^^^^^^^ + | + = help: consider describing why the failing assert is problematic + = note: `-D clippy::missing-assert-message` implied by `-D warnings` + +error: assert without any message + --> $DIR/missing_assert_message.rs:15:5 + | +LL | assert_eq!(foo(), foo()); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider describing why the failing assert is problematic + +error: assert without any message + --> $DIR/missing_assert_message.rs:16:5 + | +LL | assert_ne!(foo(), foo()); + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider describing why the failing assert is problematic + +error: assert without any message + --> $DIR/missing_assert_message.rs:17:5 + | +LL | debug_assert!(foo()); + | ^^^^^^^^^^^^^^^^^^^^ + | + = help: consider describing why the failing assert is problematic + +error: assert without any message + --> $DIR/missing_assert_message.rs:18:5 + | +LL | debug_assert_eq!(foo(), foo()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider describing why the failing assert is problematic + +error: assert without any message + --> $DIR/missing_assert_message.rs:19:5 + | +LL | debug_assert_ne!(foo(), foo()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider describing why the failing assert is problematic + +error: assert without any message + --> $DIR/missing_assert_message.rs:24:5 + | +LL | assert!(bar!(true)); + | ^^^^^^^^^^^^^^^^^^^ + | + = help: consider describing why the failing assert is problematic + +error: assert without any message + --> $DIR/missing_assert_message.rs:25:5 + | +LL | assert!(bar!(true, false)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider describing why the failing assert is problematic + +error: assert without any message + --> $DIR/missing_assert_message.rs:26:5 + | +LL | assert_eq!(bar!(true), foo()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider describing why the failing assert is problematic + +error: assert without any message + --> $DIR/missing_assert_message.rs:27:5 + | +LL | assert_ne!(bar!(true, true), bar!(true)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider describing why the failing assert is problematic + +error: assert without any message + --> $DIR/missing_assert_message.rs:32:5 + | +LL | assert!(foo(),); + | ^^^^^^^^^^^^^^^ + | + = help: consider describing why the failing assert is problematic + +error: assert without any message + --> $DIR/missing_assert_message.rs:33:5 + | +LL | assert_eq!(foo(), foo(),); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider describing why the failing assert is problematic + +error: assert without any message + --> $DIR/missing_assert_message.rs:34:5 + | +LL | assert_ne!(foo(), foo(),); + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider describing why the failing assert is problematic + +error: assert without any message + --> $DIR/missing_assert_message.rs:35:5 + | +LL | debug_assert!(foo(),); + | ^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider describing why the failing assert is problematic + +error: assert without any message + --> $DIR/missing_assert_message.rs:36:5 + | +LL | debug_assert_eq!(foo(), foo(),); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider describing why the failing assert is problematic + +error: assert without any message + --> $DIR/missing_assert_message.rs:37:5 + | +LL | debug_assert_ne!(foo(), foo(),); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider describing why the failing assert is problematic + +error: aborting due to 16 previous errors + diff --git a/tests/ui/missing_doc.stderr b/tests/ui/missing_doc.stderr index d3bef28bf64..4e8a49bf1cd 100644 --- a/tests/ui/missing_doc.stderr +++ b/tests/ui/missing_doc.stderr @@ -6,30 +6,12 @@ LL | type Typedef = String; | = note: `-D clippy::missing-docs-in-private-items` implied by `-D warnings` -error: missing documentation for a type alias - --> $DIR/missing_doc.rs:17:1 - | -LL | pub type PubTypedef = String; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error: missing documentation for a module --> $DIR/missing_doc.rs:19:1 | LL | mod module_no_dox {} | ^^^^^^^^^^^^^^^^^^^^ -error: missing documentation for a module - --> $DIR/missing_doc.rs:20:1 - | -LL | pub mod pub_module_no_dox {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: missing documentation for a function - --> $DIR/missing_doc.rs:24:1 - | -LL | pub fn foo2() {} - | ^^^^^^^^^^^^^^^^ - error: missing documentation for a function --> $DIR/missing_doc.rs:25:1 | @@ -69,50 +51,18 @@ error: missing documentation for a variant LL | BarB, | ^^^^ -error: missing documentation for an enum - --> $DIR/missing_doc.rs:44:1 - | -LL | / pub enum PubBaz { -LL | | PubBazA { a: isize }, -LL | | } - | |_^ - -error: missing documentation for a variant - --> $DIR/missing_doc.rs:45:5 - | -LL | PubBazA { a: isize }, - | ^^^^^^^^^^^^^^^^^^^^ - -error: missing documentation for a struct field - --> $DIR/missing_doc.rs:45:15 - | -LL | PubBazA { a: isize }, - | ^^^^^^^^ - error: missing documentation for a constant --> $DIR/missing_doc.rs:65:1 | LL | const FOO: u32 = 0; | ^^^^^^^^^^^^^^^^^^^ -error: missing documentation for a constant - --> $DIR/missing_doc.rs:72:1 - | -LL | pub const FOO4: u32 = 0; - | ^^^^^^^^^^^^^^^^^^^^^^^^ - error: missing documentation for a static --> $DIR/missing_doc.rs:74:1 | LL | static BAR: u32 = 0; | ^^^^^^^^^^^^^^^^^^^^ -error: missing documentation for a static - --> $DIR/missing_doc.rs:81:1 - | -LL | pub static BAR4: u32 = 0; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - error: missing documentation for a module --> $DIR/missing_doc.rs:83:1 | @@ -125,35 +75,17 @@ LL | | } LL | | } | |_^ -error: missing documentation for a function - --> $DIR/missing_doc.rs:86:5 - | -LL | pub fn undocumented1() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: missing documentation for a function - --> $DIR/missing_doc.rs:87:5 - | -LL | pub fn undocumented2() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - error: missing documentation for a function --> $DIR/missing_doc.rs:88:5 | LL | fn undocumented3() {} | ^^^^^^^^^^^^^^^^^^^^^ -error: missing documentation for a function - --> $DIR/missing_doc.rs:93:9 - | -LL | pub fn also_undocumented1() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error: missing documentation for a function --> $DIR/missing_doc.rs:94:9 | LL | fn also_undocumented2() {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 24 previous errors +error: aborting due to 13 previous errors diff --git a/tests/ui/missing_doc_impl.stderr b/tests/ui/missing_doc_impl.stderr index b410f56e167..111d6546966 100644 --- a/tests/ui/missing_doc_impl.stderr +++ b/tests/ui/missing_doc_impl.stderr @@ -21,60 +21,12 @@ error: missing documentation for a struct field LL | b: isize, | ^^^^^^^^ -error: missing documentation for a struct - --> $DIR/missing_doc_impl.rs:18:1 - | -LL | / pub struct PubFoo { -LL | | pub a: isize, -LL | | b: isize, -LL | | } - | |_^ - -error: missing documentation for a struct field - --> $DIR/missing_doc_impl.rs:19:5 - | -LL | pub a: isize, - | ^^^^^^^^^^^^ - error: missing documentation for a struct field --> $DIR/missing_doc_impl.rs:20:5 | LL | b: isize, | ^^^^^^^^ -error: missing documentation for a trait - --> $DIR/missing_doc_impl.rs:43:1 - | -LL | / pub trait C { -LL | | fn foo(&self); -LL | | fn foo_with_impl(&self) {} -LL | | } - | |_^ - -error: missing documentation for a method - --> $DIR/missing_doc_impl.rs:44:5 - | -LL | fn foo(&self); - | ^^^^^^^^^^^^^^ - -error: missing documentation for a method - --> $DIR/missing_doc_impl.rs:45:5 - | -LL | fn foo_with_impl(&self) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: missing documentation for an associated type - --> $DIR/missing_doc_impl.rs:55:5 - | -LL | type AssociatedType; - | ^^^^^^^^^^^^^^^^^^^^ - -error: missing documentation for an associated type - --> $DIR/missing_doc_impl.rs:56:5 - | -LL | type AssociatedTypeDef = Self; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error: missing documentation for an associated function --> $DIR/missing_doc_impl.rs:67:5 | @@ -89,12 +41,6 @@ error: missing documentation for an associated function LL | fn bar() {} | ^^^^^^^^^^^ -error: missing documentation for an associated function - --> $DIR/missing_doc_impl.rs:74:5 - | -LL | pub fn foo() {} - | ^^^^^^^^^^^^^^^ - error: missing documentation for an associated function --> $DIR/missing_doc_impl.rs:78:5 | @@ -103,5 +49,5 @@ LL | | 1 LL | | } | |_____^ -error: aborting due to 15 previous errors +error: aborting due to 7 previous errors diff --git a/tests/ui/multiple_unsafe_ops_per_block.rs b/tests/ui/multiple_unsafe_ops_per_block.rs index 4511bc99c3c..5073685c9f0 100644 --- a/tests/ui/multiple_unsafe_ops_per_block.rs +++ b/tests/ui/multiple_unsafe_ops_per_block.rs @@ -116,4 +116,32 @@ fn issue10259() { unsafe_macro!(); } +fn _fn_ptr(x: unsafe fn()) { + unsafe { + x(); + x(); + } +} + +fn _assoc_const() { + trait X { + const X: unsafe fn(); + } + fn _f() { + unsafe { + T::X(); + T::X(); + } + } +} + +fn _field_fn_ptr(x: unsafe fn()) { + struct X(unsafe fn()); + let x = X(x); + unsafe { + x.0(); + x.0(); + } +} + fn main() {} diff --git a/tests/ui/multiple_unsafe_ops_per_block.stderr b/tests/ui/multiple_unsafe_ops_per_block.stderr index 303aeb7aee0..e0c1d3801f7 100644 --- a/tests/ui/multiple_unsafe_ops_per_block.stderr +++ b/tests/ui/multiple_unsafe_ops_per_block.stderr @@ -125,5 +125,65 @@ note: raw pointer dereference occurs here LL | unsafe { char::from_u32_unchecked(*ptr.cast::()) } | ^^^^^^^^^^^^^^^^^^ -error: aborting due to 5 previous errors +error: this `unsafe` block contains 2 unsafe operations, expected only one + --> $DIR/multiple_unsafe_ops_per_block.rs:120:5 + | +LL | / unsafe { +LL | | x(); +LL | | x(); +LL | | } + | |_____^ + | +note: unsafe function call occurs here + --> $DIR/multiple_unsafe_ops_per_block.rs:121:9 + | +LL | x(); + | ^^^ +note: unsafe function call occurs here + --> $DIR/multiple_unsafe_ops_per_block.rs:122:9 + | +LL | x(); + | ^^^ + +error: this `unsafe` block contains 2 unsafe operations, expected only one + --> $DIR/multiple_unsafe_ops_per_block.rs:131:9 + | +LL | / unsafe { +LL | | T::X(); +LL | | T::X(); +LL | | } + | |_________^ + | +note: unsafe function call occurs here + --> $DIR/multiple_unsafe_ops_per_block.rs:132:13 + | +LL | T::X(); + | ^^^^^^ +note: unsafe function call occurs here + --> $DIR/multiple_unsafe_ops_per_block.rs:133:13 + | +LL | T::X(); + | ^^^^^^ + +error: this `unsafe` block contains 2 unsafe operations, expected only one + --> $DIR/multiple_unsafe_ops_per_block.rs:141:5 + | +LL | / unsafe { +LL | | x.0(); +LL | | x.0(); +LL | | } + | |_____^ + | +note: unsafe function call occurs here + --> $DIR/multiple_unsafe_ops_per_block.rs:142:9 + | +LL | x.0(); + | ^^^^^ +note: unsafe function call occurs here + --> $DIR/multiple_unsafe_ops_per_block.rs:143:9 + | +LL | x.0(); + | ^^^^^ + +error: aborting due to 8 previous errors diff --git a/tests/ui/new_ret_no_self.rs b/tests/ui/new_ret_no_self.rs index beec42f08bb..a2a30c8b931 100644 --- a/tests/ui/new_ret_no_self.rs +++ b/tests/ui/new_ret_no_self.rs @@ -406,7 +406,7 @@ mod issue10041 { struct Bomb; impl Bomb { - // Hidden default generic paramter. + // Hidden default generic parameter. pub fn new() -> impl PartialOrd { 0i32 } diff --git a/tests/ui/redundant_async_block.fixed b/tests/ui/redundant_async_block.fixed new file mode 100644 index 00000000000..5f9931df45e --- /dev/null +++ b/tests/ui/redundant_async_block.fixed @@ -0,0 +1,64 @@ +// run-rustfix + +#![allow(unused)] +#![warn(clippy::redundant_async_block)] + +async fn func1(n: usize) -> usize { + n + 1 +} + +async fn func2() -> String { + let s = String::from("some string"); + let f = async { (*s).to_owned() }; + let x = f; + x.await +} + +macro_rules! await_in_macro { + ($e:expr) => { + std::convert::identity($e).await + }; +} + +async fn func3(n: usize) -> usize { + // Do not lint (suggestion would be `std::convert::identity(func1(n))` + // which copies code from inside the macro) + async move { await_in_macro!(func1(n)) }.await +} + +// This macro should never be linted as `$e` might contain `.await` +macro_rules! async_await_parameter_in_macro { + ($e:expr) => { + async { $e.await } + }; +} + +// MISSED OPPORTUNITY: this macro could be linted as the `async` block does not +// contain code coming from the parameters +macro_rules! async_await_in_macro { + ($f:expr) => { + ($f)(async { func2().await }) + }; +} + +fn main() { + let fut1 = async { 17 }; + let fut2 = fut1; + + let fut1 = async { 25 }; + let fut2 = fut1; + + let fut = async { 42 }; + + // Do not lint: not a single expression + let fut = async { + func1(10).await; + func2().await + }; + + // Do not lint: expression contains `.await` + let fut = async { func1(func2().await.len()).await }; + + let fut = async_await_parameter_in_macro!(func2()); + let fut = async_await_in_macro!(std::convert::identity); +} diff --git a/tests/ui/redundant_async_block.rs b/tests/ui/redundant_async_block.rs new file mode 100644 index 00000000000..de3c9970c65 --- /dev/null +++ b/tests/ui/redundant_async_block.rs @@ -0,0 +1,64 @@ +// run-rustfix + +#![allow(unused)] +#![warn(clippy::redundant_async_block)] + +async fn func1(n: usize) -> usize { + n + 1 +} + +async fn func2() -> String { + let s = String::from("some string"); + let f = async { (*s).to_owned() }; + let x = async { f.await }; + x.await +} + +macro_rules! await_in_macro { + ($e:expr) => { + std::convert::identity($e).await + }; +} + +async fn func3(n: usize) -> usize { + // Do not lint (suggestion would be `std::convert::identity(func1(n))` + // which copies code from inside the macro) + async move { await_in_macro!(func1(n)) }.await +} + +// This macro should never be linted as `$e` might contain `.await` +macro_rules! async_await_parameter_in_macro { + ($e:expr) => { + async { $e.await } + }; +} + +// MISSED OPPORTUNITY: this macro could be linted as the `async` block does not +// contain code coming from the parameters +macro_rules! async_await_in_macro { + ($f:expr) => { + ($f)(async { func2().await }) + }; +} + +fn main() { + let fut1 = async { 17 }; + let fut2 = async { fut1.await }; + + let fut1 = async { 25 }; + let fut2 = async move { fut1.await }; + + let fut = async { async { 42 }.await }; + + // Do not lint: not a single expression + let fut = async { + func1(10).await; + func2().await + }; + + // Do not lint: expression contains `.await` + let fut = async { func1(func2().await.len()).await }; + + let fut = async_await_parameter_in_macro!(func2()); + let fut = async_await_in_macro!(std::convert::identity); +} diff --git a/tests/ui/redundant_async_block.stderr b/tests/ui/redundant_async_block.stderr new file mode 100644 index 00000000000..b16d96dce84 --- /dev/null +++ b/tests/ui/redundant_async_block.stderr @@ -0,0 +1,28 @@ +error: this async expression only awaits a single future + --> $DIR/redundant_async_block.rs:13:13 + | +LL | let x = async { f.await }; + | ^^^^^^^^^^^^^^^^^ help: you can reduce it to: `f` + | + = note: `-D clippy::redundant-async-block` implied by `-D warnings` + +error: this async expression only awaits a single future + --> $DIR/redundant_async_block.rs:46:16 + | +LL | let fut2 = async { fut1.await }; + | ^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `fut1` + +error: this async expression only awaits a single future + --> $DIR/redundant_async_block.rs:49:16 + | +LL | let fut2 = async move { fut1.await }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `fut1` + +error: this async expression only awaits a single future + --> $DIR/redundant_async_block.rs:51:15 + | +LL | let fut = async { async { 42 }.await }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `async { 42 }` + +error: aborting due to 4 previous errors + diff --git a/tests/ui/redundant_closure_call_fixable.fixed b/tests/ui/redundant_closure_call_fixable.fixed index c0e49ff4caa..b987fd2ce6f 100644 --- a/tests/ui/redundant_closure_call_fixable.fixed +++ b/tests/ui/redundant_closure_call_fixable.fixed @@ -2,6 +2,7 @@ #![feature(async_closure)] #![warn(clippy::redundant_closure_call)] +#![allow(clippy::redundant_async_block)] #![allow(unused)] async fn something() -> u32 { diff --git a/tests/ui/redundant_closure_call_fixable.rs b/tests/ui/redundant_closure_call_fixable.rs index 9e6e54348a8..633a2979d5d 100644 --- a/tests/ui/redundant_closure_call_fixable.rs +++ b/tests/ui/redundant_closure_call_fixable.rs @@ -2,6 +2,7 @@ #![feature(async_closure)] #![warn(clippy::redundant_closure_call)] +#![allow(clippy::redundant_async_block)] #![allow(unused)] async fn something() -> u32 { diff --git a/tests/ui/redundant_closure_call_fixable.stderr b/tests/ui/redundant_closure_call_fixable.stderr index d71bcba2a82..8a1f0771659 100644 --- a/tests/ui/redundant_closure_call_fixable.stderr +++ b/tests/ui/redundant_closure_call_fixable.stderr @@ -1,5 +1,5 @@ error: try not to call a closure in the expression where it is declared - --> $DIR/redundant_closure_call_fixable.rs:16:13 + --> $DIR/redundant_closure_call_fixable.rs:17:13 | LL | let a = (|| 42)(); | ^^^^^^^^^ help: try doing something like: `42` @@ -7,7 +7,7 @@ LL | let a = (|| 42)(); = note: `-D clippy::redundant-closure-call` implied by `-D warnings` error: try not to call a closure in the expression where it is declared - --> $DIR/redundant_closure_call_fixable.rs:17:13 + --> $DIR/redundant_closure_call_fixable.rs:18:13 | LL | let b = (async || { | _____________^ @@ -27,7 +27,7 @@ LL ~ }; | error: try not to call a closure in the expression where it is declared - --> $DIR/redundant_closure_call_fixable.rs:22:13 + --> $DIR/redundant_closure_call_fixable.rs:23:13 | LL | let c = (|| { | _____________^ @@ -47,13 +47,13 @@ LL ~ }; | error: try not to call a closure in the expression where it is declared - --> $DIR/redundant_closure_call_fixable.rs:27:13 + --> $DIR/redundant_closure_call_fixable.rs:28:13 | LL | let d = (async || something().await)(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try doing something like: `async { something().await }` error: try not to call a closure in the expression where it is declared - --> $DIR/redundant_closure_call_fixable.rs:36:13 + --> $DIR/redundant_closure_call_fixable.rs:37:13 | LL | (|| m!())() | ^^^^^^^^^^^ help: try doing something like: `m!()` @@ -64,7 +64,7 @@ LL | m2!(); = note: this error originates in the macro `m2` (in Nightly builds, run with -Z macro-backtrace for more info) error: try not to call a closure in the expression where it is declared - --> $DIR/redundant_closure_call_fixable.rs:31:13 + --> $DIR/redundant_closure_call_fixable.rs:32:13 | LL | (|| 0)() | ^^^^^^^^ help: try doing something like: `0` diff --git a/tests/ui/swap.fixed b/tests/ui/swap.fixed index fa89706a815..04008c0d9b3 100644 --- a/tests/ui/swap.fixed +++ b/tests/ui/swap.fixed @@ -65,19 +65,19 @@ fn xor_swap_locals() { // This is an xor-based swap of local variables. let mut a = 0; let mut b = 1; - std::mem::swap(&mut a, &mut b) + std::mem::swap(&mut a, &mut b); } fn xor_field_swap() { // This is an xor-based swap of fields in a struct. let mut bar = Bar { a: 0, b: 1 }; - std::mem::swap(&mut bar.a, &mut bar.b) + std::mem::swap(&mut bar.a, &mut bar.b); } fn xor_slice_swap() { // This is an xor-based swap of a slice let foo = &mut [1, 2]; - foo.swap(0, 1) + foo.swap(0, 1); } fn xor_no_swap() { diff --git a/tests/ui/swap.stderr b/tests/ui/swap.stderr index f0acbfe253f..825c9261e19 100644 --- a/tests/ui/swap.stderr +++ b/tests/ui/swap.stderr @@ -4,7 +4,7 @@ error: this looks like you are swapping `bar.a` and `bar.b` manually LL | / let temp = bar.a; LL | | bar.a = bar.b; LL | | bar.b = temp; - | |________________^ help: try: `std::mem::swap(&mut bar.a, &mut bar.b)` + | |_________________^ help: try: `std::mem::swap(&mut bar.a, &mut bar.b);` | = note: or maybe you should use `std::mem::replace`? = note: `-D clippy::manual-swap` implied by `-D warnings` @@ -15,7 +15,7 @@ error: this looks like you are swapping elements of `foo` manually LL | / let temp = foo[0]; LL | | foo[0] = foo[1]; LL | | foo[1] = temp; - | |_________________^ help: try: `foo.swap(0, 1)` + | |__________________^ help: try: `foo.swap(0, 1);` error: this looks like you are swapping elements of `foo` manually --> $DIR/swap.rs:46:5 @@ -23,7 +23,7 @@ error: this looks like you are swapping elements of `foo` manually LL | / let temp = foo[0]; LL | | foo[0] = foo[1]; LL | | foo[1] = temp; - | |_________________^ help: try: `foo.swap(0, 1)` + | |__________________^ help: try: `foo.swap(0, 1);` error: this looks like you are swapping elements of `foo` manually --> $DIR/swap.rs:65:5 @@ -31,7 +31,7 @@ error: this looks like you are swapping elements of `foo` manually LL | / let temp = foo[0]; LL | | foo[0] = foo[1]; LL | | foo[1] = temp; - | |_________________^ help: try: `foo.swap(0, 1)` + | |__________________^ help: try: `foo.swap(0, 1);` error: this looks like you are swapping `a` and `b` manually --> $DIR/swap.rs:76:5 @@ -39,7 +39,7 @@ error: this looks like you are swapping `a` and `b` manually LL | / a ^= b; LL | | b ^= a; LL | | a ^= b; - | |___________^ help: try: `std::mem::swap(&mut a, &mut b)` + | |___________^ help: try: `std::mem::swap(&mut a, &mut b);` error: this looks like you are swapping `bar.a` and `bar.b` manually --> $DIR/swap.rs:84:5 @@ -47,7 +47,7 @@ error: this looks like you are swapping `bar.a` and `bar.b` manually LL | / bar.a ^= bar.b; LL | | bar.b ^= bar.a; LL | | bar.a ^= bar.b; - | |___________________^ help: try: `std::mem::swap(&mut bar.a, &mut bar.b)` + | |___________________^ help: try: `std::mem::swap(&mut bar.a, &mut bar.b);` error: this looks like you are swapping elements of `foo` manually --> $DIR/swap.rs:92:5 @@ -55,7 +55,7 @@ error: this looks like you are swapping elements of `foo` manually LL | / foo[0] ^= foo[1]; LL | | foo[1] ^= foo[0]; LL | | foo[0] ^= foo[1]; - | |_____________________^ help: try: `foo.swap(0, 1)` + | |_____________________^ help: try: `foo.swap(0, 1);` error: this looks like you are swapping `foo[0][1]` and `bar[1][0]` manually --> $DIR/swap.rs:121:5 @@ -63,7 +63,7 @@ error: this looks like you are swapping `foo[0][1]` and `bar[1][0]` manually LL | / let temp = foo[0][1]; LL | | foo[0][1] = bar[1][0]; LL | | bar[1][0] = temp; - | |____________________^ help: try: `std::mem::swap(&mut foo[0][1], &mut bar[1][0])` + | |_____________________^ help: try: `std::mem::swap(&mut foo[0][1], &mut bar[1][0]);` | = note: or maybe you should use `std::mem::replace`? @@ -74,7 +74,7 @@ LL | ; let t = a; | _______^ LL | | a = b; LL | | b = t; - | |_________^ help: try: `std::mem::swap(&mut a, &mut b)` + | |__________^ help: try: `std::mem::swap(&mut a, &mut b);` | = note: or maybe you should use `std::mem::replace`? @@ -85,7 +85,7 @@ LL | ; let t = c.0; | _______^ LL | | c.0 = a; LL | | a = t; - | |_________^ help: try: `std::mem::swap(&mut c.0, &mut a)` + | |__________^ help: try: `std::mem::swap(&mut c.0, &mut a);` | = note: or maybe you should use `std::mem::replace`? @@ -95,7 +95,7 @@ error: this looks like you are swapping `b` and `a` manually LL | / let t = b; LL | | b = a; LL | | a = t; - | |_________^ help: try: `std::mem::swap(&mut b, &mut a)` + | |__________^ help: try: `std::mem::swap(&mut b, &mut a);` | = note: or maybe you should use `std::mem::replace`? @@ -151,7 +151,7 @@ error: this looks like you are swapping `s.0.x` and `s.0.y` manually LL | / let t = s.0.x; LL | | s.0.x = s.0.y; LL | | s.0.y = t; - | |_____________^ help: try: `std::mem::swap(&mut s.0.x, &mut s.0.y)` + | |______________^ help: try: `std::mem::swap(&mut s.0.x, &mut s.0.y);` | = note: or maybe you should use `std::mem::replace`? diff --git a/tests/ui/trailing_empty_array.rs b/tests/ui/trailing_empty_array.rs index c39b0bcaf22..8e3749eef35 100644 --- a/tests/ui/trailing_empty_array.rs +++ b/tests/ui/trailing_empty_array.rs @@ -155,7 +155,6 @@ struct TupleStructReprC(i32, [usize; 0]); type NamedTuple = (i32, [usize; 0]); -#[rustfmt::skip] // [rustfmt#4995](https://github.com/rust-lang/rustfmt/issues/4995) struct ConstParamZeroDefault { field: i32, last: [usize; N], @@ -166,7 +165,6 @@ struct ConstParamNoDefault { last: [usize; N], } -#[rustfmt::skip] struct ConstParamNonZeroDefault { field: i32, last: [usize; N], diff --git a/tests/ui/use_self.fixed b/tests/ui/use_self.fixed index 0a6166571eb..3ac6217312a 100644 --- a/tests/ui/use_self.fixed +++ b/tests/ui/use_self.fixed @@ -647,3 +647,13 @@ fn msrv_1_37() { } } } + +mod issue_10371 { + struct Val {} + + impl From> for i32 { + fn from(_: Val) -> Self { + todo!() + } + } +} diff --git a/tests/ui/use_self.rs b/tests/ui/use_self.rs index 39c2b431f7f..9dc5d1e3f9b 100644 --- a/tests/ui/use_self.rs +++ b/tests/ui/use_self.rs @@ -647,3 +647,13 @@ fn msrv_1_37() { } } } + +mod issue_10371 { + struct Val {} + + impl From> for i32 { + fn from(_: Val) -> Self { + todo!() + } + } +} From c34d04a3ddce97a32c2024eb7cd1136e9d7fec95 Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Fri, 10 Mar 2023 11:28:10 +0100 Subject: [PATCH 020/346] Update changelog for beta-accepted labels --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0abe234fc8f..da7042f4440 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -152,6 +152,8 @@ Current stable, released 2023-03-09 * `SYSROOT` and `--sysroot` can now be set at the same time [#10149](https://github.com/rust-lang/rust-clippy/pull/10149) +* Fix error when providing an `array-size-threshold` in `clippy.toml` + [#10423](https://github.com/rust-lang/rust-clippy/pull/10423) ## Rust 1.67 @@ -186,8 +188,6 @@ Released 2023-01-26 ### Moves and Deprecations -* Moved [`uninlined_format_args`] to `style` (Now warn-by-default) - [#9865](https://github.com/rust-lang/rust-clippy/pull/9865) * Moved [`needless_collect`] to `nursery` (Now allow-by-default) [#9705](https://github.com/rust-lang/rust-clippy/pull/9705) * Moved [`or_fun_call`] to `nursery` (Now allow-by-default) @@ -423,7 +423,7 @@ Released 2022-12-15 [#9490](https://github.com/rust-lang/rust-clippy/pull/9490) * [`almost_complete_letter_range`]: No longer lints in external macros [#9467](https://github.com/rust-lang/rust-clippy/pull/9467) -* [`drop_copy`]: No longer lints on idiomatic cases in match arms +* [`drop_copy`]: No longer lints on idiomatic cases in match arms [#9491](https://github.com/rust-lang/rust-clippy/pull/9491) * [`question_mark`]: No longer lints in const context [#9487](https://github.com/rust-lang/rust-clippy/pull/9487) From 797d8bff0807acbd36d079401fc99dbf042f71e9 Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Fri, 10 Mar 2023 11:07:28 -0500 Subject: [PATCH 021/346] Don't lint `manual_clamp` in const contexts. --- clippy_lints/src/manual_clamp.rs | 7 ++++--- tests/ui/manual_clamp.rs | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/manual_clamp.rs b/clippy_lints/src/manual_clamp.rs index f239736d38a..440362b96b4 100644 --- a/clippy_lints/src/manual_clamp.rs +++ b/clippy_lints/src/manual_clamp.rs @@ -6,7 +6,8 @@ use clippy_utils::ty::implements_trait; use clippy_utils::visitors::is_const_evaluatable; use clippy_utils::MaybePath; use clippy_utils::{ - eq_expr_value, is_diag_trait_item, is_trait_method, path_res, path_to_local_id, peel_blocks, peel_blocks_with_stmt, + eq_expr_value, in_constant, is_diag_trait_item, is_trait_method, path_res, path_to_local_id, peel_blocks, + peel_blocks_with_stmt, }; use itertools::Itertools; use rustc_errors::Applicability; @@ -117,7 +118,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualClamp { if !self.msrv.meets(msrvs::CLAMP) { return; } - if !expr.span.from_expansion() { + if !expr.span.from_expansion() && !in_constant(cx, expr.hir_id) { let suggestion = is_if_elseif_else_pattern(cx, expr) .or_else(|| is_max_min_pattern(cx, expr)) .or_else(|| is_call_max_min_pattern(cx, expr)) @@ -130,7 +131,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualClamp { } fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) { - if !self.msrv.meets(msrvs::CLAMP) { + if !self.msrv.meets(msrvs::CLAMP) || in_constant(cx, block.hir_id) { return; } for suggestion in is_two_if_pattern(cx, block) { diff --git a/tests/ui/manual_clamp.rs b/tests/ui/manual_clamp.rs index f7902e6fd53..cdfd8e4c3fe 100644 --- a/tests/ui/manual_clamp.rs +++ b/tests/ui/manual_clamp.rs @@ -326,3 +326,22 @@ fn msrv_1_50() { input }; } + +const fn _const() { + let (input, min, max) = (0, -1, 2); + let _ = if input < min { + min + } else if input > max { + max + } else { + input + }; + + let mut x = input; + if max < x { + let x = max; + } + if min > x { + x = min; + } +} From 5c85cd9fee1ca177187b424a4328fa298c19a9aa Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 9 Mar 2023 19:53:59 +0000 Subject: [PATCH 022/346] Directly construct Inherited. --- .../src/methods/unnecessary_to_owned.rs | 8 +-- clippy_lints/src/transmute/utils.rs | 57 +++++++++---------- 2 files changed, 32 insertions(+), 33 deletions(-) diff --git a/clippy_lints/src/methods/unnecessary_to_owned.rs b/clippy_lints/src/methods/unnecessary_to_owned.rs index df26b36b7b3..4c4c003ca46 100644 --- a/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -369,10 +369,10 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty< Node::Item(item) => { if let ItemKind::Fn(_, _, body_id) = &item.kind && let output_ty = return_ty(cx, item.owner_id) - && Inherited::build(cx.tcx, item.owner_id.def_id).enter(|inherited| { - let fn_ctxt = FnCtxt::new(inherited, cx.param_env, item.owner_id.def_id); - fn_ctxt.can_coerce(ty, output_ty) - }) { + && let inherited = Inherited::new(cx.tcx, item.owner_id.def_id) + && let fn_ctxt = FnCtxt::new(&inherited, cx.param_env, item.owner_id.def_id) + && fn_ctxt.can_coerce(ty, output_ty) + { if has_lifetime(output_ty) && has_lifetime(ty) { return false; } diff --git a/clippy_lints/src/transmute/utils.rs b/clippy_lints/src/transmute/utils.rs index cddaf9450ea..62efd13b8d9 100644 --- a/clippy_lints/src/transmute/utils.rs +++ b/clippy_lints/src/transmute/utils.rs @@ -33,38 +33,37 @@ pub(super) fn check_cast<'tcx>( let hir_id = e.hir_id; let local_def_id = hir_id.owner.def_id; - Inherited::build(cx.tcx, local_def_id).enter(|inherited| { - let fn_ctxt = FnCtxt::new(inherited, cx.param_env, local_def_id); + let inherited = Inherited::new(cx.tcx, local_def_id); + let fn_ctxt = FnCtxt::new(&inherited, cx.param_env, local_def_id); - // If we already have errors, we can't be sure we can pointer cast. + // If we already have errors, we can't be sure we can pointer cast. + assert!( + !fn_ctxt.errors_reported_since_creation(), + "Newly created FnCtxt contained errors" + ); + + if let Ok(check) = cast::CastCheck::new( + &fn_ctxt, + e, + from_ty, + to_ty, + // We won't show any error to the user, so we don't care what the span is here. + DUMMY_SP, + DUMMY_SP, + hir::Constness::NotConst, + ) { + let res = check.do_check(&fn_ctxt); + + // do_check's documentation says that it might return Ok and create + // errors in the fcx instead of returning Err in some cases. Those cases + // should be filtered out before getting here. assert!( !fn_ctxt.errors_reported_since_creation(), - "Newly created FnCtxt contained errors" + "`fn_ctxt` contained errors after cast check!" ); - if let Ok(check) = cast::CastCheck::new( - &fn_ctxt, - e, - from_ty, - to_ty, - // We won't show any error to the user, so we don't care what the span is here. - DUMMY_SP, - DUMMY_SP, - hir::Constness::NotConst, - ) { - let res = check.do_check(&fn_ctxt); - - // do_check's documentation says that it might return Ok and create - // errors in the fcx instead of returning Err in some cases. Those cases - // should be filtered out before getting here. - assert!( - !fn_ctxt.errors_reported_since_creation(), - "`fn_ctxt` contained errors after cast check!" - ); - - res.ok() - } else { - None - } - }) + res.ok() + } else { + None + } } From 0f1474ea270fb3b5f7c0db295b2817028acdb97a Mon Sep 17 00:00:00 2001 From: blyxyas Date: Sat, 11 Mar 2023 00:23:58 +0100 Subject: [PATCH 023/346] Add `allow_attribute` lint --- CHANGELOG.md | 1 + clippy_lints/src/allow_attribute.rs | 91 +++++++++++++++++++++++++++++ clippy_lints/src/declared_lints.rs | 1 + clippy_lints/src/lib.rs | 6 ++ tests/ui/allow_attribute.fixed | 18 ++++++ tests/ui/allow_attribute.rs | 18 ++++++ tests/ui/allow_attribute.stderr | 10 ++++ 7 files changed, 145 insertions(+) create mode 100644 clippy_lints/src/allow_attribute.rs create mode 100644 tests/ui/allow_attribute.fixed create mode 100644 tests/ui/allow_attribute.rs create mode 100644 tests/ui/allow_attribute.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index da7042f4440..2b00fd962ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4382,6 +4382,7 @@ Released 2018-09-13 [`absurd_extreme_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#absurd_extreme_comparisons [`alloc_instead_of_core`]: https://rust-lang.github.io/rust-clippy/master/index.html#alloc_instead_of_core +[`allow_attribute`]: https://rust-lang.github.io/rust-clippy/master/index.html#allow_attribute [`allow_attributes_without_reason`]: https://rust-lang.github.io/rust-clippy/master/index.html#allow_attributes_without_reason [`almost_complete_letter_range`]: https://rust-lang.github.io/rust-clippy/master/index.html#almost_complete_letter_range [`almost_complete_range`]: https://rust-lang.github.io/rust-clippy/master/index.html#almost_complete_range diff --git a/clippy_lints/src/allow_attribute.rs b/clippy_lints/src/allow_attribute.rs new file mode 100644 index 00000000000..2970d467f6f --- /dev/null +++ b/clippy_lints/src/allow_attribute.rs @@ -0,0 +1,91 @@ +use ast::{AttrStyle, MetaItemKind}; +use clippy_utils::{diagnostics::span_lint_and_sugg, source::snippet}; +use rustc_ast as ast; +use rustc_errors::Applicability; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_session::{declare_tool_lint, impl_lint_pass}; +use rustc_span::{symbol::Ident, BytePos}; + +declare_clippy_lint! { + /// ### What it does + /// Detects uses of the `#[allow]` attribute and suggests to replace it with the new `#[expect]` attribute implemented by `#![feature(lint_reasons)]` ([RFC 2383](https://rust-lang.github.io/rfcs/2383-lint-reasons.html)) + /// ### Why is this bad? + /// Using `#[allow]` isn't bad, but `#[expect]` may be preferred as it lints if the code **doesn't** produce a warning. + /// ### Example + /// ```rust + /// #[allow(unused_mut)] + /// fn foo() -> usize { + /// let mut a = Vec::new(); + /// a.len() + ///} + /// ``` + /// Use instead: + /// ```rust + /// #[expect(unused_mut)] + /// fn foo() -> usize { + /// let mut a = Vec::new(); + /// a.len() + /// } + /// ``` + #[clippy::version = "1.69.0"] + pub ALLOW_ATTRIBUTE, + restriction, + "`#[allow]` will not trigger if a warning isn't found. `#[expect]` triggers if there are no warnings." +} + +pub struct AllowAttribute { + pub lint_reasons_active: bool, +} + +impl_lint_pass!(AllowAttribute => [ALLOW_ATTRIBUTE]); + +impl LateLintPass<'_> for AllowAttribute { + // Separate each crate's features. + fn check_crate_post(&mut self, _: &LateContext<'_>) { + self.lint_reasons_active = false; + } + fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &ast::Attribute) { + // Check inner attributes + + if_chain! { + if let AttrStyle::Inner = attr.style; + if attr.ident() + .unwrap_or(Ident::with_dummy_span(sym!(empty))) // Will not trigger if doesn't have an ident. + .name == sym!(feature); + if let ast::AttrKind::Normal(normal) = &attr.kind; + if let Some(MetaItemKind::List(list)) = normal.item.meta_kind(); + if list[0].ident().unwrap().name == sym!(lint_reasons); + then { + self.lint_reasons_active = true; + } + } + + // Check outer attributes + + if_chain! { + if let AttrStyle::Outer = attr.style; + if attr.ident() + .unwrap_or(Ident::with_dummy_span(sym!(empty))) // Will not trigger if doesn't have an ident. + .name == sym!(allow); + if self.lint_reasons_active; + then { + span_lint_and_sugg( + cx, + ALLOW_ATTRIBUTE, + attr.span, + "#[allow] attribute found", + "replace it with", + format!("#[expect{})]", snippet( + cx, + attr.ident().unwrap().span + .with_lo( + attr.ident().unwrap().span.hi() + BytePos(2) // Cut [( + ) + .with_hi( + attr.meta().unwrap().span.hi() - BytePos(2) // Cut )] + ) + , "...")), Applicability::MachineApplicable); + } + } + } +} diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index cc6024b87cd..73f74d59f4a 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -35,6 +35,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::utils::internal_lints::produce_ice::PRODUCE_ICE_INFO, #[cfg(feature = "internal")] crate::utils::internal_lints::unnecessary_def_path::UNNECESSARY_DEF_PATH_INFO, + crate::allow_attribute::ALLOW_ATTRIBUTE_INFO, crate::almost_complete_range::ALMOST_COMPLETE_RANGE_INFO, crate::approx_const::APPROX_CONSTANT_INFO, crate::as_conversions::AS_CONVERSIONS_INFO, diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 491732be208..51da5d1ba49 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -67,6 +67,7 @@ mod declared_lints; mod renamed_lints; // begin lints modules, do not remove this comment, it’s used in `update_lints` +mod allow_attribute; mod almost_complete_range; mod approx_const; mod as_conversions; @@ -933,6 +934,11 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|_| Box::new(missing_assert_message::MissingAssertMessage)); store.register_early_pass(|| Box::new(redundant_async_block::RedundantAsyncBlock)); store.register_late_pass(|_| Box::new(let_with_type_underscore::UnderscoreTyped)); + store.register_late_pass(|_| { + Box::new(allow_attribute::AllowAttribute { + lint_reasons_active: false, + }) + }); // add lints here, do not remove this comment, it's used in `new_lint` } diff --git a/tests/ui/allow_attribute.fixed b/tests/ui/allow_attribute.fixed new file mode 100644 index 00000000000..5f445a0bd96 --- /dev/null +++ b/tests/ui/allow_attribute.fixed @@ -0,0 +1,18 @@ +// run-rustfix +#![allow(unused)] +#![warn(clippy::allow_attribute)] +#![feature(lint_reasons)] + +fn main() {} + +// Using clippy::needless_borrow just as a placeholder, it isn't relevant. + +// Should lint +#[expect(dead_code)] +struct T1; + +struct T2; // Should not lint +#[deny(clippy::needless_borrow)] // Should not lint +struct T3; +#[warn(clippy::needless_borrow)] // Should not lint +struct T4; diff --git a/tests/ui/allow_attribute.rs b/tests/ui/allow_attribute.rs new file mode 100644 index 00000000000..36d2e3e27ab --- /dev/null +++ b/tests/ui/allow_attribute.rs @@ -0,0 +1,18 @@ +// run-rustfix +#![allow(unused)] +#![warn(clippy::allow_attribute)] +#![feature(lint_reasons)] + +fn main() {} + +// Using clippy::needless_borrow just as a placeholder, it isn't relevant. + +// Should lint +#[allow(dead_code)] +struct T1; + +struct T2; // Should not lint +#[deny(clippy::needless_borrow)] // Should not lint +struct T3; +#[warn(clippy::needless_borrow)] // Should not lint +struct T4; diff --git a/tests/ui/allow_attribute.stderr b/tests/ui/allow_attribute.stderr new file mode 100644 index 00000000000..6f90661577c --- /dev/null +++ b/tests/ui/allow_attribute.stderr @@ -0,0 +1,10 @@ +error: #[allow] attribute found + --> $DIR/allow_attribute.rs:11:1 + | +LL | #[allow(dead_code)] + | ^^^^^^^^^^^^^^^^^^^ help: replace it with: `#[expect(dead_code)]` + | + = note: `-D clippy::allow-attribute` implied by `-D warnings` + +error: aborting due to previous error + From 59568962aed2c4aff72360e4fbd3b9c04371dbec Mon Sep 17 00:00:00 2001 From: blyxyas Date: Sat, 11 Mar 2023 00:48:50 +0100 Subject: [PATCH 024/346] Fix code fragment --- clippy_lints/src/allow_attribute.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/clippy_lints/src/allow_attribute.rs b/clippy_lints/src/allow_attribute.rs index 2970d467f6f..805c804119a 100644 --- a/clippy_lints/src/allow_attribute.rs +++ b/clippy_lints/src/allow_attribute.rs @@ -21,6 +21,7 @@ declare_clippy_lint! { /// ``` /// Use instead: /// ```rust + /// # #![feature(lint_reasons)] /// #[expect(unused_mut)] /// fn foo() -> usize { /// let mut a = Vec::new(); From 1cf72183cfe0a29708130f59c79176128b06fcae Mon Sep 17 00:00:00 2001 From: blyxyas Date: Sat, 11 Mar 2023 01:08:03 +0100 Subject: [PATCH 025/346] Add ignore flag to code fragments --- clippy_lints/src/allow_attribute.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/allow_attribute.rs b/clippy_lints/src/allow_attribute.rs index 805c804119a..2258b973307 100644 --- a/clippy_lints/src/allow_attribute.rs +++ b/clippy_lints/src/allow_attribute.rs @@ -12,7 +12,7 @@ declare_clippy_lint! { /// ### Why is this bad? /// Using `#[allow]` isn't bad, but `#[expect]` may be preferred as it lints if the code **doesn't** produce a warning. /// ### Example - /// ```rust + /// ```rust,ignore /// #[allow(unused_mut)] /// fn foo() -> usize { /// let mut a = Vec::new(); @@ -20,7 +20,7 @@ declare_clippy_lint! { ///} /// ``` /// Use instead: - /// ```rust + /// ```rust,ignore /// # #![feature(lint_reasons)] /// #[expect(unused_mut)] /// fn foo() -> usize { From 2d572d4a9c20a11a3aa75a7fdd9168cc95c60d4c Mon Sep 17 00:00:00 2001 From: blyxyas Date: Sat, 11 Mar 2023 13:11:27 +0100 Subject: [PATCH 026/346] Replace list indexing for `.get` (fail-safe) --- clippy_lints/src/allow_attribute.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clippy_lints/src/allow_attribute.rs b/clippy_lints/src/allow_attribute.rs index 2258b973307..defd14da9ef 100644 --- a/clippy_lints/src/allow_attribute.rs +++ b/clippy_lints/src/allow_attribute.rs @@ -55,7 +55,8 @@ impl LateLintPass<'_> for AllowAttribute { .name == sym!(feature); if let ast::AttrKind::Normal(normal) = &attr.kind; if let Some(MetaItemKind::List(list)) = normal.item.meta_kind(); - if list[0].ident().unwrap().name == sym!(lint_reasons); + if let Some(symbol) = list.get(0); + if symbol.ident().unwrap().name == sym!(lint_reasons); then { self.lint_reasons_active = true; } From d65c9a5700454ab2a3bd81dccff610ad13855d14 Mon Sep 17 00:00:00 2001 From: blyxyas Date: Sat, 11 Mar 2023 21:30:34 +0100 Subject: [PATCH 027/346] Extend tests + improve description + general improvement --- clippy_lints/src/allow_attribute.rs | 84 ++++++++++++----------------- clippy_lints/src/lib.rs | 6 +-- tests/ui/allow_attribute.fixed | 7 +++ tests/ui/allow_attribute.rs | 7 +++ tests/ui/allow_attribute.stderr | 12 +++-- 5 files changed, 59 insertions(+), 57 deletions(-) diff --git a/clippy_lints/src/allow_attribute.rs b/clippy_lints/src/allow_attribute.rs index defd14da9ef..28fc45d0554 100644 --- a/clippy_lints/src/allow_attribute.rs +++ b/clippy_lints/src/allow_attribute.rs @@ -1,16 +1,27 @@ -use ast::{AttrStyle, MetaItemKind}; -use clippy_utils::{diagnostics::span_lint_and_sugg, source::snippet}; +use ast::AttrStyle; +use clippy_utils::diagnostics::span_lint_and_sugg; use rustc_ast as ast; use rustc_errors::Applicability; use rustc_lint::{LateContext, LateLintPass}; -use rustc_session::{declare_tool_lint, impl_lint_pass}; -use rustc_span::{symbol::Ident, BytePos}; +use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// ### What it does - /// Detects uses of the `#[allow]` attribute and suggests to replace it with the new `#[expect]` attribute implemented by `#![feature(lint_reasons)]` ([RFC 2383](https://rust-lang.github.io/rfcs/2383-lint-reasons.html)) + /// Detects uses of the `#[allow]` attribute and suggests replacing it with + /// the `#[expect]` (See [RFC 2383](https://rust-lang.github.io/rfcs/2383-lint-reasons.html)) + /// + /// The expect attribute is still unstable and requires the `lint_reasons` + /// on nightly. It can be enabled by adding `#![feature(lint_reasons)]` to + /// the crate root. + /// + /// This lint only warns outer attributes (`#[allow]`), as inner attributes + /// (`#![allow]`) are usually used to enable or disable lints on a global scale. + /// /// ### Why is this bad? - /// Using `#[allow]` isn't bad, but `#[expect]` may be preferred as it lints if the code **doesn't** produce a warning. + /// + /// `#[expect]` attributes suppress the lint emission, but emit a warning, if + /// the expectation is unfulfilled. This can be useful to be notified when the + /// lint is no longer triggered. + /// /// ### Example /// ```rust,ignore /// #[allow(unused_mut)] @@ -34,59 +45,34 @@ declare_clippy_lint! { "`#[allow]` will not trigger if a warning isn't found. `#[expect]` triggers if there are no warnings." } -pub struct AllowAttribute { - pub lint_reasons_active: bool, -} - -impl_lint_pass!(AllowAttribute => [ALLOW_ATTRIBUTE]); +declare_lint_pass!(AllowAttribute => [ALLOW_ATTRIBUTE]); impl LateLintPass<'_> for AllowAttribute { // Separate each crate's features. - fn check_crate_post(&mut self, _: &LateContext<'_>) { - self.lint_reasons_active = false; - } fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &ast::Attribute) { - // Check inner attributes - - if_chain! { - if let AttrStyle::Inner = attr.style; - if attr.ident() - .unwrap_or(Ident::with_dummy_span(sym!(empty))) // Will not trigger if doesn't have an ident. - .name == sym!(feature); - if let ast::AttrKind::Normal(normal) = &attr.kind; - if let Some(MetaItemKind::List(list)) = normal.item.meta_kind(); - if let Some(symbol) = list.get(0); - if symbol.ident().unwrap().name == sym!(lint_reasons); - then { - self.lint_reasons_active = true; - } - } - - // Check outer attributes - if_chain! { + if cx.tcx.features().lint_reasons; if let AttrStyle::Outer = attr.style; - if attr.ident() - .unwrap_or(Ident::with_dummy_span(sym!(empty))) // Will not trigger if doesn't have an ident. - .name == sym!(allow); - if self.lint_reasons_active; + if let Some(ident) = attr.ident(); + if ident.name == rustc_span::symbol::sym::allow; then { span_lint_and_sugg( cx, ALLOW_ATTRIBUTE, - attr.span, + ident.span, "#[allow] attribute found", - "replace it with", - format!("#[expect{})]", snippet( - cx, - attr.ident().unwrap().span - .with_lo( - attr.ident().unwrap().span.hi() + BytePos(2) // Cut [( - ) - .with_hi( - attr.meta().unwrap().span.hi() - BytePos(2) // Cut )] - ) - , "...")), Applicability::MachineApplicable); + "replace it with", "expect".into() + // format!("expect{}", snippet( + // cx, + // ident.span + // .with_lo( + // ident.span.hi() + BytePos(2) // Cut *( + // ) + // .with_hi( + // attr.meta().unwrap().span.hi() - BytePos(1) // Cut ) + // ) + // , "...")) + , Applicability::MachineApplicable); } } } diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 51da5d1ba49..a3c65a69c99 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -934,11 +934,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|_| Box::new(missing_assert_message::MissingAssertMessage)); store.register_early_pass(|| Box::new(redundant_async_block::RedundantAsyncBlock)); store.register_late_pass(|_| Box::new(let_with_type_underscore::UnderscoreTyped)); - store.register_late_pass(|_| { - Box::new(allow_attribute::AllowAttribute { - lint_reasons_active: false, - }) - }); + store.register_late_pass(|_| Box::new(allow_attribute::AllowAttribute)); // add lints here, do not remove this comment, it's used in `new_lint` } diff --git a/tests/ui/allow_attribute.fixed b/tests/ui/allow_attribute.fixed index 5f445a0bd96..01759ced09d 100644 --- a/tests/ui/allow_attribute.fixed +++ b/tests/ui/allow_attribute.fixed @@ -16,3 +16,10 @@ struct T2; // Should not lint struct T3; #[warn(clippy::needless_borrow)] // Should not lint struct T4; +// `panic = "unwind"` should always be true +#[cfg_attr(panic = "unwind", expect(dead_code))] +struct CfgT; + +fn ignore_inner_attr() { + #![allow(unused)] // Should not lint +} diff --git a/tests/ui/allow_attribute.rs b/tests/ui/allow_attribute.rs index 36d2e3e27ab..b8e341fe9e4 100644 --- a/tests/ui/allow_attribute.rs +++ b/tests/ui/allow_attribute.rs @@ -16,3 +16,10 @@ struct T2; // Should not lint struct T3; #[warn(clippy::needless_borrow)] // Should not lint struct T4; +// `panic = "unwind"` should always be true +#[cfg_attr(panic = "unwind", allow(dead_code))] +struct CfgT; + +fn ignore_inner_attr() { + #![allow(unused)] // Should not lint +} diff --git a/tests/ui/allow_attribute.stderr b/tests/ui/allow_attribute.stderr index 6f90661577c..58b7323b068 100644 --- a/tests/ui/allow_attribute.stderr +++ b/tests/ui/allow_attribute.stderr @@ -1,10 +1,16 @@ error: #[allow] attribute found - --> $DIR/allow_attribute.rs:11:1 + --> $DIR/allow_attribute.rs:11:3 | LL | #[allow(dead_code)] - | ^^^^^^^^^^^^^^^^^^^ help: replace it with: `#[expect(dead_code)]` + | ^^^^^ help: replace it with: `expect` | = note: `-D clippy::allow-attribute` implied by `-D warnings` -error: aborting due to previous error +error: #[allow] attribute found + --> $DIR/allow_attribute.rs:20:30 + | +LL | #[cfg_attr(panic = "unwind", allow(dead_code))] + | ^^^^^ help: replace it with: `expect` + +error: aborting due to 2 previous errors From 213a22efb94ab62d7458501c5ab9e303b222e6a2 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Mon, 27 Feb 2023 13:07:44 +0000 Subject: [PATCH 028/346] Remove uses of `box_syntax` in rustc and tools --- tests/ui/boxed_local.rs | 35 +++++++------------- tests/ui/boxed_local.stderr | 8 ++--- tests/ui/no_effect.rs | 3 +- tests/ui/no_effect.stderr | 38 ++++++++++------------ tests/ui/unnecessary_operation.fixed | 2 -- tests/ui/unnecessary_operation.rs | 2 -- tests/ui/unnecessary_operation.stderr | 46 ++++++++++++--------------- 7 files changed, 53 insertions(+), 81 deletions(-) diff --git a/tests/ui/boxed_local.rs b/tests/ui/boxed_local.rs index 4639f00a8d8..79b6d33fc77 100644 --- a/tests/ui/boxed_local.rs +++ b/tests/ui/boxed_local.rs @@ -1,4 +1,3 @@ -#![feature(box_syntax)] #![feature(lint_reasons)] #![allow( clippy::borrowed_box, @@ -34,7 +33,7 @@ fn ok_box_trait(boxed_trait: &Box) { } fn warn_call() { - let x = box A; + let x = Box::new(A); x.foo(); } @@ -43,41 +42,41 @@ fn warn_arg(x: Box) { } fn nowarn_closure_arg() { - let x = Some(box A); + let x = Some(Box::new(A)); x.map_or((), |x| take_ref(&x)); } fn warn_rename_call() { - let x = box A; + let x = Box::new(A); let y = x; y.foo(); // via autoderef } fn warn_notuse() { - let bz = box A; + let bz = Box::new(A); } fn warn_pass() { - let bz = box A; + let bz = Box::new(A); take_ref(&bz); // via deref coercion } fn nowarn_return() -> Box { - box A // moved out, "escapes" + Box::new(A) // moved out, "escapes" } fn nowarn_move() { - let bx = box A; + let bx = Box::new(A); drop(bx) // moved in, "escapes" } fn nowarn_call() { - let bx = box A; + let bx = Box::new(A); bx.clone(); // method only available to Box, not via autoderef } fn nowarn_pass() { - let bx = box A; + let bx = Box::new(A); take_box(&bx); // fn needs &Box } @@ -86,30 +85,20 @@ fn take_ref(x: &A) {} fn nowarn_ref_take() { // false positive, should actually warn - let x = box A; + let x = Box::new(A); let y = &x; take_box(y); } fn nowarn_match() { - let x = box A; // moved into a match + let x = Box::new(A); // moved into a match match x { y => drop(y), } } fn warn_match() { - let x = box A; - match &x { - // not moved - y => (), - } -} - -fn nowarn_large_array() { - // should not warn, is large array - // and should not be on stack - let x = box [1; 10000]; + let x = Box::new(A); match &x { // not moved y => (), diff --git a/tests/ui/boxed_local.stderr b/tests/ui/boxed_local.stderr index 9036529f39c..10d78fbc0ab 100644 --- a/tests/ui/boxed_local.stderr +++ b/tests/ui/boxed_local.stderr @@ -1,5 +1,5 @@ error: local variable doesn't need to be boxed here - --> $DIR/boxed_local.rs:41:13 + --> $DIR/boxed_local.rs:40:13 | LL | fn warn_arg(x: Box) { | ^ @@ -7,19 +7,19 @@ LL | fn warn_arg(x: Box) { = note: `-D clippy::boxed-local` implied by `-D warnings` error: local variable doesn't need to be boxed here - --> $DIR/boxed_local.rs:132:12 + --> $DIR/boxed_local.rs:121:12 | LL | pub fn new(_needs_name: Box>) -> () {} | ^^^^^^^^^^^ error: local variable doesn't need to be boxed here - --> $DIR/boxed_local.rs:196:44 + --> $DIR/boxed_local.rs:185:44 | LL | fn default_impl_x(self: Box, x: Box) -> u32 { | ^ error: local variable doesn't need to be boxed here - --> $DIR/boxed_local.rs:203:16 + --> $DIR/boxed_local.rs:192:16 | LL | fn foo(x: Box) {} | ^ diff --git a/tests/ui/no_effect.rs b/tests/ui/no_effect.rs index f08eb092e6b..ec8a5aa28c5 100644 --- a/tests/ui/no_effect.rs +++ b/tests/ui/no_effect.rs @@ -1,4 +1,4 @@ -#![feature(box_syntax, fn_traits, unboxed_closures)] +#![feature(fn_traits, unboxed_closures)] #![warn(clippy::no_effect_underscore_binding)] #![allow(dead_code, path_statements)] #![allow(clippy::deref_addrof, clippy::redundant_field_names, clippy::uninlined_format_args)] @@ -102,7 +102,6 @@ fn main() { *&42; &6; (5, 6, 7); - box 42; ..; 5..; ..5; diff --git a/tests/ui/no_effect.stderr b/tests/ui/no_effect.stderr index 6a1e636f9a6..92f6dbfbdba 100644 --- a/tests/ui/no_effect.stderr +++ b/tests/ui/no_effect.stderr @@ -81,83 +81,77 @@ LL | (5, 6, 7); error: statement with no effect --> $DIR/no_effect.rs:105:5 | -LL | box 42; - | ^^^^^^^ - -error: statement with no effect - --> $DIR/no_effect.rs:106:5 - | LL | ..; | ^^^ error: statement with no effect - --> $DIR/no_effect.rs:107:5 + --> $DIR/no_effect.rs:106:5 | LL | 5..; | ^^^^ error: statement with no effect - --> $DIR/no_effect.rs:108:5 + --> $DIR/no_effect.rs:107:5 | LL | ..5; | ^^^^ error: statement with no effect - --> $DIR/no_effect.rs:109:5 + --> $DIR/no_effect.rs:108:5 | LL | 5..6; | ^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:110:5 + --> $DIR/no_effect.rs:109:5 | LL | 5..=6; | ^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:111:5 + --> $DIR/no_effect.rs:110:5 | LL | [42, 55]; | ^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:112:5 + --> $DIR/no_effect.rs:111:5 | LL | [42, 55][1]; | ^^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:113:5 + --> $DIR/no_effect.rs:112:5 | LL | (42, 55).1; | ^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:114:5 + --> $DIR/no_effect.rs:113:5 | LL | [42; 55]; | ^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:115:5 + --> $DIR/no_effect.rs:114:5 | LL | [42; 55][13]; | ^^^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:117:5 + --> $DIR/no_effect.rs:116:5 | LL | || x += 5; | ^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:119:5 + --> $DIR/no_effect.rs:118:5 | LL | FooString { s: s }; | ^^^^^^^^^^^^^^^^^^^ error: binding to `_` prefixed variable with no side-effect - --> $DIR/no_effect.rs:120:5 + --> $DIR/no_effect.rs:119:5 | LL | let _unused = 1; | ^^^^^^^^^^^^^^^^ @@ -165,22 +159,22 @@ LL | let _unused = 1; = note: `-D clippy::no-effect-underscore-binding` implied by `-D warnings` error: binding to `_` prefixed variable with no side-effect - --> $DIR/no_effect.rs:121:5 + --> $DIR/no_effect.rs:120:5 | LL | let _penguin = || println!("Some helpful closure"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: binding to `_` prefixed variable with no side-effect - --> $DIR/no_effect.rs:122:5 + --> $DIR/no_effect.rs:121:5 | LL | let _duck = Struct { field: 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: binding to `_` prefixed variable with no side-effect - --> $DIR/no_effect.rs:123:5 + --> $DIR/no_effect.rs:122:5 | LL | let _cat = [2, 4, 6, 8][2]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 30 previous errors +error: aborting due to 29 previous errors diff --git a/tests/ui/unnecessary_operation.fixed b/tests/ui/unnecessary_operation.fixed index d37163570ab..65d9c910b82 100644 --- a/tests/ui/unnecessary_operation.fixed +++ b/tests/ui/unnecessary_operation.fixed @@ -1,6 +1,5 @@ // run-rustfix -#![feature(box_syntax)] #![allow(clippy::deref_addrof, dead_code, unused, clippy::no_effect)] #![warn(clippy::unnecessary_operation)] @@ -59,7 +58,6 @@ fn main() { 5;6;get_number(); get_number(); get_number(); - get_number(); 5;get_number(); 42;get_number(); assert!([42, 55].len() > get_usize()); diff --git a/tests/ui/unnecessary_operation.rs b/tests/ui/unnecessary_operation.rs index a14fd4bca0e..4e2acd59f04 100644 --- a/tests/ui/unnecessary_operation.rs +++ b/tests/ui/unnecessary_operation.rs @@ -1,6 +1,5 @@ // run-rustfix -#![feature(box_syntax)] #![allow(clippy::deref_addrof, dead_code, unused, clippy::no_effect)] #![warn(clippy::unnecessary_operation)] @@ -57,7 +56,6 @@ fn main() { *&get_number(); &get_number(); (5, 6, get_number()); - box get_number(); get_number()..; ..get_number(); 5..get_number(); diff --git a/tests/ui/unnecessary_operation.stderr b/tests/ui/unnecessary_operation.stderr index f66d08ecb82..44cf2e01ff7 100644 --- a/tests/ui/unnecessary_operation.stderr +++ b/tests/ui/unnecessary_operation.stderr @@ -1,5 +1,5 @@ error: unnecessary operation - --> $DIR/unnecessary_operation.rs:51:5 + --> $DIR/unnecessary_operation.rs:50:5 | LL | Tuple(get_number()); | ^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` @@ -7,109 +7,103 @@ LL | Tuple(get_number()); = note: `-D clippy::unnecessary-operation` implied by `-D warnings` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:52:5 + --> $DIR/unnecessary_operation.rs:51:5 | LL | Struct { field: get_number() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:53:5 + --> $DIR/unnecessary_operation.rs:52:5 | LL | Struct { ..get_struct() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_struct();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:54:5 + --> $DIR/unnecessary_operation.rs:53:5 | LL | Enum::Tuple(get_number()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:55:5 + --> $DIR/unnecessary_operation.rs:54:5 | LL | Enum::Struct { field: get_number() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:56:5 + --> $DIR/unnecessary_operation.rs:55:5 | LL | 5 + get_number(); | ^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `5;get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:57:5 + --> $DIR/unnecessary_operation.rs:56:5 | LL | *&get_number(); | ^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:58:5 + --> $DIR/unnecessary_operation.rs:57:5 | LL | &get_number(); | ^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:59:5 + --> $DIR/unnecessary_operation.rs:58:5 | LL | (5, 6, get_number()); | ^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `5;6;get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:60:5 - | -LL | box get_number(); - | ^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` - -error: unnecessary operation - --> $DIR/unnecessary_operation.rs:61:5 + --> $DIR/unnecessary_operation.rs:59:5 | LL | get_number()..; | ^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:62:5 + --> $DIR/unnecessary_operation.rs:60:5 | LL | ..get_number(); | ^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:63:5 + --> $DIR/unnecessary_operation.rs:61:5 | LL | 5..get_number(); | ^^^^^^^^^^^^^^^^ help: statement can be reduced to: `5;get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:64:5 + --> $DIR/unnecessary_operation.rs:62:5 | LL | [42, get_number()]; | ^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `42;get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:65:5 + --> $DIR/unnecessary_operation.rs:63:5 | LL | [42, 55][get_usize()]; | ^^^^^^^^^^^^^^^^^^^^^^ help: statement can be written as: `assert!([42, 55].len() > get_usize());` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:66:5 + --> $DIR/unnecessary_operation.rs:64:5 | LL | (42, get_number()).1; | ^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `42;get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:67:5 + --> $DIR/unnecessary_operation.rs:65:5 | LL | [get_number(); 55]; | ^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:68:5 + --> $DIR/unnecessary_operation.rs:66:5 | LL | [42; 55][get_usize()]; | ^^^^^^^^^^^^^^^^^^^^^^ help: statement can be written as: `assert!([42; 55].len() > get_usize());` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:69:5 + --> $DIR/unnecessary_operation.rs:67:5 | LL | / { LL | | get_number() @@ -117,12 +111,12 @@ LL | | }; | |______^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:72:5 + --> $DIR/unnecessary_operation.rs:70:5 | LL | / FooString { LL | | s: String::from("blah"), LL | | }; | |______^ help: statement can be reduced to: `String::from("blah");` -error: aborting due to 20 previous errors +error: aborting due to 19 previous errors From 15f24234c874df0f5225229a6fd5c0514f2c7ceb Mon Sep 17 00:00:00 2001 From: clubby789 Date: Mon, 27 Feb 2023 13:17:29 +0000 Subject: [PATCH 029/346] Remove `box_syntax` from AST and use in tools --- clippy_lints/src/suspicious_operation_groupings.rs | 3 +-- clippy_utils/src/ast_utils.rs | 2 +- clippy_utils/src/sugg.rs | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/suspicious_operation_groupings.rs b/clippy_lints/src/suspicious_operation_groupings.rs index e111c7d2291..8aa47b62ebf 100644 --- a/clippy_lints/src/suspicious_operation_groupings.rs +++ b/clippy_lints/src/suspicious_operation_groupings.rs @@ -596,8 +596,7 @@ fn ident_difference_expr_with_base_location( | (MethodCall(_), MethodCall(_)) | (Call(_, _), Call(_, _)) | (ConstBlock(_), ConstBlock(_)) - | (Array(_), Array(_)) - | (Box(_), Box(_)) => { + | (Array(_), Array(_)) => { // keep going }, _ => { diff --git a/clippy_utils/src/ast_utils.rs b/clippy_utils/src/ast_utils.rs index d82098523e3..809d654603a 100644 --- a/clippy_utils/src/ast_utils.rs +++ b/clippy_utils/src/ast_utils.rs @@ -143,7 +143,7 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool { (Paren(l), _) => eq_expr(l, r), (_, Paren(r)) => eq_expr(l, r), (Err, Err) => true, - (Box(l), Box(r)) | (Try(l), Try(r)) | (Await(l), Await(r)) => eq_expr(l, r), + (Try(l), Try(r)) | (Await(l), Await(r)) => eq_expr(l, r), (Array(l), Array(r)) => over(l, r, |l, r| eq_expr(l, r)), (Tup(l), Tup(r)) => over(l, r, |l, r| eq_expr(l, r)), (Repeat(le, ls), Repeat(re, rs)) => eq_expr(le, re) && eq_expr(&ls.value, &rs.value), diff --git a/clippy_utils/src/sugg.rs b/clippy_utils/src/sugg.rs index 07feadca2b0..85bf28b708b 100644 --- a/clippy_utils/src/sugg.rs +++ b/clippy_utils/src/sugg.rs @@ -188,7 +188,6 @@ impl<'a> Sugg<'a> { match expr.kind { _ if expr.span.ctxt() != ctxt => Sugg::NonParen(snippet_with_context(cx, expr.span, ctxt, default, app).0), ast::ExprKind::AddrOf(..) - | ast::ExprKind::Box(..) | ast::ExprKind::Closure { .. } | ast::ExprKind::If(..) | ast::ExprKind::Let(..) From 1c7048d7852937099320091900e25061fde5479f Mon Sep 17 00:00:00 2001 From: Jason Newcomb Date: Tue, 7 Mar 2023 09:40:55 -0500 Subject: [PATCH 030/346] Add utility macros to help with writing tests. --- tests/ui/almost_complete_range.fixed | 49 +- tests/ui/almost_complete_range.rs | 49 +- tests/ui/almost_complete_range.stderr | 93 ++-- tests/ui/as_conversions.rs | 13 +- tests/ui/as_conversions.stderr | 6 +- tests/ui/auxiliary/doc_unsafe_macros.rs | 16 - tests/ui/auxiliary/implicit_hasher_macros.rs | 6 - tests/ui/auxiliary/macro_rules.rs | 141 ------ tests/ui/auxiliary/macro_use_helper.rs | 2 +- tests/ui/auxiliary/proc_macro_with_span.rs | 32 -- tests/ui/auxiliary/proc_macros.rs | 474 ++++++++++++++++++ .../auxiliary/helper.rs | 2 +- tests/ui/crashes/ice-10148.rs | 6 +- tests/ui/default_numeric_fallback_f64.fixed | 17 +- tests/ui/default_numeric_fallback_f64.rs | 17 +- tests/ui/default_numeric_fallback_f64.stderr | 11 +- tests/ui/default_numeric_fallback_i32.fixed | 17 +- tests/ui/default_numeric_fallback_i32.rs | 17 +- tests/ui/default_numeric_fallback_i32.stderr | 11 +- tests/ui/default_trait_access.fixed | 6 +- tests/ui/default_trait_access.rs | 6 +- tests/ui/deref_addrof.fixed | 24 +- tests/ui/deref_addrof.rs | 24 +- tests/ui/deref_addrof.stderr | 38 +- tests/ui/deref_addrof_macro.rs | 15 +- tests/ui/doc_unsafe.rs | 12 +- tests/ui/empty_loop.rs | 15 +- tests/ui/equatable_if_let.fixed | 16 +- tests/ui/equatable_if_let.rs | 16 +- tests/ui/equatable_if_let.stderr | 32 +- tests/ui/field_reassign_with_default.rs | 36 +- tests/ui/field_reassign_with_default.stderr | 44 +- tests/ui/implicit_hasher.rs | 25 +- tests/ui/implicit_hasher.stderr | 55 +- .../ui/inconsistent_struct_constructor.fixed | 21 +- tests/ui/inconsistent_struct_constructor.rs | 21 +- .../ui/inconsistent_struct_constructor.stderr | 4 +- tests/ui/large_enum_variant.rs | 13 +- tests/ui/macro_use_imports.fixed | 4 +- tests/ui/macro_use_imports.rs | 2 +- tests/ui/macro_use_imports.stderr | 2 +- tests/ui/macro_use_imports_expect.rs | 2 +- tests/ui/manual_rem_euclid.fixed | 24 +- tests/ui/manual_rem_euclid.rs | 24 +- tests/ui/manual_rem_euclid.stderr | 17 +- tests/ui/mem_replace_macro.rs | 23 +- tests/ui/mem_replace_macro.stderr | 11 +- .../ui/missing_const_for_fn/cant_be_const.rs | 6 +- tests/ui/missing_doc.rs | 6 +- tests/ui/missing_doc_impl.rs | 6 +- tests/ui/mistyped_literal_suffix.fixed | 6 +- tests/ui/mistyped_literal_suffix.rs | 6 +- tests/ui/multiple_unsafe_ops_per_block.rs | 11 +- tests/ui/multiple_unsafe_ops_per_block.stderr | 18 +- tests/ui/must_use_unit.fixed | 11 +- tests/ui/must_use_unit.rs | 11 +- tests/ui/mut_mut.rs | 11 +- tests/ui/mut_mut.stderr | 25 +- tests/ui/needless_late_init.fixed | 36 +- tests/ui/needless_late_init.rs | 36 +- tests/ui/needless_late_init.stderr | 32 +- tests/ui/needless_lifetimes.fixed | 41 +- tests/ui/needless_lifetimes.rs | 41 +- tests/ui/needless_lifetimes.stderr | 15 +- tests/ui/option_env_unwrap.rs | 24 +- tests/ui/option_env_unwrap.stderr | 42 +- tests/ui/ptr_as_ptr.fixed | 16 +- tests/ui/ptr_as_ptr.rs | 16 +- tests/ui/ptr_as_ptr.stderr | 25 +- tests/ui/single_match_else.rs | 6 +- tests/ui/string_add.rs | 11 +- tests/ui/toplevel_ref_arg.fixed | 24 +- tests/ui/toplevel_ref_arg.rs | 24 +- tests/ui/toplevel_ref_arg.stderr | 21 +- tests/ui/toplevel_ref_arg_non_rustfix.rs | 22 +- tests/ui/toplevel_ref_arg_non_rustfix.stderr | 7 +- tests/ui/try_err.fixed | 67 +-- tests/ui/try_err.rs | 67 +-- tests/ui/try_err.stderr | 32 +- tests/ui/uninlined_format_args.fixed | 6 +- tests/ui/uninlined_format_args.rs | 6 +- tests/ui/unit_arg.rs | 6 +- tests/ui/unnecessary_lazy_eval.fixed | 6 +- tests/ui/unnecessary_lazy_eval.rs | 6 +- tests/ui/unnecessary_unsafety_doc.rs | 12 +- tests/ui/unnecessary_unsafety_doc.stderr | 2 +- 86 files changed, 1179 insertions(+), 1098 deletions(-) delete mode 100644 tests/ui/auxiliary/doc_unsafe_macros.rs delete mode 100644 tests/ui/auxiliary/implicit_hasher_macros.rs delete mode 100644 tests/ui/auxiliary/proc_macro_with_span.rs create mode 100644 tests/ui/auxiliary/proc_macros.rs diff --git a/tests/ui/almost_complete_range.fixed b/tests/ui/almost_complete_range.fixed index 6046addf719..a4bf7fe18d5 100644 --- a/tests/ui/almost_complete_range.fixed +++ b/tests/ui/almost_complete_range.fixed @@ -1,6 +1,6 @@ // run-rustfix // edition:2018 -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![feature(exclusive_range_pattern)] #![feature(stmt_expr_attributes)] @@ -9,33 +9,10 @@ #![allow(clippy::needless_parens_on_range_literals)] #![allow(clippy::double_parens)] -#[macro_use] -extern crate macro_rules; - -macro_rules! a { - () => { - 'a' - }; -} -macro_rules! A { - () => { - 'A' - }; -} -macro_rules! zero { - () => { - '0' - }; -} - -macro_rules! b { - () => { - let _ = 'a'..='z'; - let _ = 'A'..='Z'; - let _ = '0'..='9'; - }; -} +extern crate proc_macros; +use proc_macros::{external, inline_macros}; +#[inline_macros] fn main() { #[rustfmt::skip] { @@ -56,9 +33,9 @@ fn main() { let _ = b'B'..b'Z'; let _ = b'1'..b'9'; - let _ = a!()..='z'; - let _ = A!()..='Z'; - let _ = zero!()..='9'; + let _ = inline!('a')..='z'; + let _ = inline!('A')..='Z'; + let _ = inline!('0')..='9'; let _ = match 0u8 { b'a'..=b'z' if true => 1, @@ -80,8 +57,16 @@ fn main() { _ => 7, }; - almost_complete_range!(); - b!(); + external!( + let _ = 'a'..'z'; + let _ = 'A'..'Z'; + let _ = '0'..'9'; + ); + inline!( + let _ = 'a'..='z'; + let _ = 'A'..='Z'; + let _ = '0'..='9'; + ); } #[clippy::msrv = "1.25"] diff --git a/tests/ui/almost_complete_range.rs b/tests/ui/almost_complete_range.rs index ae7e07ab872..8237c3a1361 100644 --- a/tests/ui/almost_complete_range.rs +++ b/tests/ui/almost_complete_range.rs @@ -1,6 +1,6 @@ // run-rustfix // edition:2018 -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![feature(exclusive_range_pattern)] #![feature(stmt_expr_attributes)] @@ -9,33 +9,10 @@ #![allow(clippy::needless_parens_on_range_literals)] #![allow(clippy::double_parens)] -#[macro_use] -extern crate macro_rules; - -macro_rules! a { - () => { - 'a' - }; -} -macro_rules! A { - () => { - 'A' - }; -} -macro_rules! zero { - () => { - '0' - }; -} - -macro_rules! b { - () => { - let _ = 'a'..'z'; - let _ = 'A'..'Z'; - let _ = '0'..'9'; - }; -} +extern crate proc_macros; +use proc_macros::{external, inline_macros}; +#[inline_macros] fn main() { #[rustfmt::skip] { @@ -56,9 +33,9 @@ fn main() { let _ = b'B'..b'Z'; let _ = b'1'..b'9'; - let _ = a!()..'z'; - let _ = A!()..'Z'; - let _ = zero!()..'9'; + let _ = inline!('a')..'z'; + let _ = inline!('A')..'Z'; + let _ = inline!('0')..'9'; let _ = match 0u8 { b'a'..b'z' if true => 1, @@ -80,8 +57,16 @@ fn main() { _ => 7, }; - almost_complete_range!(); - b!(); + external!( + let _ = 'a'..'z'; + let _ = 'A'..'Z'; + let _ = '0'..'9'; + ); + inline!( + let _ = 'a'..'z'; + let _ = 'A'..'Z'; + let _ = '0'..'9'; + ); } #[clippy::msrv = "1.25"] diff --git a/tests/ui/almost_complete_range.stderr b/tests/ui/almost_complete_range.stderr index a7a53287850..34521c13ab3 100644 --- a/tests/ui/almost_complete_range.stderr +++ b/tests/ui/almost_complete_range.stderr @@ -1,5 +1,5 @@ error: almost complete ascii range - --> $DIR/almost_complete_range.rs:42:17 + --> $DIR/almost_complete_range.rs:19:17 | LL | let _ = ('a') ..'z'; | ^^^^^^--^^^ @@ -9,7 +9,7 @@ LL | let _ = ('a') ..'z'; = note: `-D clippy::almost-complete-range` implied by `-D warnings` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:43:17 + --> $DIR/almost_complete_range.rs:20:17 | LL | let _ = 'A' .. ('Z'); | ^^^^--^^^^^^ @@ -17,7 +17,7 @@ LL | let _ = 'A' .. ('Z'); | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:44:17 + --> $DIR/almost_complete_range.rs:21:17 | LL | let _ = ((('0'))) .. ('9'); | ^^^^^^^^^^--^^^^^^ @@ -25,7 +25,7 @@ LL | let _ = ((('0'))) .. ('9'); | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:51:13 + --> $DIR/almost_complete_range.rs:28:13 | LL | let _ = (b'a')..(b'z'); | ^^^^^^--^^^^^^ @@ -33,7 +33,7 @@ LL | let _ = (b'a')..(b'z'); | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:52:13 + --> $DIR/almost_complete_range.rs:29:13 | LL | let _ = b'A'..b'Z'; | ^^^^--^^^^ @@ -41,7 +41,7 @@ LL | let _ = b'A'..b'Z'; | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:53:13 + --> $DIR/almost_complete_range.rs:30:13 | LL | let _ = b'0'..b'9'; | ^^^^--^^^^ @@ -49,31 +49,31 @@ LL | let _ = b'0'..b'9'; | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:59:13 + --> $DIR/almost_complete_range.rs:36:13 | -LL | let _ = a!()..'z'; - | ^^^^--^^^ - | | - | help: use an inclusive range: `..=` +LL | let _ = inline!('a')..'z'; + | ^^^^^^^^^^^^--^^^ + | | + | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:60:13 + --> $DIR/almost_complete_range.rs:37:13 | -LL | let _ = A!()..'Z'; - | ^^^^--^^^ - | | - | help: use an inclusive range: `..=` +LL | let _ = inline!('A')..'Z'; + | ^^^^^^^^^^^^--^^^ + | | + | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:61:13 + --> $DIR/almost_complete_range.rs:38:13 | -LL | let _ = zero!()..'9'; - | ^^^^^^^--^^^ - | | - | help: use an inclusive range: `..=` +LL | let _ = inline!('0')..'9'; + | ^^^^^^^^^^^^--^^^ + | | + | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:64:9 + --> $DIR/almost_complete_range.rs:41:9 | LL | b'a'..b'z' if true => 1, | ^^^^--^^^^ @@ -81,7 +81,7 @@ LL | b'a'..b'z' if true => 1, | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:65:9 + --> $DIR/almost_complete_range.rs:42:9 | LL | b'A'..b'Z' if true => 2, | ^^^^--^^^^ @@ -89,7 +89,7 @@ LL | b'A'..b'Z' if true => 2, | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:66:9 + --> $DIR/almost_complete_range.rs:43:9 | LL | b'0'..b'9' if true => 3, | ^^^^--^^^^ @@ -97,7 +97,7 @@ LL | b'0'..b'9' if true => 3, | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:74:9 + --> $DIR/almost_complete_range.rs:51:9 | LL | 'a'..'z' if true => 1, | ^^^--^^^ @@ -105,7 +105,7 @@ LL | 'a'..'z' if true => 1, | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:75:9 + --> $DIR/almost_complete_range.rs:52:9 | LL | 'A'..'Z' if true => 2, | ^^^--^^^ @@ -113,7 +113,7 @@ LL | 'A'..'Z' if true => 2, | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:76:9 + --> $DIR/almost_complete_range.rs:53:9 | LL | '0'..'9' if true => 3, | ^^^--^^^ @@ -121,46 +121,37 @@ LL | '0'..'9' if true => 3, | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:33:17 + --> $DIR/almost_complete_range.rs:66:17 | LL | let _ = 'a'..'z'; | ^^^--^^^ | | | help: use an inclusive range: `..=` -... -LL | b!(); - | ---- in this macro invocation | - = note: this error originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: almost complete ascii range - --> $DIR/almost_complete_range.rs:34:17 + --> $DIR/almost_complete_range.rs:67:17 | LL | let _ = 'A'..'Z'; | ^^^--^^^ | | | help: use an inclusive range: `..=` -... -LL | b!(); - | ---- in this macro invocation | - = note: this error originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: almost complete ascii range - --> $DIR/almost_complete_range.rs:35:17 + --> $DIR/almost_complete_range.rs:68:17 | LL | let _ = '0'..'9'; | ^^^--^^^ | | | help: use an inclusive range: `..=` -... -LL | b!(); - | ---- in this macro invocation | - = note: this error originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: almost complete ascii range - --> $DIR/almost_complete_range.rs:90:9 + --> $DIR/almost_complete_range.rs:75:9 | LL | 'a'..'z' => 1, | ^^^--^^^ @@ -168,7 +159,7 @@ LL | 'a'..'z' => 1, | help: use an inclusive range: `...` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:91:9 + --> $DIR/almost_complete_range.rs:76:9 | LL | 'A'..'Z' => 2, | ^^^--^^^ @@ -176,7 +167,7 @@ LL | 'A'..'Z' => 2, | help: use an inclusive range: `...` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:92:9 + --> $DIR/almost_complete_range.rs:77:9 | LL | '0'..'9' => 3, | ^^^--^^^ @@ -184,7 +175,7 @@ LL | '0'..'9' => 3, | help: use an inclusive range: `...` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:99:13 + --> $DIR/almost_complete_range.rs:84:13 | LL | let _ = 'a'..'z'; | ^^^--^^^ @@ -192,7 +183,7 @@ LL | let _ = 'a'..'z'; | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:100:13 + --> $DIR/almost_complete_range.rs:85:13 | LL | let _ = 'A'..'Z'; | ^^^--^^^ @@ -200,7 +191,7 @@ LL | let _ = 'A'..'Z'; | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:101:13 + --> $DIR/almost_complete_range.rs:86:13 | LL | let _ = '0'..'9'; | ^^^--^^^ @@ -208,7 +199,7 @@ LL | let _ = '0'..'9'; | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:103:9 + --> $DIR/almost_complete_range.rs:88:9 | LL | 'a'..'z' => 1, | ^^^--^^^ @@ -216,7 +207,7 @@ LL | 'a'..'z' => 1, | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:104:9 + --> $DIR/almost_complete_range.rs:89:9 | LL | 'A'..'Z' => 1, | ^^^--^^^ @@ -224,7 +215,7 @@ LL | 'A'..'Z' => 1, | help: use an inclusive range: `..=` error: almost complete ascii range - --> $DIR/almost_complete_range.rs:105:9 + --> $DIR/almost_complete_range.rs:90:9 | LL | '0'..'9' => 3, | ^^^--^^^ diff --git a/tests/ui/as_conversions.rs b/tests/ui/as_conversions.rs index ba4394defbf..c50d4088b5e 100644 --- a/tests/ui/as_conversions.rs +++ b/tests/ui/as_conversions.rs @@ -1,20 +1,15 @@ -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::as_conversions)] #![allow(clippy::borrow_as_ptr)] -#[macro_use] -extern crate macro_rules; - -fn with_external_macro() { - as_conv_with_arg!(0u32 as u64); - as_conv!(); -} +extern crate proc_macros; +use proc_macros::external; fn main() { let i = 0u32 as u64; let j = &i as *const u64 as *mut u64; - with_external_macro(); + external!(0u32 as u64); } diff --git a/tests/ui/as_conversions.stderr b/tests/ui/as_conversions.stderr index f5d59e1e5d8..54037a64997 100644 --- a/tests/ui/as_conversions.stderr +++ b/tests/ui/as_conversions.stderr @@ -1,5 +1,5 @@ error: using a potentially dangerous silent `as` conversion - --> $DIR/as_conversions.rs:15:13 + --> $DIR/as_conversions.rs:10:13 | LL | let i = 0u32 as u64; | ^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | let i = 0u32 as u64; = note: `-D clippy::as-conversions` implied by `-D warnings` error: using a potentially dangerous silent `as` conversion - --> $DIR/as_conversions.rs:17:13 + --> $DIR/as_conversions.rs:12:13 | LL | let j = &i as *const u64 as *mut u64; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -16,7 +16,7 @@ LL | let j = &i as *const u64 as *mut u64; = help: consider using a safe wrapper for this conversion error: using a potentially dangerous silent `as` conversion - --> $DIR/as_conversions.rs:17:13 + --> $DIR/as_conversions.rs:12:13 | LL | let j = &i as *const u64 as *mut u64; | ^^^^^^^^^^^^^^^^ diff --git a/tests/ui/auxiliary/doc_unsafe_macros.rs b/tests/ui/auxiliary/doc_unsafe_macros.rs deleted file mode 100644 index 3d917e3dc75..00000000000 --- a/tests/ui/auxiliary/doc_unsafe_macros.rs +++ /dev/null @@ -1,16 +0,0 @@ -#[macro_export] -macro_rules! undocd_unsafe { - () => { - pub unsafe fn oy_vey() { - unimplemented!(); - } - }; -} -#[macro_export] -macro_rules! undocd_safe { - () => { - pub fn vey_oy() { - unimplemented!(); - } - }; -} diff --git a/tests/ui/auxiliary/implicit_hasher_macros.rs b/tests/ui/auxiliary/implicit_hasher_macros.rs deleted file mode 100644 index 1eb77c53183..00000000000 --- a/tests/ui/auxiliary/implicit_hasher_macros.rs +++ /dev/null @@ -1,6 +0,0 @@ -#[macro_export] -macro_rules! implicit_hasher_fn { - () => { - pub fn f(input: &HashMap) {} - }; -} diff --git a/tests/ui/auxiliary/macro_rules.rs b/tests/ui/auxiliary/macro_rules.rs index a13af565203..1dc92c1b92b 100644 --- a/tests/ui/auxiliary/macro_rules.rs +++ b/tests/ui/auxiliary/macro_rules.rs @@ -2,21 +2,6 @@ //! Used to test that certain lints don't trigger in imported external macros -#[macro_export] -macro_rules! foofoo { - () => { - loop {} - }; -} - -#[macro_export] -macro_rules! must_use_unit { - () => { - #[must_use] - fn foo() {} - }; -} - #[macro_export] macro_rules! try_err { () => { @@ -36,135 +21,9 @@ macro_rules! string_add { }; } -#[macro_export] -macro_rules! take_external { - ($s:expr) => { - std::mem::replace($s, Default::default()) - }; -} - -#[macro_export] -macro_rules! option_env_unwrap_external { - ($env: expr) => { - option_env!($env).unwrap() - }; - ($env: expr, $message: expr) => { - option_env!($env).expect($message) - }; -} - -#[macro_export] -macro_rules! ref_arg_binding { - () => { - let ref _y = 42; - }; -} - -#[macro_export] -macro_rules! ref_arg_function { - () => { - fn fun_example(ref _x: usize) {} - }; -} - -#[macro_export] -macro_rules! as_conv_with_arg { - (0u32 as u64) => { - () - }; -} - -#[macro_export] -macro_rules! as_conv { - () => { - 0u32 as u64 - }; -} - -#[macro_export] -macro_rules! large_enum_variant { - () => { - enum LargeEnumInMacro { - A(i32), - B([i32; 8000]), - } - }; -} - -#[macro_export] -macro_rules! field_reassign_with_default { - () => { - #[derive(Default)] - struct A { - pub i: i32, - pub j: i64, - } - fn lint() { - let mut a: A = Default::default(); - a.i = 42; - a; - } - }; -} - -#[macro_export] -macro_rules! default_numeric_fallback { - () => { - let x = 22; - }; -} - #[macro_export] macro_rules! mut_mut { () => { let mut_mut_ty: &mut &mut u32 = &mut &mut 1u32; }; } - -#[macro_export] -macro_rules! ptr_as_ptr_cast { - ($ptr: ident) => { - $ptr as *const i32 - }; -} - -#[macro_export] -macro_rules! manual_rem_euclid { - () => { - let value: i32 = 5; - let _: i32 = ((value % 4) + 4) % 4; - }; -} - -#[macro_export] -macro_rules! equatable_if_let { - ($a:ident) => {{ if let 2 = $a {} }}; -} - -#[macro_export] -macro_rules! almost_complete_range { - () => { - let _ = 'a'..'z'; - let _ = 'A'..'Z'; - let _ = '0'..'9'; - }; -} - -#[macro_export] -macro_rules! unsafe_macro { - () => { - unsafe { - *core::ptr::null::<()>(); - *core::ptr::null::<()>(); - } - }; -} - -#[macro_export] -macro_rules! needless_lifetime { - () => { - fn needless_lifetime<'a>(x: &'a u8) -> &'a u8 { - unimplemented!() - } - }; -} diff --git a/tests/ui/auxiliary/macro_use_helper.rs b/tests/ui/auxiliary/macro_use_helper.rs index ecb55d8cb48..7ed8a28dbd9 100644 --- a/tests/ui/auxiliary/macro_use_helper.rs +++ b/tests/ui/auxiliary/macro_use_helper.rs @@ -13,7 +13,7 @@ pub mod inner { // RE-EXPORT // this will stick in `inner` module - pub use macro_rules::foofoo; + pub use macro_rules::mut_mut; pub use macro_rules::try_err; pub mod nested { diff --git a/tests/ui/auxiliary/proc_macro_with_span.rs b/tests/ui/auxiliary/proc_macro_with_span.rs deleted file mode 100644 index 8ea631f2bbd..00000000000 --- a/tests/ui/auxiliary/proc_macro_with_span.rs +++ /dev/null @@ -1,32 +0,0 @@ -// compile-flags: --emit=link -// no-prefer-dynamic - -#![crate_type = "proc-macro"] - -extern crate proc_macro; - -use proc_macro::{token_stream::IntoIter, Group, Span, TokenStream, TokenTree}; - -#[proc_macro] -pub fn with_span(input: TokenStream) -> TokenStream { - let mut iter = input.into_iter(); - let span = iter.next().unwrap().span(); - let mut res = TokenStream::new(); - write_with_span(span, iter, &mut res); - res -} - -fn write_with_span(s: Span, input: IntoIter, out: &mut TokenStream) { - for mut tt in input { - if let TokenTree::Group(g) = tt { - let mut stream = TokenStream::new(); - write_with_span(s, g.stream().into_iter(), &mut stream); - let mut group = Group::new(g.delimiter(), stream); - group.set_span(s); - out.extend([TokenTree::Group(group)]); - } else { - tt.set_span(s); - out.extend([tt]); - } - } -} diff --git a/tests/ui/auxiliary/proc_macros.rs b/tests/ui/auxiliary/proc_macros.rs new file mode 100644 index 00000000000..325be83a0d7 --- /dev/null +++ b/tests/ui/auxiliary/proc_macros.rs @@ -0,0 +1,474 @@ +// compile-flags: --emit=link +// no-prefer-dynamic + +#![crate_type = "proc-macro"] +#![feature(let_chains)] +#![feature(proc_macro_span)] +#![allow(dead_code)] + +extern crate proc_macro; + +use core::mem; +use proc_macro::{ + token_stream::IntoIter, + Delimiter::{self, Brace, Parenthesis}, + Group, Ident, Literal, Punct, + Spacing::{self, Alone, Joint}, + Span, TokenStream, TokenTree as TT, +}; + +type Result = core::result::Result; + +/// Make a `compile_error!` pointing to the given span. +fn make_error(msg: &str, span: Span) -> TokenStream { + TokenStream::from_iter([ + TT::Ident(Ident::new("compile_error", span)), + TT::Punct(punct_with_span('!', Alone, span)), + TT::Group({ + let mut msg = Literal::string(msg); + msg.set_span(span); + group_with_span(Parenthesis, TokenStream::from_iter([TT::Literal(msg)]), span) + }), + ]) +} + +fn expect_tt(tt: Option, f: impl FnOnce(TT) -> Option, expected: &str, span: Span) -> Result { + match tt { + None => Err(make_error( + &format!("unexpected end of input, expected {expected}"), + span, + )), + Some(tt) => { + let span = tt.span(); + match f(tt) { + Some(x) => Ok(x), + None => Err(make_error(&format!("unexpected token, expected {expected}"), span)), + } + }, + } +} + +fn punct_with_span(c: char, spacing: Spacing, span: Span) -> Punct { + let mut p = Punct::new(c, spacing); + p.set_span(span); + p +} + +fn group_with_span(delimiter: Delimiter, stream: TokenStream, span: Span) -> Group { + let mut g = Group::new(delimiter, stream); + g.set_span(span); + g +} + +/// Token used to escape the following token from the macro's span rules. +const ESCAPE_CHAR: char = '$'; + +/// Takes a single token followed by a sequence tokens. Returns the sequence of tokens with their +/// span set to that of the first token. Tokens may be escaped with either `#ident` or `#(tokens)`. +#[proc_macro] +pub fn with_span(input: TokenStream) -> TokenStream { + let mut iter = input.into_iter(); + let span = iter.next().unwrap().span(); + let mut res = TokenStream::new(); + if let Err(e) = write_with_span(span, iter, &mut res) { + e + } else { + res + } +} + +/// Takes a sequence of tokens and return the tokens with the span set such that they appear to be +/// from an external macro. Tokens may be escaped with either `#ident` or `#(tokens)`. +#[proc_macro] +pub fn external(input: TokenStream) -> TokenStream { + let mut res = TokenStream::new(); + if let Err(e) = write_with_span(Span::mixed_site(), input.into_iter(), &mut res) { + e + } else { + res + } +} + +/// Copies all the tokens, replacing all their spans with the given span. Tokens can be escaped +/// either by `#ident` or `#(tokens)`. +fn write_with_span(s: Span, mut input: IntoIter, out: &mut TokenStream) -> Result<()> { + while let Some(tt) = input.next() { + match tt { + TT::Punct(p) if p.as_char() == ESCAPE_CHAR => { + expect_tt( + input.next(), + |tt| match tt { + tt @ (TT::Ident(_) | TT::Literal(_)) => { + out.extend([tt]); + Some(()) + }, + TT::Punct(mut p) if p.as_char() == ESCAPE_CHAR => { + p.set_span(s); + out.extend([TT::Punct(p)]); + Some(()) + }, + TT::Group(g) if g.delimiter() == Parenthesis => { + out.extend([TT::Group(group_with_span(Delimiter::None, g.stream(), g.span()))]); + Some(()) + }, + _ => None, + }, + "an ident, a literal, or parenthesized tokens", + p.span(), + )?; + }, + TT::Group(g) => { + let mut stream = TokenStream::new(); + write_with_span(s, g.stream().into_iter(), &mut stream)?; + out.extend([TT::Group(group_with_span(g.delimiter(), stream, s))]); + }, + mut tt => { + tt.set_span(s); + out.extend([tt]); + }, + } + } + Ok(()) +} + +/// Within the item this attribute is attached to, an `inline!` macro is available which expands the +/// contained tokens as though they came from a macro expansion. +/// +/// Within the `inline!` macro, any token preceded by `$` is passed as though it were an argument +/// with an automatically chosen fragment specifier. `$ident` will be passed as `ident`, `$1` or +/// `$"literal"` will be passed as `literal`, `$'lt` will be passed as `lifetime`, and `$(...)` will +/// pass the contained tokens as a `tt` sequence (the wrapping parenthesis are removed). If another +/// specifier is required it can be specified within parenthesis like `$(@expr ...)`. This will +/// expand the remaining tokens as a single argument. +/// +/// Multiple `inline!` macros may be nested within each other. This will expand as nested macro +/// calls. However, any arguments will be passed as though they came from the outermost context. +#[proc_macro_attribute] +pub fn inline_macros(args: TokenStream, input: TokenStream) -> TokenStream { + let mut args = args.into_iter(); + let mac_name = match args.next() { + Some(TT::Ident(name)) => Some(name), + Some(tt) => { + return make_error( + "unexpected argument, expected either an ident or no arguments", + tt.span(), + ); + }, + None => None, + }; + if let Some(tt) = args.next() { + return make_error( + "unexpected argument, expected either an ident or no arguments", + tt.span(), + ); + }; + + let mac_name = if let Some(mac_name) = mac_name { + Ident::new(&format!("__inline_mac_{mac_name}"), Span::call_site()) + } else { + let mut input = match LookaheadIter::new(input.clone().into_iter()) { + Some(x) => x, + None => return input, + }; + loop { + match input.next() { + None => break Ident::new("__inline_mac", Span::call_site()), + Some(TT::Ident(kind)) => match &*kind.to_string() { + "impl" => break Ident::new("__inline_mac_impl", Span::call_site()), + kind @ ("struct" | "enum" | "union" | "fn" | "mod" | "trait" | "type" | "const" | "static") => { + if let TT::Ident(name) = &input.tt { + break Ident::new(&format!("__inline_mac_{kind}_{name}"), Span::call_site()); + } else { + break Ident::new(&format!("__inline_mac_{kind}"), Span::call_site()); + } + }, + _ => {}, + }, + _ => {}, + } + } + }; + + let mut expander = Expander::default(); + let mut mac = MacWriter::new(mac_name); + if let Err(e) = expander.expand(input.into_iter(), &mut mac) { + return e; + } + let mut out = TokenStream::new(); + mac.finish(&mut out); + out.extend(expander.expn); + out +} + +/// Wraps a `TokenStream` iterator with a single token lookahead. +struct LookaheadIter { + tt: TT, + iter: IntoIter, +} +impl LookaheadIter { + fn new(mut iter: IntoIter) -> Option { + iter.next().map(|tt| Self { tt, iter }) + } + + /// Get's the lookahead token, replacing it with the next token in the stream. + /// Note: If there isn't a next token, this will not return the lookahead token. + fn next(&mut self) -> Option { + self.iter.next().map(|tt| mem::replace(&mut self.tt, tt)) + } +} + +/// Builds the macro used to implement all the `inline!` macro calls. +struct MacWriter { + name: Ident, + macros: TokenStream, + next_idx: usize, +} +impl MacWriter { + fn new(name: Ident) -> Self { + Self { + name, + macros: TokenStream::new(), + next_idx: 0, + } + } + + /// Inserts a new `inline!` call. + fn insert(&mut self, name_span: Span, bang_span: Span, body: Group, expander: &mut Expander) -> Result<()> { + let idx = self.next_idx; + self.next_idx += 1; + + let mut inner = Expander::for_arm(idx); + inner.expand(body.stream().into_iter(), self)?; + let new_arm = inner.arm.unwrap(); + + self.macros.extend([ + TT::Group(Group::new(Parenthesis, new_arm.args_def)), + TT::Punct(Punct::new('=', Joint)), + TT::Punct(Punct::new('>', Alone)), + TT::Group(Group::new(Parenthesis, inner.expn)), + TT::Punct(Punct::new(';', Alone)), + ]); + + expander.expn.extend([ + TT::Ident({ + let mut name = self.name.clone(); + name.set_span(name_span); + name + }), + TT::Punct(punct_with_span('!', Alone, bang_span)), + ]); + let mut call_body = TokenStream::from_iter([TT::Literal(Literal::usize_unsuffixed(idx))]); + if let Some(arm) = expander.arm.as_mut() { + if !new_arm.args.is_empty() { + arm.add_sub_args(new_arm.args, &mut call_body); + } + } else { + call_body.extend(new_arm.args); + } + let mut g = Group::new(body.delimiter(), call_body); + g.set_span(body.span()); + expander.expn.extend([TT::Group(g)]); + Ok(()) + } + + /// Creates the macro definition. + fn finish(self, out: &mut TokenStream) { + if self.next_idx != 0 { + out.extend([ + TT::Ident(Ident::new("macro_rules", Span::call_site())), + TT::Punct(Punct::new('!', Alone)), + TT::Ident(self.name), + TT::Group(Group::new(Brace, self.macros)), + ]) + } + } +} + +struct MacroArm { + args_def: TokenStream, + args: Vec, +} +impl MacroArm { + fn add_single_arg_def(&mut self, kind: &str, dollar_span: Span, arg_span: Span, out: &mut TokenStream) { + let mut name = Ident::new(&format!("_{}", self.args.len()), Span::call_site()); + self.args_def.extend([ + TT::Punct(Punct::new('$', Alone)), + TT::Ident(name.clone()), + TT::Punct(Punct::new(':', Alone)), + TT::Ident(Ident::new(kind, Span::call_site())), + ]); + name.set_span(arg_span); + out.extend([TT::Punct(punct_with_span('$', Alone, dollar_span)), TT::Ident(name)]); + } + + fn add_parenthesized_arg_def(&mut self, kind: Ident, dollar_span: Span, arg_span: Span, out: &mut TokenStream) { + let mut name = Ident::new(&format!("_{}", self.args.len()), Span::call_site()); + self.args_def.extend([TT::Group(Group::new( + Parenthesis, + TokenStream::from_iter([ + TT::Punct(Punct::new('$', Alone)), + TT::Ident(name.clone()), + TT::Punct(Punct::new(':', Alone)), + TT::Ident(kind), + ]), + ))]); + name.set_span(arg_span); + out.extend([TT::Punct(punct_with_span('$', Alone, dollar_span)), TT::Ident(name)]); + } + + fn add_multi_arg_def(&mut self, dollar_span: Span, arg_span: Span, out: &mut TokenStream) { + let mut name = Ident::new(&format!("_{}", self.args.len()), Span::call_site()); + self.args_def.extend([TT::Group(Group::new( + Parenthesis, + TokenStream::from_iter([ + TT::Punct(Punct::new('$', Alone)), + TT::Group(Group::new( + Parenthesis, + TokenStream::from_iter([ + TT::Punct(Punct::new('$', Alone)), + TT::Ident(name.clone()), + TT::Punct(Punct::new(':', Alone)), + TT::Ident(Ident::new("tt", Span::call_site())), + ]), + )), + TT::Punct(Punct::new('*', Alone)), + ]), + ))]); + name.set_span(arg_span); + out.extend([ + TT::Punct(punct_with_span('$', Alone, dollar_span)), + TT::Group(group_with_span( + Parenthesis, + TokenStream::from_iter([TT::Punct(punct_with_span('$', Alone, dollar_span)), TT::Ident(name)]), + dollar_span, + )), + TT::Punct(punct_with_span('*', Alone, dollar_span)), + ]); + } + + fn add_arg(&mut self, dollar_span: Span, tt: TT, input: &mut IntoIter, out: &mut TokenStream) -> Result<()> { + match tt { + TT::Punct(p) if p.as_char() == ESCAPE_CHAR => out.extend([TT::Punct(p)]), + TT::Punct(p) if p.as_char() == '\'' && p.spacing() == Joint => { + let lt_name = expect_tt( + input.next(), + |tt| match tt { + TT::Ident(x) => Some(x), + _ => None, + }, + "lifetime name", + p.span(), + )?; + let arg_span = p.span().join(lt_name.span()).unwrap_or(p.span()); + self.add_single_arg_def("lifetime", dollar_span, arg_span, out); + self.args.extend([TT::Punct(p), TT::Ident(lt_name)]); + }, + TT::Ident(x) => { + self.add_single_arg_def("ident", dollar_span, x.span(), out); + self.args.push(TT::Ident(x)); + }, + TT::Literal(x) => { + self.add_single_arg_def("literal", dollar_span, x.span(), out); + self.args.push(TT::Literal(x)); + }, + TT::Group(g) if g.delimiter() == Parenthesis => { + let mut inner = g.stream().into_iter(); + if let Some(TT::Punct(p)) = inner.next() + && p.as_char() == '@' + { + let kind = expect_tt( + inner.next(), + |tt| match tt { + TT::Ident(kind) => Some(kind), + _ => None, + }, + "a macro fragment specifier", + p.span(), + )?; + self.add_parenthesized_arg_def(kind, dollar_span, g.span(), out); + self.args.push(TT::Group(group_with_span(Parenthesis, inner.collect(), g.span()))) + } else { + self.add_multi_arg_def(dollar_span, g.span(), out); + self.args.push(TT::Group(g)); + } + }, + tt => return Err(make_error("unsupported escape", tt.span())), + }; + Ok(()) + } + + fn add_sub_args(&mut self, args: Vec, out: &mut TokenStream) { + self.add_multi_arg_def(Span::call_site(), Span::call_site(), out); + self.args + .extend([TT::Group(Group::new(Parenthesis, TokenStream::from_iter(args)))]); + } +} + +#[derive(Default)] +struct Expander { + arm: Option, + expn: TokenStream, +} +impl Expander { + fn for_arm(idx: usize) -> Self { + Self { + arm: Some(MacroArm { + args_def: TokenStream::from_iter([TT::Literal(Literal::usize_unsuffixed(idx))]), + args: Vec::new(), + }), + expn: TokenStream::new(), + } + } + + fn write_tt(&mut self, tt: TT, mac: &mut MacWriter) -> Result<()> { + match tt { + TT::Group(g) => { + let outer = mem::take(&mut self.expn); + self.expand(g.stream().into_iter(), mac)?; + let inner = mem::replace(&mut self.expn, outer); + self.expn + .extend([TT::Group(group_with_span(g.delimiter(), inner, g.span()))]); + }, + tt => self.expn.extend([tt]), + } + Ok(()) + } + + fn expand(&mut self, input: IntoIter, mac: &mut MacWriter) -> Result<()> { + let Some(mut input) = LookaheadIter::new(input) else { + return Ok(()); + }; + while let Some(tt) = input.next() { + if let TT::Punct(p) = &tt + && p.as_char() == ESCAPE_CHAR + && let Some(arm) = self.arm.as_mut() + { + arm.add_arg(p.span(), mem::replace(&mut input.tt, tt), &mut input.iter, &mut self.expn)?; + if input.next().is_none() { + return Ok(()); + } + } else if let TT::Punct(p) = &input.tt + && p.as_char() == '!' + && let TT::Ident(name) = &tt + && name.to_string() == "inline" + { + let g = expect_tt( + input.iter.next(), + |tt| match tt { + TT::Group(g) => Some(g), + _ => None, + }, + "macro arguments", + p.span(), + )?; + mac.insert(name.span(), p.span(), g, self)?; + if input.next().is_none() { + return Ok(()); + } + } else { + self.write_tt(tt, mac)?; + } + } + self.write_tt(input.tt, mac) + } +} diff --git a/tests/ui/borrow_interior_mutable_const/auxiliary/helper.rs b/tests/ui/borrow_interior_mutable_const/auxiliary/helper.rs index f13733af3d0..b03c21262c3 100644 --- a/tests/ui/borrow_interior_mutable_const/auxiliary/helper.rs +++ b/tests/ui/borrow_interior_mutable_const/auxiliary/helper.rs @@ -1,5 +1,5 @@ // this file solely exists to test constants defined in foreign crates. -// As the most common case is the `http` crate, it replicates `http::HeadewrName`'s structure. +// As the most common case is the `http` crate, it replicates `http::HeaderName`'s structure. #![allow(clippy::declare_interior_mutable_const)] #![allow(unused_tuple_struct_fields)] diff --git a/tests/ui/crashes/ice-10148.rs b/tests/ui/crashes/ice-10148.rs index af33b10c693..1ab3570c907 100644 --- a/tests/ui/crashes/ice-10148.rs +++ b/tests/ui/crashes/ice-10148.rs @@ -1,8 +1,8 @@ -// aux-build:../../auxiliary/proc_macro_with_span.rs +// aux-build:../../auxiliary/proc_macros.rs -extern crate proc_macro_with_span; +extern crate proc_macros; -use proc_macro_with_span::with_span; +use proc_macros::with_span; fn main() { println!(with_span!(""something "")); diff --git a/tests/ui/default_numeric_fallback_f64.fixed b/tests/ui/default_numeric_fallback_f64.fixed index a9e5fd159af..42c15d6a70b 100644 --- a/tests/ui/default_numeric_fallback_f64.fixed +++ b/tests/ui/default_numeric_fallback_f64.fixed @@ -1,5 +1,5 @@ // run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::default_numeric_fallback)] #![allow( @@ -13,8 +13,8 @@ clippy::let_with_type_underscore )] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::{external, inline_macros}; mod basic_expr { fn test() { @@ -167,20 +167,17 @@ mod method_calls { } mod in_macro { - macro_rules! internal_macro { - () => { - let x = 22.0_f64; - }; - } + use super::*; // Should lint in internal macro. + #[inline_macros] fn internal() { - internal_macro!(); + inline!(let x = 22.0_f64;); } // Should NOT lint in external macro. fn external() { - default_numeric_fallback!(); + external!(let x = 22.;); } } diff --git a/tests/ui/default_numeric_fallback_f64.rs b/tests/ui/default_numeric_fallback_f64.rs index 085f8f452b2..7da7ea254e9 100644 --- a/tests/ui/default_numeric_fallback_f64.rs +++ b/tests/ui/default_numeric_fallback_f64.rs @@ -1,5 +1,5 @@ // run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::default_numeric_fallback)] #![allow( @@ -13,8 +13,8 @@ clippy::let_with_type_underscore )] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::{external, inline_macros}; mod basic_expr { fn test() { @@ -167,20 +167,17 @@ mod method_calls { } mod in_macro { - macro_rules! internal_macro { - () => { - let x = 22.; - }; - } + use super::*; // Should lint in internal macro. + #[inline_macros] fn internal() { - internal_macro!(); + inline!(let x = 22.;); } // Should NOT lint in external macro. fn external() { - default_numeric_fallback!(); + external!(let x = 22.;); } } diff --git a/tests/ui/default_numeric_fallback_f64.stderr b/tests/ui/default_numeric_fallback_f64.stderr index 44c6f1a9bea..b949cd1d50b 100644 --- a/tests/ui/default_numeric_fallback_f64.stderr +++ b/tests/ui/default_numeric_fallback_f64.stderr @@ -139,15 +139,12 @@ LL | s.generic_arg(1.); | ^^ help: consider adding suffix: `1.0_f64` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_f64.rs:172:21 + --> $DIR/default_numeric_fallback_f64.rs:175:25 | -LL | let x = 22.; - | ^^^ help: consider adding suffix: `22.0_f64` -... -LL | internal_macro!(); - | ----------------- in this macro invocation +LL | inline!(let x = 22.;); + | ^^^ help: consider adding suffix: `22.0_f64` | - = note: this error originates in the macro `internal_macro` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_fn_internal` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 24 previous errors diff --git a/tests/ui/default_numeric_fallback_i32.fixed b/tests/ui/default_numeric_fallback_i32.fixed index 63ac4d5aeb6..b7485b73dcd 100644 --- a/tests/ui/default_numeric_fallback_i32.fixed +++ b/tests/ui/default_numeric_fallback_i32.fixed @@ -1,5 +1,5 @@ // run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![feature(lint_reasons)] #![warn(clippy::default_numeric_fallback)] @@ -13,8 +13,8 @@ clippy::let_with_type_underscore )] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::{external, inline_macros}; mod basic_expr { fn test() { @@ -168,20 +168,17 @@ mod method_calls { } mod in_macro { - macro_rules! internal_macro { - () => { - let x = 22_i32; - }; - } + use super::*; // Should lint in internal macro. + #[inline_macros] fn internal() { - internal_macro!(); + inline!(let x = 22_i32;); } // Should NOT lint in external macro. fn external() { - default_numeric_fallback!(); + external!(let x = 22;); } } diff --git a/tests/ui/default_numeric_fallback_i32.rs b/tests/ui/default_numeric_fallback_i32.rs index 28e6eceb80e..7307d31354e 100644 --- a/tests/ui/default_numeric_fallback_i32.rs +++ b/tests/ui/default_numeric_fallback_i32.rs @@ -1,5 +1,5 @@ // run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![feature(lint_reasons)] #![warn(clippy::default_numeric_fallback)] @@ -13,8 +13,8 @@ clippy::let_with_type_underscore )] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::{external, inline_macros}; mod basic_expr { fn test() { @@ -168,20 +168,17 @@ mod method_calls { } mod in_macro { - macro_rules! internal_macro { - () => { - let x = 22; - }; - } + use super::*; // Should lint in internal macro. + #[inline_macros] fn internal() { - internal_macro!(); + inline!(let x = 22;); } // Should NOT lint in external macro. fn external() { - default_numeric_fallback!(); + external!(let x = 22;); } } diff --git a/tests/ui/default_numeric_fallback_i32.stderr b/tests/ui/default_numeric_fallback_i32.stderr index dd91574d5b3..48cd28102ce 100644 --- a/tests/ui/default_numeric_fallback_i32.stderr +++ b/tests/ui/default_numeric_fallback_i32.stderr @@ -151,15 +151,12 @@ LL | s.generic_arg(1); | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:173:21 + --> $DIR/default_numeric_fallback_i32.rs:176:25 | -LL | let x = 22; - | ^^ help: consider adding suffix: `22_i32` -... -LL | internal_macro!(); - | ----------------- in this macro invocation +LL | inline!(let x = 22;); + | ^^ help: consider adding suffix: `22_i32` | - = note: this error originates in the macro `internal_macro` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_fn_internal` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 26 previous errors diff --git a/tests/ui/default_trait_access.fixed b/tests/ui/default_trait_access.fixed index 5640599d48a..7842ef3ec40 100644 --- a/tests/ui/default_trait_access.fixed +++ b/tests/ui/default_trait_access.fixed @@ -1,12 +1,12 @@ // run-rustfix -// aux-build: proc_macro_with_span.rs +// aux-build: proc_macros.rs #![deny(clippy::default_trait_access)] #![allow(dead_code, unused_imports)] #![allow(clippy::uninlined_format_args)] -extern crate proc_macro_with_span; +extern crate proc_macros; -use proc_macro_with_span::with_span; +use proc_macros::with_span; use std::default; use std::default::Default as D2; use std::string; diff --git a/tests/ui/default_trait_access.rs b/tests/ui/default_trait_access.rs index 11d4bc5c5f0..cbb3e59c970 100644 --- a/tests/ui/default_trait_access.rs +++ b/tests/ui/default_trait_access.rs @@ -1,12 +1,12 @@ // run-rustfix -// aux-build: proc_macro_with_span.rs +// aux-build: proc_macros.rs #![deny(clippy::default_trait_access)] #![allow(dead_code, unused_imports)] #![allow(clippy::uninlined_format_args)] -extern crate proc_macro_with_span; +extern crate proc_macros; -use proc_macro_with_span::with_span; +use proc_macros::with_span; use std::default; use std::default::Default as D2; use std::string; diff --git a/tests/ui/deref_addrof.fixed b/tests/ui/deref_addrof.fixed index 2f489deb1ee..ca5c03304c7 100644 --- a/tests/ui/deref_addrof.fixed +++ b/tests/ui/deref_addrof.fixed @@ -1,7 +1,12 @@ // run-rustfix +// aux-build:proc_macros.rs + #![allow(clippy::return_self_not_must_use)] #![warn(clippy::deref_addrof)] +extern crate proc_macros; +use proc_macros::inline_macros; + fn get_number() -> usize { 10 } @@ -41,28 +46,15 @@ fn main() { let _ = unsafe { *core::ptr::addr_of!(a) }; } -#[rustfmt::skip] -macro_rules! m { - ($visitor: expr) => { - $visitor - }; -} - -#[rustfmt::skip] -macro_rules! m_mut { - ($visitor: expr) => { - $visitor - }; -} - #[derive(Copy, Clone)] pub struct S; +#[inline_macros] impl S { pub fn f(&self) -> &Self { - m!(self) + inline!($(@expr self)) } #[allow(unused_mut)] // mut will be unused, once the macro is fixed pub fn f_mut(mut self) -> Self { - m_mut!(self) + inline!($(@expr self)) } } diff --git a/tests/ui/deref_addrof.rs b/tests/ui/deref_addrof.rs index 49f360b9a7f..3db5fafe944 100644 --- a/tests/ui/deref_addrof.rs +++ b/tests/ui/deref_addrof.rs @@ -1,7 +1,12 @@ // run-rustfix +// aux-build:proc_macros.rs + #![allow(clippy::return_self_not_must_use)] #![warn(clippy::deref_addrof)] +extern crate proc_macros; +use proc_macros::inline_macros; + fn get_number() -> usize { 10 } @@ -41,28 +46,15 @@ fn main() { let _ = unsafe { *core::ptr::addr_of!(a) }; } -#[rustfmt::skip] -macro_rules! m { - ($visitor: expr) => { - *& $visitor - }; -} - -#[rustfmt::skip] -macro_rules! m_mut { - ($visitor: expr) => { - *& mut $visitor - }; -} - #[derive(Copy, Clone)] pub struct S; +#[inline_macros] impl S { pub fn f(&self) -> &Self { - m!(self) + inline!(*& $(@expr self)) } #[allow(unused_mut)] // mut will be unused, once the macro is fixed pub fn f_mut(mut self) -> Self { - m_mut!(self) + inline!(*&mut $(@expr self)) } } diff --git a/tests/ui/deref_addrof.stderr b/tests/ui/deref_addrof.stderr index 75371fcdb96..e0287522fc5 100644 --- a/tests/ui/deref_addrof.stderr +++ b/tests/ui/deref_addrof.stderr @@ -1,5 +1,5 @@ error: immediately dereferencing a reference - --> $DIR/deref_addrof.rs:19:13 + --> $DIR/deref_addrof.rs:24:13 | LL | let b = *&a; | ^^^ help: try this: `a` @@ -7,68 +7,62 @@ LL | let b = *&a; = note: `-D clippy::deref-addrof` implied by `-D warnings` error: immediately dereferencing a reference - --> $DIR/deref_addrof.rs:21:13 + --> $DIR/deref_addrof.rs:26:13 | LL | let b = *&get_number(); | ^^^^^^^^^^^^^^ help: try this: `get_number()` error: immediately dereferencing a reference - --> $DIR/deref_addrof.rs:26:13 + --> $DIR/deref_addrof.rs:31:13 | LL | let b = *&bytes[1..2][0]; | ^^^^^^^^^^^^^^^^ help: try this: `bytes[1..2][0]` error: immediately dereferencing a reference - --> $DIR/deref_addrof.rs:30:13 + --> $DIR/deref_addrof.rs:35:13 | LL | let b = *&(a); | ^^^^^ help: try this: `(a)` error: immediately dereferencing a reference - --> $DIR/deref_addrof.rs:32:13 + --> $DIR/deref_addrof.rs:37:13 | LL | let b = *(&a); | ^^^^^ help: try this: `a` error: immediately dereferencing a reference - --> $DIR/deref_addrof.rs:35:13 + --> $DIR/deref_addrof.rs:40:13 | LL | let b = *((&a)); | ^^^^^^^ help: try this: `a` error: immediately dereferencing a reference - --> $DIR/deref_addrof.rs:37:13 + --> $DIR/deref_addrof.rs:42:13 | LL | let b = *&&a; | ^^^^ help: try this: `&a` error: immediately dereferencing a reference - --> $DIR/deref_addrof.rs:39:14 + --> $DIR/deref_addrof.rs:44:14 | LL | let b = **&aref; | ^^^^^^ help: try this: `aref` error: immediately dereferencing a reference - --> $DIR/deref_addrof.rs:47:9 + --> $DIR/deref_addrof.rs:54:17 | -LL | *& $visitor - | ^^^^^^^^^^^ help: try this: `$visitor` -... -LL | m!(self) - | -------- in this macro invocation +LL | inline!(*& $(@expr self)) + | ^^^^^^^^^^^^^^^^ help: try this: `$(@expr self)` | - = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: immediately dereferencing a reference - --> $DIR/deref_addrof.rs:54:9 + --> $DIR/deref_addrof.rs:58:17 | -LL | *& mut $visitor - | ^^^^^^^^^^^^^^^ help: try this: `$visitor` -... -LL | m_mut!(self) - | ------------ in this macro invocation +LL | inline!(*&mut $(@expr self)) + | ^^^^^^^^^^^^^^^^^^^ help: try this: `$(@expr self)` | - = note: this error originates in the macro `m_mut` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_impl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 10 previous errors diff --git a/tests/ui/deref_addrof_macro.rs b/tests/ui/deref_addrof_macro.rs index dcebd6c6e29..57c0be3f51e 100644 --- a/tests/ui/deref_addrof_macro.rs +++ b/tests/ui/deref_addrof_macro.rs @@ -1,10 +1,13 @@ -macro_rules! m { - ($($x:tt),*) => { &[$(($x, stringify!(x)),)*] }; -} +// aux-build:proc_macros.rs -#[warn(clippy::deref_addrof)] -fn f() -> [(i32, &'static str); 3] { - *m![1, 2, 3] // should be fine +#![warn(clippy::deref_addrof)] + +extern crate proc_macros; + +#[proc_macros::inline_macros] +fn f() -> i32 { + // should be fine + *inline!(&$1) } fn main() {} diff --git a/tests/ui/doc_unsafe.rs b/tests/ui/doc_unsafe.rs index b91f7aa0dd8..30674ce3708 100644 --- a/tests/ui/doc_unsafe.rs +++ b/tests/ui/doc_unsafe.rs @@ -1,9 +1,9 @@ -// aux-build:doc_unsafe_macros.rs +// aux-build:proc_macros.rs #![allow(clippy::let_unit_value)] -#[macro_use] -extern crate doc_unsafe_macros; +extern crate proc_macros; +use proc_macros::external; /// This is not sufficiently documented pub unsafe fn destroy_the_planet() { @@ -105,7 +105,11 @@ macro_rules! very_unsafe { very_unsafe!(); // we don't lint code from external macros -undocd_unsafe!(); +external! { + pub unsafe fn oy_vey() { + unimplemented!(); + } +} fn main() { unsafe { diff --git a/tests/ui/empty_loop.rs b/tests/ui/empty_loop.rs index 8fd7697eb3b..6a8e6b550c1 100644 --- a/tests/ui/empty_loop.rs +++ b/tests/ui/empty_loop.rs @@ -1,9 +1,9 @@ -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::empty_loop)] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::{external, inline_macros}; fn should_trigger() { loop {} @@ -16,6 +16,7 @@ fn should_trigger() { } } +#[inline_macros] fn should_not_trigger() { loop { panic!("This is fine") @@ -38,14 +39,10 @@ fn should_not_trigger() { loop {} // We don't lint loops inside macros - macro_rules! foo { - () => { - loop {} - }; - } + inline!(loop {}); // We don't lint external macros - foofoo!() + external!(loop {}); } fn main() {} diff --git a/tests/ui/equatable_if_let.fixed b/tests/ui/equatable_if_let.fixed index 9af2ba96272..007702ab550 100644 --- a/tests/ui/equatable_if_let.fixed +++ b/tests/ui/equatable_if_let.fixed @@ -1,11 +1,11 @@ // run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![allow(unused_variables, dead_code, clippy::derive_partial_eq_without_eq)] #![warn(clippy::equatable_if_let)] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::{external, inline_macros}; use std::cmp::Ordering; @@ -44,6 +44,7 @@ impl PartialEq for NotStructuralEq { } } +#[inline_macros] fn main() { let a = 2; let b = 3; @@ -78,14 +79,9 @@ fn main() { if Some(g) == Some(NotStructuralEq::A) {} if matches!(h, NoPartialEqStruct { a: 2, b: false }) {} - macro_rules! m1 { - (x) => { - "abc" - }; - } - if "abc" == m1!(x) { + if "abc" == inline!("abc") { println!("OK"); } - equatable_if_let!(a); + external!({ if let 2 = $a {} }); } diff --git a/tests/ui/equatable_if_let.rs b/tests/ui/equatable_if_let.rs index c3626c081dd..3bda7977645 100644 --- a/tests/ui/equatable_if_let.rs +++ b/tests/ui/equatable_if_let.rs @@ -1,11 +1,11 @@ // run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![allow(unused_variables, dead_code, clippy::derive_partial_eq_without_eq)] #![warn(clippy::equatable_if_let)] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::{external, inline_macros}; use std::cmp::Ordering; @@ -44,6 +44,7 @@ impl PartialEq for NotStructuralEq { } } +#[inline_macros] fn main() { let a = 2; let b = 3; @@ -78,14 +79,9 @@ fn main() { if let Some(NotStructuralEq::A) = Some(g) {} if let NoPartialEqStruct { a: 2, b: false } = h {} - macro_rules! m1 { - (x) => { - "abc" - }; - } - if let m1!(x) = "abc" { + if let inline!("abc") = "abc" { println!("OK"); } - equatable_if_let!(a); + external!({ if let 2 = $a {} }); } diff --git a/tests/ui/equatable_if_let.stderr b/tests/ui/equatable_if_let.stderr index 40ca75b8da2..a72d87bb7ba 100644 --- a/tests/ui/equatable_if_let.stderr +++ b/tests/ui/equatable_if_let.stderr @@ -1,5 +1,5 @@ error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:59:8 + --> $DIR/equatable_if_let.rs:60:8 | LL | if let 2 = a {} | ^^^^^^^^^ help: try: `a == 2` @@ -7,82 +7,82 @@ LL | if let 2 = a {} = note: `-D clippy::equatable-if-let` implied by `-D warnings` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:60:8 + --> $DIR/equatable_if_let.rs:61:8 | LL | if let Ordering::Greater = a.cmp(&b) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.cmp(&b) == Ordering::Greater` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:61:8 + --> $DIR/equatable_if_let.rs:62:8 | LL | if let Some(2) = c {} | ^^^^^^^^^^^^^^^ help: try: `c == Some(2)` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:62:8 + --> $DIR/equatable_if_let.rs:63:8 | LL | if let Struct { a: 2, b: false } = d {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `d == (Struct { a: 2, b: false })` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:63:8 + --> $DIR/equatable_if_let.rs:64:8 | LL | if let Enum::TupleVariant(32, 64) = e {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == Enum::TupleVariant(32, 64)` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:64:8 + --> $DIR/equatable_if_let.rs:65:8 | LL | if let Enum::RecordVariant { a: 64, b: 32 } = e {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == (Enum::RecordVariant { a: 64, b: 32 })` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:65:8 + --> $DIR/equatable_if_let.rs:66:8 | LL | if let Enum::UnitVariant = e {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == Enum::UnitVariant` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:66:8 + --> $DIR/equatable_if_let.rs:67:8 | LL | if let (Enum::UnitVariant, &Struct { a: 2, b: false }) = (e, &d) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(e, &d) == (Enum::UnitVariant, &Struct { a: 2, b: false })` error: this pattern matching can be expressed using `matches!` - --> $DIR/equatable_if_let.rs:75:8 + --> $DIR/equatable_if_let.rs:76:8 | LL | if let NotPartialEq::A = f {} | ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(f, NotPartialEq::A)` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:76:8 + --> $DIR/equatable_if_let.rs:77:8 | LL | if let NotStructuralEq::A = g {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `g == NotStructuralEq::A` error: this pattern matching can be expressed using `matches!` - --> $DIR/equatable_if_let.rs:77:8 + --> $DIR/equatable_if_let.rs:78:8 | LL | if let Some(NotPartialEq::A) = Some(f) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(Some(f), Some(NotPartialEq::A))` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:78:8 + --> $DIR/equatable_if_let.rs:79:8 | LL | if let Some(NotStructuralEq::A) = Some(g) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(g) == Some(NotStructuralEq::A)` error: this pattern matching can be expressed using `matches!` - --> $DIR/equatable_if_let.rs:79:8 + --> $DIR/equatable_if_let.rs:80:8 | LL | if let NoPartialEqStruct { a: 2, b: false } = h {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `matches!(h, NoPartialEqStruct { a: 2, b: false })` error: this pattern matching can be expressed using equality - --> $DIR/equatable_if_let.rs:86:8 + --> $DIR/equatable_if_let.rs:82:8 | -LL | if let m1!(x) = "abc" { - | ^^^^^^^^^^^^^^^^^^ help: try: `"abc" == m1!(x)` +LL | if let inline!("abc") = "abc" { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `"abc" == inline!("abc")` error: aborting due to 14 previous errors diff --git a/tests/ui/field_reassign_with_default.rs b/tests/ui/field_reassign_with_default.rs index 1f989bb1220..0e208b3ed0e 100644 --- a/tests/ui/field_reassign_with_default.rs +++ b/tests/ui/field_reassign_with_default.rs @@ -1,12 +1,12 @@ // aux-build:proc_macro_derive.rs -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::field_reassign_with_default)] #[macro_use] extern crate proc_macro_derive; -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::{external, inline_macros}; // Don't lint on derives that derive `Default` // See https://github.com/rust-lang/rust-clippy/issues/6545 @@ -36,14 +36,6 @@ struct D { b: Option, } -macro_rules! m { - ($key:ident: $value:tt) => {{ - let mut data = $crate::D::default(); - data.$key = Some($value); - data - }}; -} - /// Implements .next() that returns a different number each time. struct SideEffect(i32); @@ -57,6 +49,7 @@ impl SideEffect { } } +#[inline_macros] fn main() { // wrong, produces first error in stderr let mut a: A = Default::default(); @@ -150,7 +143,18 @@ fn main() { a.i = vec![1]; // Don't lint in external macros - field_reassign_with_default!(); + external! { + #[derive(Default)] + struct A { + pub i: i32, + pub j: i64, + } + fn lint() { + let mut a: A = Default::default(); + a.i = 42; + a; + } + } // be sure suggestion is correct with generics let mut a: Wrapper = Default::default(); @@ -160,9 +164,11 @@ fn main() { a.i = 42; // Don't lint in macros - m! { - a: 42 - }; + inline!( + let mut data = $crate::D::default(); + data.$a = Some($42); + data + ); } mod m { diff --git a/tests/ui/field_reassign_with_default.stderr b/tests/ui/field_reassign_with_default.stderr index 710bb66a48a..da74f9ef9f7 100644 --- a/tests/ui/field_reassign_with_default.stderr +++ b/tests/ui/field_reassign_with_default.stderr @@ -1,132 +1,132 @@ error: field assignment outside of initializer for an instance created with Default::default() - --> $DIR/field_reassign_with_default.rs:63:5 + --> $DIR/field_reassign_with_default.rs:56:5 | LL | a.i = 42; | ^^^^^^^^^ | note: consider initializing the variable with `main::A { i: 42, ..Default::default() }` and removing relevant reassignments - --> $DIR/field_reassign_with_default.rs:62:5 + --> $DIR/field_reassign_with_default.rs:55:5 | LL | let mut a: A = Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: `-D clippy::field-reassign-with-default` implied by `-D warnings` error: field assignment outside of initializer for an instance created with Default::default() - --> $DIR/field_reassign_with_default.rs:103:5 + --> $DIR/field_reassign_with_default.rs:96:5 | LL | a.j = 43; | ^^^^^^^^^ | note: consider initializing the variable with `main::A { j: 43, i: 42 }` and removing relevant reassignments - --> $DIR/field_reassign_with_default.rs:102:5 + --> $DIR/field_reassign_with_default.rs:95:5 | LL | let mut a: A = Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: field assignment outside of initializer for an instance created with Default::default() - --> $DIR/field_reassign_with_default.rs:108:5 + --> $DIR/field_reassign_with_default.rs:101:5 | LL | a.i = 42; | ^^^^^^^^^ | note: consider initializing the variable with `main::A { i: 42, j: 44 }` and removing relevant reassignments - --> $DIR/field_reassign_with_default.rs:107:5 + --> $DIR/field_reassign_with_default.rs:100:5 | LL | let mut a: A = Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: field assignment outside of initializer for an instance created with Default::default() - --> $DIR/field_reassign_with_default.rs:114:5 + --> $DIR/field_reassign_with_default.rs:107:5 | LL | a.i = 42; | ^^^^^^^^^ | note: consider initializing the variable with `main::A { i: 42, ..Default::default() }` and removing relevant reassignments - --> $DIR/field_reassign_with_default.rs:113:5 + --> $DIR/field_reassign_with_default.rs:106:5 | LL | let mut a = A::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: field assignment outside of initializer for an instance created with Default::default() - --> $DIR/field_reassign_with_default.rs:124:5 + --> $DIR/field_reassign_with_default.rs:117:5 | LL | a.i = Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: consider initializing the variable with `main::A { i: Default::default(), ..Default::default() }` and removing relevant reassignments - --> $DIR/field_reassign_with_default.rs:123:5 + --> $DIR/field_reassign_with_default.rs:116:5 | LL | let mut a: A = Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: field assignment outside of initializer for an instance created with Default::default() - --> $DIR/field_reassign_with_default.rs:128:5 + --> $DIR/field_reassign_with_default.rs:121:5 | LL | a.i = Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | note: consider initializing the variable with `main::A { i: Default::default(), j: 45 }` and removing relevant reassignments - --> $DIR/field_reassign_with_default.rs:127:5 + --> $DIR/field_reassign_with_default.rs:120:5 | LL | let mut a: A = Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: field assignment outside of initializer for an instance created with Default::default() - --> $DIR/field_reassign_with_default.rs:150:5 + --> $DIR/field_reassign_with_default.rs:143:5 | LL | a.i = vec![1]; | ^^^^^^^^^^^^^^ | note: consider initializing the variable with `C { i: vec![1], ..Default::default() }` and removing relevant reassignments - --> $DIR/field_reassign_with_default.rs:149:5 + --> $DIR/field_reassign_with_default.rs:142:5 | LL | let mut a: C = C::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: field assignment outside of initializer for an instance created with Default::default() - --> $DIR/field_reassign_with_default.rs:157:5 + --> $DIR/field_reassign_with_default.rs:161:5 | LL | a.i = true; | ^^^^^^^^^^^ | note: consider initializing the variable with `Wrapper:: { i: true }` and removing relevant reassignments - --> $DIR/field_reassign_with_default.rs:156:5 + --> $DIR/field_reassign_with_default.rs:160:5 | LL | let mut a: Wrapper = Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: field assignment outside of initializer for an instance created with Default::default() - --> $DIR/field_reassign_with_default.rs:160:5 + --> $DIR/field_reassign_with_default.rs:164:5 | LL | a.i = 42; | ^^^^^^^^^ | note: consider initializing the variable with `WrapperMulti:: { i: 42, ..Default::default() }` and removing relevant reassignments - --> $DIR/field_reassign_with_default.rs:159:5 + --> $DIR/field_reassign_with_default.rs:163:5 | LL | let mut a: WrapperMulti = Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: field assignment outside of initializer for an instance created with Default::default() - --> $DIR/field_reassign_with_default.rs:229:13 + --> $DIR/field_reassign_with_default.rs:235:13 | LL | f.name = name.len(); | ^^^^^^^^^^^^^^^^^^^^ | note: consider initializing the variable with `issue6312::ImplDropAllCopy { name: name.len(), ..Default::default() }` and removing relevant reassignments - --> $DIR/field_reassign_with_default.rs:228:13 + --> $DIR/field_reassign_with_default.rs:234:13 | LL | let mut f = ImplDropAllCopy::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: field assignment outside of initializer for an instance created with Default::default() - --> $DIR/field_reassign_with_default.rs:245:13 + --> $DIR/field_reassign_with_default.rs:251:13 | LL | f.name = name.len(); | ^^^^^^^^^^^^^^^^^^^^ | note: consider initializing the variable with `issue6312::NoDropAllCopy { name: name.len(), ..Default::default() }` and removing relevant reassignments - --> $DIR/field_reassign_with_default.rs:244:13 + --> $DIR/field_reassign_with_default.rs:250:13 | LL | let mut f = NoDropAllCopy::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/implicit_hasher.rs b/tests/ui/implicit_hasher.rs index fd96ca3f466..35d08a07bc3 100644 --- a/tests/ui/implicit_hasher.rs +++ b/tests/ui/implicit_hasher.rs @@ -1,9 +1,11 @@ -// aux-build:implicit_hasher_macros.rs +// aux-build:proc_macros.rs + #![deny(clippy::implicit_hasher)] #![allow(unused)] #[macro_use] -extern crate implicit_hasher_macros; +extern crate proc_macros; +use proc_macros::external; use std::cmp::Eq; use std::collections::{HashMap, HashSet}; @@ -68,22 +70,19 @@ impl Foo for HashSet { pub fn foo(_map: &mut HashMap, _set: &mut HashSet) {} -macro_rules! gen { - (impl) => { +#[proc_macros::inline_macros] +pub mod gen { + use super::*; + inline! { impl Foo for HashMap { fn make() -> (Self, Self) { (HashMap::new(), HashMap::with_capacity(10)) } } - }; - (fn $name:ident) => { - pub fn $name(_map: &mut HashMap, _set: &mut HashSet) {} - }; + pub fn bar(_map: &mut HashMap, _set: &mut HashSet) {} + } } -#[rustfmt::skip] -gen!(impl); -gen!(fn bar); // When the macro is in a different file, the suggestion spans can't be combined properly // and should not cause an ICE @@ -94,7 +93,9 @@ pub mod test_macro; __implicit_hasher_test_macro!(impl for HashMap where V: test_macro::A); // #4260 -implicit_hasher_fn!(); +external! { + pub fn f(input: &HashMap) {} +} // #7712 pub async fn election_vote(_data: HashMap) {} diff --git a/tests/ui/implicit_hasher.stderr b/tests/ui/implicit_hasher.stderr index 59b0fba2a4c..83b46de2eb5 100644 --- a/tests/ui/implicit_hasher.stderr +++ b/tests/ui/implicit_hasher.stderr @@ -1,11 +1,11 @@ error: impl for `HashMap` should be generalized over different hashers - --> $DIR/implicit_hasher.rs:16:35 + --> $DIR/implicit_hasher.rs:18:35 | LL | impl Foo for HashMap { | ^^^^^^^^^^^^^ | note: the lint level is defined here - --> $DIR/implicit_hasher.rs:2:9 + --> $DIR/implicit_hasher.rs:3:9 | LL | #![deny(clippy::implicit_hasher)] | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -19,7 +19,7 @@ LL | (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default: | ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: impl for `HashMap` should be generalized over different hashers - --> $DIR/implicit_hasher.rs:25:36 + --> $DIR/implicit_hasher.rs:27:36 | LL | impl Foo for (HashMap,) { | ^^^^^^^^^^^^^ @@ -34,7 +34,7 @@ LL | ((HashMap::default(),), (HashMap::with_capacity_and_hasher(10, Defa | ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: impl for `HashMap` should be generalized over different hashers - --> $DIR/implicit_hasher.rs:30:19 + --> $DIR/implicit_hasher.rs:32:19 | LL | impl Foo for HashMap { | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default: | ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: impl for `HashSet` should be generalized over different hashers - --> $DIR/implicit_hasher.rs:47:32 + --> $DIR/implicit_hasher.rs:49:32 | LL | impl Foo for HashSet { | ^^^^^^^^^^ @@ -64,7 +64,7 @@ LL | (HashSet::default(), HashSet::with_capacity_and_hasher(10, Default: | ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: impl for `HashSet` should be generalized over different hashers - --> $DIR/implicit_hasher.rs:52:19 + --> $DIR/implicit_hasher.rs:54:19 | LL | impl Foo for HashSet { | ^^^^^^^^^^^^^^^ @@ -79,7 +79,7 @@ LL | (HashSet::default(), HashSet::with_capacity_and_hasher(10, Default: | ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: parameter of type `HashMap` should be generalized over different hashers - --> $DIR/implicit_hasher.rs:69:23 + --> $DIR/implicit_hasher.rs:71:23 | LL | pub fn foo(_map: &mut HashMap, _set: &mut HashSet) {} | ^^^^^^^^^^^^^^^^^ @@ -90,7 +90,7 @@ LL | pub fn foo(_map: &mut HashMap, _s | +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~~~~~~ error: parameter of type `HashSet` should be generalized over different hashers - --> $DIR/implicit_hasher.rs:69:53 + --> $DIR/implicit_hasher.rs:71:53 | LL | pub fn foo(_map: &mut HashMap, _set: &mut HashSet) {} | ^^^^^^^^^^^^ @@ -101,15 +101,12 @@ LL | pub fn foo(_map: &mut HashMap, _set: | +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~ error: impl for `HashMap` should be generalized over different hashers - --> $DIR/implicit_hasher.rs:73:43 + --> $DIR/implicit_hasher.rs:77:43 | LL | impl Foo for HashMap { | ^^^^^^^^^^^^^ -... -LL | gen!(impl); - | ---------- in this macro invocation | - = note: this error originates in the macro `gen` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_mod_gen` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider adding a type parameter | LL | impl Foo for HashMap { @@ -120,37 +117,31 @@ LL | (HashMap::default(), HashMap::with_capacity_and_hasher(10, | ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: parameter of type `HashMap` should be generalized over different hashers - --> $DIR/implicit_hasher.rs:81:33 + --> $DIR/implicit_hasher.rs:83:31 | -LL | pub fn $name(_map: &mut HashMap, _set: &mut HashSet) {} - | ^^^^^^^^^^^^^^^^^ -... -LL | gen!(fn bar); - | ------------ in this macro invocation +LL | pub fn bar(_map: &mut HashMap, _set: &mut HashSet) {} + | ^^^^^^^^^^^^^^^^^ | - = note: this error originates in the macro `gen` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_mod_gen` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider adding a type parameter | -LL | pub fn $name(_map: &mut HashMap, _set: &mut HashSet) {} - | +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~~~~~~ +LL | pub fn bar(_map: &mut HashMap, _set: &mut HashSet) {} + | +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~~~~~~ error: parameter of type `HashSet` should be generalized over different hashers - --> $DIR/implicit_hasher.rs:81:63 + --> $DIR/implicit_hasher.rs:83:61 | -LL | pub fn $name(_map: &mut HashMap, _set: &mut HashSet) {} - | ^^^^^^^^^^^^ -... -LL | gen!(fn bar); - | ------------ in this macro invocation +LL | pub fn bar(_map: &mut HashMap, _set: &mut HashSet) {} + | ^^^^^^^^^^^^ | - = note: this error originates in the macro `gen` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_mod_gen` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider adding a type parameter | -LL | pub fn $name(_map: &mut HashMap, _set: &mut HashSet) {} - | +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~ +LL | pub fn bar(_map: &mut HashMap, _set: &mut HashSet) {} + | +++++++++++++++++++++++++++++ ~~~~~~~~~~~~~~~ error: parameter of type `HashMap` should be generalized over different hashers - --> $DIR/implicit_hasher.rs:100:35 + --> $DIR/implicit_hasher.rs:101:35 | LL | pub async fn election_vote(_data: HashMap) {} | ^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/inconsistent_struct_constructor.fixed b/tests/ui/inconsistent_struct_constructor.fixed index 74ba2f1c5e7..5aaa00f8517 100644 --- a/tests/ui/inconsistent_struct_constructor.fixed +++ b/tests/ui/inconsistent_struct_constructor.fixed @@ -1,10 +1,14 @@ // run-rustfix +// aux-build:proc_macros.rs + #![warn(clippy::inconsistent_struct_constructor)] #![allow(clippy::redundant_field_names)] #![allow(clippy::unnecessary_operation)] #![allow(clippy::no_effect)] #![allow(dead_code)] +extern crate proc_macros; + #[derive(Default)] struct Foo { x: i32, @@ -12,18 +16,10 @@ struct Foo { z: i32, } -macro_rules! new_foo { - () => { - let x = 1; - let y = 1; - let z = 1; - Foo { y, x, z } - }; -} - mod without_base { use super::Foo; + #[proc_macros::inline_macros] fn test() { let x = 1; let y = 1; @@ -34,7 +30,12 @@ mod without_base { // Should NOT lint. // issue #7069. - new_foo!(); + inline!({ + let x = 1; + let y = 1; + let z = 1; + Foo { y, x, z } + }); // Should NOT lint because the order is the same as in the definition. Foo { x, y, z }; diff --git a/tests/ui/inconsistent_struct_constructor.rs b/tests/ui/inconsistent_struct_constructor.rs index ba96e1e330f..2b2dd7f59a4 100644 --- a/tests/ui/inconsistent_struct_constructor.rs +++ b/tests/ui/inconsistent_struct_constructor.rs @@ -1,10 +1,14 @@ // run-rustfix +// aux-build:proc_macros.rs + #![warn(clippy::inconsistent_struct_constructor)] #![allow(clippy::redundant_field_names)] #![allow(clippy::unnecessary_operation)] #![allow(clippy::no_effect)] #![allow(dead_code)] +extern crate proc_macros; + #[derive(Default)] struct Foo { x: i32, @@ -12,18 +16,10 @@ struct Foo { z: i32, } -macro_rules! new_foo { - () => { - let x = 1; - let y = 1; - let z = 1; - Foo { y, x, z } - }; -} - mod without_base { use super::Foo; + #[proc_macros::inline_macros] fn test() { let x = 1; let y = 1; @@ -34,7 +30,12 @@ mod without_base { // Should NOT lint. // issue #7069. - new_foo!(); + inline!({ + let x = 1; + let y = 1; + let z = 1; + Foo { y, x, z } + }); // Should NOT lint because the order is the same as in the definition. Foo { x, y, z }; diff --git a/tests/ui/inconsistent_struct_constructor.stderr b/tests/ui/inconsistent_struct_constructor.stderr index c90189e964f..785a6dc9d53 100644 --- a/tests/ui/inconsistent_struct_constructor.stderr +++ b/tests/ui/inconsistent_struct_constructor.stderr @@ -1,5 +1,5 @@ error: struct constructor field order is inconsistent with struct definition field order - --> $DIR/inconsistent_struct_constructor.rs:33:9 + --> $DIR/inconsistent_struct_constructor.rs:29:9 | LL | Foo { y, x, z }; | ^^^^^^^^^^^^^^^ help: try: `Foo { x, y, z }` @@ -7,7 +7,7 @@ LL | Foo { y, x, z }; = note: `-D clippy::inconsistent-struct-constructor` implied by `-D warnings` error: struct constructor field order is inconsistent with struct definition field order - --> $DIR/inconsistent_struct_constructor.rs:55:9 + --> $DIR/inconsistent_struct_constructor.rs:56:9 | LL | / Foo { LL | | z, diff --git a/tests/ui/large_enum_variant.rs b/tests/ui/large_enum_variant.rs index 3b96f09d7b1..f09f8ae0ccc 100644 --- a/tests/ui/large_enum_variant.rs +++ b/tests/ui/large_enum_variant.rs @@ -1,11 +1,11 @@ -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![allow(dead_code)] #![allow(unused_variables)] #![warn(clippy::large_enum_variant)] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::external; enum LargeEnum { A(i32), @@ -155,5 +155,10 @@ enum LargeEnumOfConst { } fn main() { - large_enum_variant!(); + external!( + enum LargeEnumInMacro { + A(i32), + B([i32; 8000]), + } + ); } diff --git a/tests/ui/macro_use_imports.fixed b/tests/ui/macro_use_imports.fixed index e612480d264..15f7a099a7d 100644 --- a/tests/ui/macro_use_imports.fixed +++ b/tests/ui/macro_use_imports.fixed @@ -20,7 +20,7 @@ mod a { use mac; use mini_mac::ClippyMiniMacroTest; use mini_mac; - use mac::{inner::foofoo, inner::try_err}; + use mac::{inner::mut_mut, inner::try_err}; use mac::inner; use mac::inner::nested::string_add; use mac::inner::nested; @@ -36,7 +36,7 @@ mod a { let v: ty_macro!() = Vec::default(); inner::try_err!(); - inner::foofoo!(); + inner::mut_mut!(); nested::string_add!(); } } diff --git a/tests/ui/macro_use_imports.rs b/tests/ui/macro_use_imports.rs index b34817cc3b2..b1a28733294 100644 --- a/tests/ui/macro_use_imports.rs +++ b/tests/ui/macro_use_imports.rs @@ -36,7 +36,7 @@ mod a { let v: ty_macro!() = Vec::default(); inner::try_err!(); - inner::foofoo!(); + inner::mut_mut!(); nested::string_add!(); } } diff --git a/tests/ui/macro_use_imports.stderr b/tests/ui/macro_use_imports.stderr index 61843124ccd..68d558dede0 100644 --- a/tests/ui/macro_use_imports.stderr +++ b/tests/ui/macro_use_imports.stderr @@ -16,7 +16,7 @@ error: `macro_use` attributes are no longer needed in the Rust 2018 edition --> $DIR/macro_use_imports.rs:23:5 | LL | #[macro_use] - | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{inner::foofoo, inner::try_err};` + | ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use mac::{inner::mut_mut, inner::try_err};` error: `macro_use` attributes are no longer needed in the Rust 2018 edition --> $DIR/macro_use_imports.rs:19:5 diff --git a/tests/ui/macro_use_imports_expect.rs b/tests/ui/macro_use_imports_expect.rs index 8a1b05da9ef..5aac5af26db 100644 --- a/tests/ui/macro_use_imports_expect.rs +++ b/tests/ui/macro_use_imports_expect.rs @@ -39,7 +39,7 @@ mod a { let v: ty_macro!() = Vec::default(); inner::try_err!(); - inner::foofoo!(); + inner::mut_mut!(); nested::string_add!(); } } diff --git a/tests/ui/manual_rem_euclid.fixed b/tests/ui/manual_rem_euclid.fixed index 6916a284a20..1f6df1b0a86 100644 --- a/tests/ui/manual_rem_euclid.fixed +++ b/tests/ui/manual_rem_euclid.fixed @@ -1,19 +1,13 @@ // run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::manual_rem_euclid)] #![allow(clippy::let_with_type_underscore)] -#[macro_use] -extern crate macro_rules; - -macro_rules! internal_rem_euclid { - () => { - let value: i32 = 5; - let _: i32 = value.rem_euclid(4); - }; -} +extern crate proc_macros; +use proc_macros::{external, inline_macros}; +#[inline_macros] fn main() { let value: i32 = 5; @@ -39,10 +33,16 @@ fn main() { let _: i32 = ((4 % value) + 4) % 4; // Lint in internal macros - internal_rem_euclid!(); + inline!( + let value: i32 = 5; + let _: i32 = value.rem_euclid(4); + ); // Do not lint in external macros - manual_rem_euclid!(); + external!( + let value: i32 = 5; + let _: i32 = ((value % 4) + 4) % 4; + ); } // Should lint for params too diff --git a/tests/ui/manual_rem_euclid.rs b/tests/ui/manual_rem_euclid.rs index 412dbddb426..b275e8a38d2 100644 --- a/tests/ui/manual_rem_euclid.rs +++ b/tests/ui/manual_rem_euclid.rs @@ -1,19 +1,13 @@ // run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::manual_rem_euclid)] #![allow(clippy::let_with_type_underscore)] -#[macro_use] -extern crate macro_rules; - -macro_rules! internal_rem_euclid { - () => { - let value: i32 = 5; - let _: i32 = ((value % 4) + 4) % 4; - }; -} +extern crate proc_macros; +use proc_macros::{external, inline_macros}; +#[inline_macros] fn main() { let value: i32 = 5; @@ -39,10 +33,16 @@ fn main() { let _: i32 = ((4 % value) + 4) % 4; // Lint in internal macros - internal_rem_euclid!(); + inline!( + let value: i32 = 5; + let _: i32 = ((value % 4) + 4) % 4; + ); // Do not lint in external macros - manual_rem_euclid!(); + external!( + let value: i32 = 5; + let _: i32 = ((value % 4) + 4) % 4; + ); } // Should lint for params too diff --git a/tests/ui/manual_rem_euclid.stderr b/tests/ui/manual_rem_euclid.stderr index 6d06654638b..a43707f89c4 100644 --- a/tests/ui/manual_rem_euclid.stderr +++ b/tests/ui/manual_rem_euclid.stderr @@ -1,5 +1,5 @@ error: manual `rem_euclid` implementation - --> $DIR/manual_rem_euclid.rs:20:18 + --> $DIR/manual_rem_euclid.rs:14:18 | LL | let _: i32 = ((value % 4) + 4) % 4; | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)` @@ -7,39 +7,36 @@ LL | let _: i32 = ((value % 4) + 4) % 4; = note: `-D clippy::manual-rem-euclid` implied by `-D warnings` error: manual `rem_euclid` implementation - --> $DIR/manual_rem_euclid.rs:21:18 + --> $DIR/manual_rem_euclid.rs:15:18 | LL | let _: i32 = (4 + (value % 4)) % 4; | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)` error: manual `rem_euclid` implementation - --> $DIR/manual_rem_euclid.rs:22:18 + --> $DIR/manual_rem_euclid.rs:16:18 | LL | let _: i32 = (value % 4 + 4) % 4; | ^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)` error: manual `rem_euclid` implementation - --> $DIR/manual_rem_euclid.rs:23:18 + --> $DIR/manual_rem_euclid.rs:17:18 | LL | let _: i32 = (4 + value % 4) % 4; | ^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)` error: manual `rem_euclid` implementation - --> $DIR/manual_rem_euclid.rs:24:22 + --> $DIR/manual_rem_euclid.rs:18:22 | LL | let _: i32 = 1 + (4 + value % 4) % 4; | ^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)` error: manual `rem_euclid` implementation - --> $DIR/manual_rem_euclid.rs:13:22 + --> $DIR/manual_rem_euclid.rs:38:22 | LL | let _: i32 = ((value % 4) + 4) % 4; | ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `value.rem_euclid(4)` -... -LL | internal_rem_euclid!(); - | ---------------------- in this macro invocation | - = note: this error originates in the macro `internal_rem_euclid` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: manual `rem_euclid` implementation --> $DIR/manual_rem_euclid.rs:50:5 diff --git a/tests/ui/mem_replace_macro.rs b/tests/ui/mem_replace_macro.rs index 0c09344b80d..3932e7d00c1 100644 --- a/tests/ui/mem_replace_macro.rs +++ b/tests/ui/mem_replace_macro.rs @@ -1,21 +1,12 @@ -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::mem_replace_with_default)] -#[macro_use] -extern crate macro_rules; - -macro_rules! take { - ($s:expr) => { - std::mem::replace($s, Default::default()) - }; -} - -fn replace_with_default() { - let s = &mut String::from("foo"); - take!(s); - take_external!(s); -} +extern crate proc_macros; +use proc_macros::{external, inline_macros}; +#[inline_macros] fn main() { - replace_with_default(); + let s = &mut String::from("foo"); + inline!(std::mem::replace($s, Default::default())); + external!(std::mem::replace($s, Default::default())); } diff --git a/tests/ui/mem_replace_macro.stderr b/tests/ui/mem_replace_macro.stderr index dd69ab8b5ef..35dda93da3d 100644 --- a/tests/ui/mem_replace_macro.stderr +++ b/tests/ui/mem_replace_macro.stderr @@ -1,14 +1,11 @@ error: replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take` - --> $DIR/mem_replace_macro.rs:9:9 + --> $DIR/mem_replace_macro.rs:10:13 | -LL | std::mem::replace($s, Default::default()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -... -LL | take!(s); - | -------- in this macro invocation +LL | inline!(std::mem::replace($s, Default::default())); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `-D clippy::mem-replace-with-default` implied by `-D warnings` - = note: this error originates in the macro `take` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/tests/ui/missing_const_for_fn/cant_be_const.rs b/tests/ui/missing_const_for_fn/cant_be_const.rs index 75cace18167..e6f88c6e622 100644 --- a/tests/ui/missing_const_for_fn/cant_be_const.rs +++ b/tests/ui/missing_const_for_fn/cant_be_const.rs @@ -3,15 +3,15 @@ //! The .stderr output of this test should be empty. Otherwise it's a bug somewhere. // aux-build:helper.rs -// aux-build:../../auxiliary/proc_macro_with_span.rs +// aux-build:../../auxiliary/proc_macros.rs #![warn(clippy::missing_const_for_fn)] #![feature(start)] extern crate helper; -extern crate proc_macro_with_span; +extern crate proc_macros; -use proc_macro_with_span::with_span; +use proc_macros::with_span; struct Game; diff --git a/tests/ui/missing_doc.rs b/tests/ui/missing_doc.rs index 590ad63c90b..5752048949c 100644 --- a/tests/ui/missing_doc.rs +++ b/tests/ui/missing_doc.rs @@ -1,5 +1,5 @@ // needs-asm-support -// aux-build: proc_macro_with_span.rs +// aux-build: proc_macros.rs #![warn(clippy::missing_docs_in_private_items)] // When denying at the crate level, be sure to not get random warnings from the @@ -8,9 +8,9 @@ //! Some garbage docs for the crate here #![doc = "More garbage"] -extern crate proc_macro_with_span; +extern crate proc_macros; -use proc_macro_with_span::with_span; +use proc_macros::with_span; use std::arch::global_asm; type Typedef = String; diff --git a/tests/ui/missing_doc_impl.rs b/tests/ui/missing_doc_impl.rs index 0396d1193ff..e2d49b0907d 100644 --- a/tests/ui/missing_doc_impl.rs +++ b/tests/ui/missing_doc_impl.rs @@ -1,4 +1,4 @@ -// aux-build: proc_macro_with_span.rs +// aux-build: proc_macros.rs #![warn(clippy::missing_docs_in_private_items)] #![allow(dead_code)] @@ -7,8 +7,8 @@ //! Some garbage docs for the crate here #![doc = "More garbage"] -extern crate proc_macro_with_span; -use proc_macro_with_span::with_span; +extern crate proc_macros; +use proc_macros::with_span; struct Foo { a: isize, diff --git a/tests/ui/mistyped_literal_suffix.fixed b/tests/ui/mistyped_literal_suffix.fixed index becb9562a84..9a47d7c56ed 100644 --- a/tests/ui/mistyped_literal_suffix.fixed +++ b/tests/ui/mistyped_literal_suffix.fixed @@ -1,5 +1,5 @@ // run-rustfix -// aux-build: proc_macro_with_span.rs +// aux-build: proc_macros.rs #![allow( dead_code, @@ -10,8 +10,8 @@ clippy::unusual_byte_groupings )] -extern crate proc_macro_with_span; -use proc_macro_with_span::with_span; +extern crate proc_macros; +use proc_macros::with_span; fn main() { let fail14 = 2_i32; diff --git a/tests/ui/mistyped_literal_suffix.rs b/tests/ui/mistyped_literal_suffix.rs index ee841bcd7e4..04261cba55a 100644 --- a/tests/ui/mistyped_literal_suffix.rs +++ b/tests/ui/mistyped_literal_suffix.rs @@ -1,5 +1,5 @@ // run-rustfix -// aux-build: proc_macro_with_span.rs +// aux-build: proc_macros.rs #![allow( dead_code, @@ -10,8 +10,8 @@ clippy::unusual_byte_groupings )] -extern crate proc_macro_with_span; -use proc_macro_with_span::with_span; +extern crate proc_macros; +use proc_macros::with_span; fn main() { let fail14 = 2_32; diff --git a/tests/ui/multiple_unsafe_ops_per_block.rs b/tests/ui/multiple_unsafe_ops_per_block.rs index 5073685c9f0..9082f1675a8 100644 --- a/tests/ui/multiple_unsafe_ops_per_block.rs +++ b/tests/ui/multiple_unsafe_ops_per_block.rs @@ -1,12 +1,12 @@ -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![allow(unused)] #![allow(deref_nullptr)] #![allow(clippy::unnecessary_operation)] #![allow(clippy::drop_copy)] #![warn(clippy::multiple_unsafe_ops_per_block)] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::external; use core::arch::asm; @@ -113,7 +113,10 @@ unsafe fn read_char_good(ptr: *const u8) -> char { // no lint fn issue10259() { - unsafe_macro!(); + external!(unsafe { + *core::ptr::null::<()>(); + *core::ptr::null::<()>(); + }); } fn _fn_ptr(x: unsafe fn()) { diff --git a/tests/ui/multiple_unsafe_ops_per_block.stderr b/tests/ui/multiple_unsafe_ops_per_block.stderr index e0c1d3801f7..badc284ec42 100644 --- a/tests/ui/multiple_unsafe_ops_per_block.stderr +++ b/tests/ui/multiple_unsafe_ops_per_block.stderr @@ -126,7 +126,7 @@ LL | unsafe { char::from_u32_unchecked(*ptr.cast::()) } | ^^^^^^^^^^^^^^^^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one - --> $DIR/multiple_unsafe_ops_per_block.rs:120:5 + --> $DIR/multiple_unsafe_ops_per_block.rs:123:5 | LL | / unsafe { LL | | x(); @@ -135,18 +135,18 @@ LL | | } | |_____^ | note: unsafe function call occurs here - --> $DIR/multiple_unsafe_ops_per_block.rs:121:9 + --> $DIR/multiple_unsafe_ops_per_block.rs:124:9 | LL | x(); | ^^^ note: unsafe function call occurs here - --> $DIR/multiple_unsafe_ops_per_block.rs:122:9 + --> $DIR/multiple_unsafe_ops_per_block.rs:125:9 | LL | x(); | ^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one - --> $DIR/multiple_unsafe_ops_per_block.rs:131:9 + --> $DIR/multiple_unsafe_ops_per_block.rs:134:9 | LL | / unsafe { LL | | T::X(); @@ -155,18 +155,18 @@ LL | | } | |_________^ | note: unsafe function call occurs here - --> $DIR/multiple_unsafe_ops_per_block.rs:132:13 + --> $DIR/multiple_unsafe_ops_per_block.rs:135:13 | LL | T::X(); | ^^^^^^ note: unsafe function call occurs here - --> $DIR/multiple_unsafe_ops_per_block.rs:133:13 + --> $DIR/multiple_unsafe_ops_per_block.rs:136:13 | LL | T::X(); | ^^^^^^ error: this `unsafe` block contains 2 unsafe operations, expected only one - --> $DIR/multiple_unsafe_ops_per_block.rs:141:5 + --> $DIR/multiple_unsafe_ops_per_block.rs:144:5 | LL | / unsafe { LL | | x.0(); @@ -175,12 +175,12 @@ LL | | } | |_____^ | note: unsafe function call occurs here - --> $DIR/multiple_unsafe_ops_per_block.rs:142:9 + --> $DIR/multiple_unsafe_ops_per_block.rs:145:9 | LL | x.0(); | ^^^^^ note: unsafe function call occurs here - --> $DIR/multiple_unsafe_ops_per_block.rs:143:9 + --> $DIR/multiple_unsafe_ops_per_block.rs:146:9 | LL | x.0(); | ^^^^^ diff --git a/tests/ui/must_use_unit.fixed b/tests/ui/must_use_unit.fixed index 6c9aa434ac0..b7d375ff80e 100644 --- a/tests/ui/must_use_unit.fixed +++ b/tests/ui/must_use_unit.fixed @@ -1,11 +1,11 @@ //run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::must_use_unit)] #![allow(clippy::unused_unit)] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::external; pub fn must_use_default() {} @@ -22,5 +22,8 @@ fn main() { must_use_with_note(); // We should not lint in external macros - must_use_unit!(); + external!( + #[must_use] + fn foo() {} + ); } diff --git a/tests/ui/must_use_unit.rs b/tests/ui/must_use_unit.rs index 8a395dc284d..74d6b4ca865 100644 --- a/tests/ui/must_use_unit.rs +++ b/tests/ui/must_use_unit.rs @@ -1,11 +1,11 @@ //run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::must_use_unit)] #![allow(clippy::unused_unit)] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::external; #[must_use] pub fn must_use_default() {} @@ -22,5 +22,8 @@ fn main() { must_use_with_note(); // We should not lint in external macros - must_use_unit!(); + external!( + #[must_use] + fn foo() {} + ); } diff --git a/tests/ui/mut_mut.rs b/tests/ui/mut_mut.rs index ee3a856566c..06bb085442a 100644 --- a/tests/ui/mut_mut.rs +++ b/tests/ui/mut_mut.rs @@ -1,10 +1,10 @@ -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::mut_mut)] #![allow(unused)] #![allow(clippy::no_effect, clippy::uninlined_format_args, clippy::unnecessary_operation)] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::{external, inline_macros}; fn fun(x: &mut &mut u32) -> bool { **x > 0 @@ -21,6 +21,7 @@ macro_rules! mut_ptr { } #[allow(unused_mut, unused_variables)] +#[inline_macros] fn main() { let mut x = &mut &mut 1u32; { @@ -37,7 +38,7 @@ fn main() { ***y + **x; } - let mut z = mut_ptr!(&mut 3u32); + let mut z = inline!(&mut $(&mut 3u32)); } fn issue939() { @@ -55,7 +56,7 @@ fn issue939() { fn issue6922() { // do not lint from an external macro - mut_mut!(); + external!(let mut_mut_ty: &mut &mut u32 = &mut &mut 1u32;); } mod issue9035 { diff --git a/tests/ui/mut_mut.stderr b/tests/ui/mut_mut.stderr index 6820a85aa54..93b857eb207 100644 --- a/tests/ui/mut_mut.stderr +++ b/tests/ui/mut_mut.stderr @@ -7,54 +7,51 @@ LL | fn fun(x: &mut &mut u32) -> bool { = note: `-D clippy::mut-mut` implied by `-D warnings` error: generally you want to avoid `&mut &mut _` if possible - --> $DIR/mut_mut.rs:25:17 + --> $DIR/mut_mut.rs:26:17 | LL | let mut x = &mut &mut 1u32; | ^^^^^^^^^^^^^^ error: generally you want to avoid `&mut &mut _` if possible - --> $DIR/mut_mut.rs:19:9 + --> $DIR/mut_mut.rs:41:25 | -LL | &mut $p - | ^^^^^^^ -... -LL | let mut z = mut_ptr!(&mut 3u32); - | ------------------- in this macro invocation +LL | let mut z = inline!(&mut $(&mut 3u32)); + | ^ | - = note: this error originates in the macro `mut_ptr` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: this expression mutably borrows a mutable reference. Consider reborrowing - --> $DIR/mut_mut.rs:27:21 + --> $DIR/mut_mut.rs:28:21 | LL | let mut y = &mut x; | ^^^^^^ error: generally you want to avoid `&mut &mut _` if possible - --> $DIR/mut_mut.rs:31:32 + --> $DIR/mut_mut.rs:32:32 | LL | let y: &mut &mut u32 = &mut &mut 2; | ^^^^^^^^^^^ error: generally you want to avoid `&mut &mut _` if possible - --> $DIR/mut_mut.rs:31:16 + --> $DIR/mut_mut.rs:32:16 | LL | let y: &mut &mut u32 = &mut &mut 2; | ^^^^^^^^^^^^^ error: generally you want to avoid `&mut &mut _` if possible - --> $DIR/mut_mut.rs:36:37 + --> $DIR/mut_mut.rs:37:37 | LL | let y: &mut &mut &mut u32 = &mut &mut &mut 2; | ^^^^^^^^^^^^^^^^ error: generally you want to avoid `&mut &mut _` if possible - --> $DIR/mut_mut.rs:36:16 + --> $DIR/mut_mut.rs:37:16 | LL | let y: &mut &mut &mut u32 = &mut &mut &mut 2; | ^^^^^^^^^^^^^^^^^^ error: generally you want to avoid `&mut &mut _` if possible - --> $DIR/mut_mut.rs:36:21 + --> $DIR/mut_mut.rs:37:21 | LL | let y: &mut &mut &mut u32 = &mut &mut &mut 2; | ^^^^^^^^^^^^^ diff --git a/tests/ui/needless_late_init.fixed b/tests/ui/needless_late_init.fixed index 17f2227ba91..86d899bb46c 100644 --- a/tests/ui/needless_late_init.fixed +++ b/tests/ui/needless_late_init.fixed @@ -1,4 +1,5 @@ // run-rustfix +// aux-build:proc_macros.rs #![feature(let_chains)] #![allow(unused)] #![allow( @@ -10,6 +11,8 @@ clippy::uninlined_format_args )] +extern crate proc_macros; + use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::rc::Rc; @@ -138,6 +141,7 @@ const fn in_const() -> &'static str { a } +#[proc_macros::inline_macros] fn does_not_lint() { let z; if false { @@ -195,35 +199,27 @@ fn does_not_lint() { } y = 3; - macro_rules! assign { - ($i:ident) => { - $i = 1; - }; - } let x; - assign!(x); + inline!($x = 1;); let x; if true { - assign!(x); + inline!($x = 1;); } else { x = 2; } - macro_rules! in_macro { - () => { - let x; - x = 1; + inline!({ + let x; + x = 1; - let x; - if true { - x = 1; - } else { - x = 2; - } - }; - } - in_macro!(); + let x; + if true { + x = 1; + } else { + x = 2; + } + }); // ignore if-lets - https://github.com/rust-lang/rust-clippy/issues/8613 let x; diff --git a/tests/ui/needless_late_init.rs b/tests/ui/needless_late_init.rs index d84457a2987..969afb38edf 100644 --- a/tests/ui/needless_late_init.rs +++ b/tests/ui/needless_late_init.rs @@ -1,4 +1,5 @@ // run-rustfix +// aux-build:proc_macros.rs #![feature(let_chains)] #![allow(unused)] #![allow( @@ -10,6 +11,8 @@ clippy::uninlined_format_args )] +extern crate proc_macros; + use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet}; use std::rc::Rc; @@ -138,6 +141,7 @@ const fn in_const() -> &'static str { a } +#[proc_macros::inline_macros] fn does_not_lint() { let z; if false { @@ -195,35 +199,27 @@ fn does_not_lint() { } y = 3; - macro_rules! assign { - ($i:ident) => { - $i = 1; - }; - } let x; - assign!(x); + inline!($x = 1;); let x; if true { - assign!(x); + inline!($x = 1;); } else { x = 2; } - macro_rules! in_macro { - () => { - let x; - x = 1; + inline!({ + let x; + x = 1; - let x; - if true { - x = 1; - } else { - x = 2; - } - }; - } - in_macro!(); + let x; + if true { + x = 1; + } else { + x = 2; + } + }); // ignore if-lets - https://github.com/rust-lang/rust-clippy/issues/8613 let x; diff --git a/tests/ui/needless_late_init.stderr b/tests/ui/needless_late_init.stderr index 0a256fb4a13..eff782f8bf1 100644 --- a/tests/ui/needless_late_init.stderr +++ b/tests/ui/needless_late_init.stderr @@ -1,5 +1,5 @@ error: unneeded late initialization - --> $DIR/needless_late_init.rs:24:5 + --> $DIR/needless_late_init.rs:27:5 | LL | let a; | ^^^^^^ created here @@ -13,7 +13,7 @@ LL | let a = "zero"; | ~~~~~ error: unneeded late initialization - --> $DIR/needless_late_init.rs:27:5 + --> $DIR/needless_late_init.rs:30:5 | LL | let b; | ^^^^^^ created here @@ -27,7 +27,7 @@ LL | let b = 1; | ~~~~~ error: unneeded late initialization - --> $DIR/needless_late_init.rs:28:5 + --> $DIR/needless_late_init.rs:31:5 | LL | let c; | ^^^^^^ created here @@ -41,7 +41,7 @@ LL | let c = 2; | ~~~~~ error: unneeded late initialization - --> $DIR/needless_late_init.rs:32:5 + --> $DIR/needless_late_init.rs:35:5 | LL | let d: usize; | ^^^^^^^^^^^^^ created here @@ -54,7 +54,7 @@ LL | let d: usize = 1; | ~~~~~~~~~~~~ error: unneeded late initialization - --> $DIR/needless_late_init.rs:35:5 + --> $DIR/needless_late_init.rs:38:5 | LL | let e; | ^^^^^^ created here @@ -67,7 +67,7 @@ LL | let e = format!("{}", d); | ~~~~~ error: unneeded late initialization - --> $DIR/needless_late_init.rs:40:5 + --> $DIR/needless_late_init.rs:43:5 | LL | let a; | ^^^^^^ @@ -88,7 +88,7 @@ LL | }; | + error: unneeded late initialization - --> $DIR/needless_late_init.rs:49:5 + --> $DIR/needless_late_init.rs:52:5 | LL | let b; | ^^^^^^ @@ -109,7 +109,7 @@ LL | }; | + error: unneeded late initialization - --> $DIR/needless_late_init.rs:56:5 + --> $DIR/needless_late_init.rs:59:5 | LL | let d; | ^^^^^^ @@ -130,7 +130,7 @@ LL | }; | + error: unneeded late initialization - --> $DIR/needless_late_init.rs:64:5 + --> $DIR/needless_late_init.rs:67:5 | LL | let e; | ^^^^^^ @@ -151,7 +151,7 @@ LL | }; | + error: unneeded late initialization - --> $DIR/needless_late_init.rs:71:5 + --> $DIR/needless_late_init.rs:74:5 | LL | let f; | ^^^^^^ @@ -167,7 +167,7 @@ LL + 1 => "three", | error: unneeded late initialization - --> $DIR/needless_late_init.rs:77:5 + --> $DIR/needless_late_init.rs:80:5 | LL | let g: usize; | ^^^^^^^^^^^^^ @@ -187,7 +187,7 @@ LL | }; | + error: unneeded late initialization - --> $DIR/needless_late_init.rs:85:5 + --> $DIR/needless_late_init.rs:88:5 | LL | let x; | ^^^^^^ created here @@ -201,7 +201,7 @@ LL | let x = 1; | ~~~~~ error: unneeded late initialization - --> $DIR/needless_late_init.rs:89:5 + --> $DIR/needless_late_init.rs:92:5 | LL | let x; | ^^^^^^ created here @@ -215,7 +215,7 @@ LL | let x = SignificantDrop; | ~~~~~ error: unneeded late initialization - --> $DIR/needless_late_init.rs:93:5 + --> $DIR/needless_late_init.rs:96:5 | LL | let x; | ^^^^^^ created here @@ -229,7 +229,7 @@ LL | let x = SignificantDrop; | ~~~~~ error: unneeded late initialization - --> $DIR/needless_late_init.rs:112:5 + --> $DIR/needless_late_init.rs:115:5 | LL | let a; | ^^^^^^ @@ -250,7 +250,7 @@ LL | }; | + error: unneeded late initialization - --> $DIR/needless_late_init.rs:129:5 + --> $DIR/needless_late_init.rs:132:5 | LL | let a; | ^^^^^^ diff --git a/tests/ui/needless_lifetimes.fixed b/tests/ui/needless_lifetimes.fixed index f0f1f9298ac..e6ead69d148 100644 --- a/tests/ui/needless_lifetimes.fixed +++ b/tests/ui/needless_lifetimes.fixed @@ -1,5 +1,5 @@ // run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::needless_lifetimes)] #![allow( @@ -12,8 +12,8 @@ clippy::get_first )] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::inline_macros; fn distinct_lifetimes(_x: &u8, _y: &u8, _z: u8) {} @@ -502,30 +502,29 @@ mod pr_9743_output_lifetime_checks { } } +#[inline_macros] mod in_macro { - macro_rules! local_one_input_macro { - () => { - fn one_input(x: &u8) -> &u8 { - unimplemented!() - } - }; - } + use proc_macros::external; // lint local macro expands to function with needless lifetimes - local_one_input_macro!(); - - // no lint on external macro - macro_rules::needless_lifetime!(); - - macro_rules! expanded_lifetime { - ($l:lifetime) => { - fn f<$l>(arg: &$l str) -> &$l str { - arg - } + inline! { + fn one_input(x: &u8) -> &u8 { + unimplemented!() } } - expanded_lifetime!('a); + // no lint on external macro + external! { + fn needless_lifetime<'a>(x: &'a u8) -> &'a u8 { + unimplemented!() + } + } + + inline! { + fn f<$'a>(arg: &$'a str) -> &$'a str { + arg + } + } } mod issue5787 { diff --git a/tests/ui/needless_lifetimes.rs b/tests/ui/needless_lifetimes.rs index ddfd1043003..06eb430506f 100644 --- a/tests/ui/needless_lifetimes.rs +++ b/tests/ui/needless_lifetimes.rs @@ -1,5 +1,5 @@ // run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::needless_lifetimes)] #![allow( @@ -12,8 +12,8 @@ clippy::get_first )] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::inline_macros; fn distinct_lifetimes<'a, 'b>(_x: &'a u8, _y: &'b u8, _z: u8) {} @@ -502,30 +502,29 @@ mod pr_9743_output_lifetime_checks { } } +#[inline_macros] mod in_macro { - macro_rules! local_one_input_macro { - () => { - fn one_input<'a>(x: &'a u8) -> &'a u8 { - unimplemented!() - } - }; - } + use proc_macros::external; // lint local macro expands to function with needless lifetimes - local_one_input_macro!(); - - // no lint on external macro - macro_rules::needless_lifetime!(); - - macro_rules! expanded_lifetime { - ($l:lifetime) => { - fn f<$l>(arg: &$l str) -> &$l str { - arg - } + inline! { + fn one_input<'a>(x: &'a u8) -> &'a u8 { + unimplemented!() } } - expanded_lifetime!('a); + // no lint on external macro + external! { + fn needless_lifetime<'a>(x: &'a u8) -> &'a u8 { + unimplemented!() + } + } + + inline! { + fn f<$'a>(arg: &$'a str) -> &$'a str { + arg + } + } } mod issue5787 { diff --git a/tests/ui/needless_lifetimes.stderr b/tests/ui/needless_lifetimes.stderr index 4e3c8f20d8c..86acc4e0046 100644 --- a/tests/ui/needless_lifetimes.stderr +++ b/tests/ui/needless_lifetimes.stderr @@ -540,19 +540,16 @@ LL + fn multiple_inputs_output_not_elided<'b>(x: &u8, y: &'b u8, z: &'b u8) | error: the following explicit lifetimes could be elided: 'a - --> $DIR/needless_lifetimes.rs:508:13 + --> $DIR/needless_lifetimes.rs:511:9 | -LL | fn one_input<'a>(x: &'a u8) -> &'a u8 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -... -LL | local_one_input_macro!(); - | ------------------------ in this macro invocation +LL | fn one_input<'a>(x: &'a u8) -> &'a u8 { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: this error originates in the macro `local_one_input_macro` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_mod_in_macro` (in Nightly builds, run with -Z macro-backtrace for more info) help: elide the lifetimes | -LL - fn one_input<'a>(x: &'a u8) -> &'a u8 { -LL + fn one_input(x: &u8) -> &u8 { +LL - fn one_input<'a>(x: &'a u8) -> &'a u8 { +LL + fn one_input(x: &u8) -> &u8 { | error: aborting due to 46 previous errors diff --git a/tests/ui/option_env_unwrap.rs b/tests/ui/option_env_unwrap.rs index 0141fb7856d..9a56cf40d8a 100644 --- a/tests/ui/option_env_unwrap.rs +++ b/tests/ui/option_env_unwrap.rs @@ -1,24 +1,16 @@ -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::option_env_unwrap)] #![allow(clippy::map_flatten)] -#[macro_use] -extern crate macro_rules; - -macro_rules! option_env_unwrap { - ($env: expr) => { - option_env!($env).unwrap() - }; - ($env: expr, $message: expr) => { - option_env!($env).expect($message) - }; -} +extern crate proc_macros; +use proc_macros::{external, inline_macros}; +#[inline_macros] fn main() { let _ = option_env!("PATH").unwrap(); let _ = option_env!("PATH").expect("environment variable PATH isn't set"); - let _ = option_env_unwrap!("PATH"); - let _ = option_env_unwrap!("PATH", "environment variable PATH isn't set"); - let _ = option_env_unwrap_external!("PATH"); - let _ = option_env_unwrap_external!("PATH", "environment variable PATH isn't set"); + let _ = inline!(option_env!($"PATH").unwrap()); + let _ = inline!(option_env!($"PATH").expect($"environment variable PATH isn't set")); + let _ = external!(option_env!($"PATH").unwrap()); + let _ = external!(option_env!($"PATH").expect($"environment variable PATH isn't set")); } diff --git a/tests/ui/option_env_unwrap.stderr b/tests/ui/option_env_unwrap.stderr index bc188a07e9e..7bba62686ee 100644 --- a/tests/ui/option_env_unwrap.stderr +++ b/tests/ui/option_env_unwrap.stderr @@ -1,5 +1,5 @@ error: this will panic at run-time if the environment variable doesn't exist at compile-time - --> $DIR/option_env_unwrap.rs:18:13 + --> $DIR/option_env_unwrap.rs:10:13 | LL | let _ = option_env!("PATH").unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | let _ = option_env!("PATH").unwrap(); = note: `-D clippy::option-env-unwrap` implied by `-D warnings` error: this will panic at run-time if the environment variable doesn't exist at compile-time - --> $DIR/option_env_unwrap.rs:19:13 + --> $DIR/option_env_unwrap.rs:11:13 | LL | let _ = option_env!("PATH").expect("environment variable PATH isn't set"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -16,46 +16,40 @@ LL | let _ = option_env!("PATH").expect("environment variable PATH isn't set = help: consider using the `env!` macro instead error: this will panic at run-time if the environment variable doesn't exist at compile-time - --> $DIR/option_env_unwrap.rs:10:9 + --> $DIR/option_env_unwrap.rs:12:21 | -LL | option_env!($env).unwrap() - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -... -LL | let _ = option_env_unwrap!("PATH"); - | -------------------------- in this macro invocation +LL | let _ = inline!(option_env!($"PATH").unwrap()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider using the `env!` macro instead - = note: this error originates in the macro `option_env_unwrap` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: this will panic at run-time if the environment variable doesn't exist at compile-time - --> $DIR/option_env_unwrap.rs:13:9 + --> $DIR/option_env_unwrap.rs:13:21 | -LL | option_env!($env).expect($message) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -... -LL | let _ = option_env_unwrap!("PATH", "environment variable PATH isn't set"); - | ----------------------------------------------------------------- in this macro invocation +LL | let _ = inline!(option_env!($"PATH").expect($"environment variable PATH isn't set")); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider using the `env!` macro instead - = note: this error originates in the macro `option_env_unwrap` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: this will panic at run-time if the environment variable doesn't exist at compile-time - --> $DIR/option_env_unwrap.rs:22:13 + --> $DIR/option_env_unwrap.rs:14:13 | -LL | let _ = option_env_unwrap_external!("PATH"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | let _ = external!(option_env!($"PATH").unwrap()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider using the `env!` macro instead - = note: this error originates in the macro `option_env_unwrap_external` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `external` (in Nightly builds, run with -Z macro-backtrace for more info) error: this will panic at run-time if the environment variable doesn't exist at compile-time - --> $DIR/option_env_unwrap.rs:23:13 + --> $DIR/option_env_unwrap.rs:15:13 | -LL | let _ = option_env_unwrap_external!("PATH", "environment variable PATH isn't set"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | let _ = external!(option_env!($"PATH").expect($"environment variable PATH isn't set")); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider using the `env!` macro instead - = note: this error originates in the macro `option_env_unwrap_external` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `external` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 6 previous errors diff --git a/tests/ui/ptr_as_ptr.fixed b/tests/ui/ptr_as_ptr.fixed index df36a9b842b..ee7b998a0b2 100644 --- a/tests/ui/ptr_as_ptr.fixed +++ b/tests/ui/ptr_as_ptr.fixed @@ -1,16 +1,12 @@ // run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::ptr_as_ptr)] -extern crate macro_rules; - -macro_rules! cast_it { - ($ptr: ident) => { - $ptr.cast::() - }; -} +extern crate proc_macros; +use proc_macros::{external, inline_macros}; +#[inline_macros] fn main() { let ptr: *const u32 = &42_u32; let mut_ptr: *mut u32 = &mut 42_u32; @@ -38,10 +34,10 @@ fn main() { let _: *mut i32 = mut_ptr.cast(); // Make sure the lint is triggered inside a macro - let _ = cast_it!(ptr); + let _ = inline!($ptr.cast::()); // Do not lint inside macros from external crates - let _ = macro_rules::ptr_as_ptr_cast!(ptr); + let _ = external!($ptr as *const i32); } #[clippy::msrv = "1.37"] diff --git a/tests/ui/ptr_as_ptr.rs b/tests/ui/ptr_as_ptr.rs index 302c66462d9..c88329ce4ec 100644 --- a/tests/ui/ptr_as_ptr.rs +++ b/tests/ui/ptr_as_ptr.rs @@ -1,16 +1,12 @@ // run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::ptr_as_ptr)] -extern crate macro_rules; - -macro_rules! cast_it { - ($ptr: ident) => { - $ptr as *const i32 - }; -} +extern crate proc_macros; +use proc_macros::{external, inline_macros}; +#[inline_macros] fn main() { let ptr: *const u32 = &42_u32; let mut_ptr: *mut u32 = &mut 42_u32; @@ -38,10 +34,10 @@ fn main() { let _: *mut i32 = mut_ptr as _; // Make sure the lint is triggered inside a macro - let _ = cast_it!(ptr); + let _ = inline!($ptr as *const i32); // Do not lint inside macros from external crates - let _ = macro_rules::ptr_as_ptr_cast!(ptr); + let _ = external!($ptr as *const i32); } #[clippy::msrv = "1.37"] diff --git a/tests/ui/ptr_as_ptr.stderr b/tests/ui/ptr_as_ptr.stderr index a68e1cab6d3..78d733994ac 100644 --- a/tests/ui/ptr_as_ptr.stderr +++ b/tests/ui/ptr_as_ptr.stderr @@ -1,5 +1,5 @@ error: `as` casting between raw pointers without changing its mutability - --> $DIR/ptr_as_ptr.rs:18:13 + --> $DIR/ptr_as_ptr.rs:14:13 | LL | let _ = ptr as *const i32; | ^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast::()` @@ -7,48 +7,45 @@ LL | let _ = ptr as *const i32; = note: `-D clippy::ptr-as-ptr` implied by `-D warnings` error: `as` casting between raw pointers without changing its mutability - --> $DIR/ptr_as_ptr.rs:19:13 + --> $DIR/ptr_as_ptr.rs:15:13 | LL | let _ = mut_ptr as *mut i32; | ^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast::()` error: `as` casting between raw pointers without changing its mutability - --> $DIR/ptr_as_ptr.rs:24:17 + --> $DIR/ptr_as_ptr.rs:20:17 | LL | let _ = *ptr_ptr as *const i32; | ^^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `(*ptr_ptr).cast::()` error: `as` casting between raw pointers without changing its mutability - --> $DIR/ptr_as_ptr.rs:37:25 + --> $DIR/ptr_as_ptr.rs:33:25 | LL | let _: *const i32 = ptr as *const _; | ^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast()` error: `as` casting between raw pointers without changing its mutability - --> $DIR/ptr_as_ptr.rs:38:23 + --> $DIR/ptr_as_ptr.rs:34:23 | LL | let _: *mut i32 = mut_ptr as _; | ^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast()` error: `as` casting between raw pointers without changing its mutability - --> $DIR/ptr_as_ptr.rs:10:9 + --> $DIR/ptr_as_ptr.rs:37:21 | -LL | $ptr as *const i32 - | ^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `$ptr.cast::()` -... -LL | let _ = cast_it!(ptr); - | ------------- in this macro invocation +LL | let _ = inline!($ptr as *const i32); + | ^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `$ptr.cast::()` | - = note: this error originates in the macro `cast_it` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: `as` casting between raw pointers without changing its mutability - --> $DIR/ptr_as_ptr.rs:62:13 + --> $DIR/ptr_as_ptr.rs:58:13 | LL | let _ = ptr as *const i32; | ^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `ptr.cast::()` error: `as` casting between raw pointers without changing its mutability - --> $DIR/ptr_as_ptr.rs:63:13 + --> $DIR/ptr_as_ptr.rs:59:13 | LL | let _ = mut_ptr as *mut i32; | ^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast::()` diff --git a/tests/ui/single_match_else.rs b/tests/ui/single_match_else.rs index 5d03f77e932..3c86f41f3a6 100644 --- a/tests/ui/single_match_else.rs +++ b/tests/ui/single_match_else.rs @@ -1,9 +1,9 @@ -// aux-build: proc_macro_with_span.rs +// aux-build: proc_macros.rs #![warn(clippy::single_match_else)] #![allow(clippy::needless_return, clippy::no_effect, clippy::uninlined_format_args)] -extern crate proc_macro_with_span; -use proc_macro_with_span::with_span; +extern crate proc_macros; +use proc_macros::with_span; enum ExprNode { ExprAddrOf, diff --git a/tests/ui/string_add.rs b/tests/ui/string_add.rs index 16673c01e63..20edbe31fa9 100644 --- a/tests/ui/string_add.rs +++ b/tests/ui/string_add.rs @@ -1,7 +1,7 @@ -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::external; #[warn(clippy::string_add)] #[allow(clippy::string_add_assign, unused)] @@ -22,5 +22,8 @@ fn main() { x = x + 1; assert_eq!(2, x); - string_add!(); + external!({ + let y = "".to_owned(); + let z = y + "..."; + }); } diff --git a/tests/ui/toplevel_ref_arg.fixed b/tests/ui/toplevel_ref_arg.fixed index 09fb66ca37e..174c858a47d 100644 --- a/tests/ui/toplevel_ref_arg.fixed +++ b/tests/ui/toplevel_ref_arg.fixed @@ -1,17 +1,12 @@ // run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::toplevel_ref_arg)] -#![allow(clippy::uninlined_format_args)] +#![allow(clippy::uninlined_format_args, unused)] -#[macro_use] -extern crate macro_rules; - -macro_rules! gen_binding { - () => { - let _y = &42; - }; -} +extern crate proc_macros; +use proc_macros::{external, inline_macros}; +#[inline_macros] fn main() { // Closures should not warn let y = |ref x| println!("{:?}", x); @@ -38,13 +33,8 @@ fn main() { for ref _x in 0..10 {} // lint in macro - #[allow(unused)] - { - gen_binding!(); - } + inline!(let _y = &42;); // do not lint in external macro - { - ref_arg_binding!(); - } + external!(let ref _y = 42;); } diff --git a/tests/ui/toplevel_ref_arg.rs b/tests/ui/toplevel_ref_arg.rs index 9d1f2f81098..4b81a06112f 100644 --- a/tests/ui/toplevel_ref_arg.rs +++ b/tests/ui/toplevel_ref_arg.rs @@ -1,17 +1,12 @@ // run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::toplevel_ref_arg)] -#![allow(clippy::uninlined_format_args)] +#![allow(clippy::uninlined_format_args, unused)] -#[macro_use] -extern crate macro_rules; - -macro_rules! gen_binding { - () => { - let ref _y = 42; - }; -} +extern crate proc_macros; +use proc_macros::{external, inline_macros}; +#[inline_macros] fn main() { // Closures should not warn let y = |ref x| println!("{:?}", x); @@ -38,13 +33,8 @@ fn main() { for ref _x in 0..10 {} // lint in macro - #[allow(unused)] - { - gen_binding!(); - } + inline!(let ref _y = 42;); // do not lint in external macro - { - ref_arg_binding!(); - } + external!(let ref _y = 42;); } diff --git a/tests/ui/toplevel_ref_arg.stderr b/tests/ui/toplevel_ref_arg.stderr index 9c853020ab0..407c2d9fcd3 100644 --- a/tests/ui/toplevel_ref_arg.stderr +++ b/tests/ui/toplevel_ref_arg.stderr @@ -1,5 +1,5 @@ error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead - --> $DIR/toplevel_ref_arg.rs:20:9 + --> $DIR/toplevel_ref_arg.rs:15:9 | LL | let ref _x = 1; | ----^^^^^^----- help: try: `let _x = &1;` @@ -7,39 +7,36 @@ LL | let ref _x = 1; = note: `-D clippy::toplevel-ref-arg` implied by `-D warnings` error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead - --> $DIR/toplevel_ref_arg.rs:22:9 + --> $DIR/toplevel_ref_arg.rs:17:9 | LL | let ref _y: (&_, u8) = (&1, 2); | ----^^^^^^--------------------- help: try: `let _y: &(&_, u8) = &(&1, 2);` error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead - --> $DIR/toplevel_ref_arg.rs:24:9 + --> $DIR/toplevel_ref_arg.rs:19:9 | LL | let ref _z = 1 + 2; | ----^^^^^^--------- help: try: `let _z = &(1 + 2);` error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead - --> $DIR/toplevel_ref_arg.rs:26:9 + --> $DIR/toplevel_ref_arg.rs:21:9 | LL | let ref mut _z = 1 + 2; | ----^^^^^^^^^^--------- help: try: `let _z = &mut (1 + 2);` error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead - --> $DIR/toplevel_ref_arg.rs:31:9 + --> $DIR/toplevel_ref_arg.rs:26:9 | LL | let ref _x = vec![1, 2, 3]; | ----^^^^^^----------------- help: try: `let _x = &vec![1, 2, 3];` error: `ref` on an entire `let` pattern is discouraged, take a reference with `&` instead - --> $DIR/toplevel_ref_arg.rs:11:13 + --> $DIR/toplevel_ref_arg.rs:36:17 | -LL | let ref _y = 42; - | ----^^^^^^------ help: try: `let _y = &42;` -... -LL | gen_binding!(); - | -------------- in this macro invocation +LL | inline!(let ref _y = 42;); + | ----^^^^^^------ help: try: `let _y = &42;` | - = note: this error originates in the macro `gen_binding` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 6 previous errors diff --git a/tests/ui/toplevel_ref_arg_non_rustfix.rs b/tests/ui/toplevel_ref_arg_non_rustfix.rs index 1a493fbce0e..2047593e7e4 100644 --- a/tests/ui/toplevel_ref_arg_non_rustfix.rs +++ b/tests/ui/toplevel_ref_arg_non_rustfix.rs @@ -1,33 +1,27 @@ -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![warn(clippy::toplevel_ref_arg)] #![allow(unused)] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::{external, inline_macros}; fn the_answer(ref mut x: u8) { *x = 42; } -macro_rules! gen_function { - () => { - fn fun_example(ref _x: usize) {} - }; -} - +#[inline_macros] fn main() { let mut x = 0; the_answer(x); // lint in macro - #[allow(unused)] - { - gen_function!(); + inline! { + fn fun_example(ref _x: usize) {} } // do not lint in external macro - { - ref_arg_function!(); + external! { + fn fun_example2(ref _x: usize) {} } } diff --git a/tests/ui/toplevel_ref_arg_non_rustfix.stderr b/tests/ui/toplevel_ref_arg_non_rustfix.stderr index e97011c7fd5..7307bd599d9 100644 --- a/tests/ui/toplevel_ref_arg_non_rustfix.stderr +++ b/tests/ui/toplevel_ref_arg_non_rustfix.stderr @@ -7,15 +7,12 @@ LL | fn the_answer(ref mut x: u8) { = note: `-D clippy::toplevel-ref-arg` implied by `-D warnings` error: `ref` directly on a function argument is ignored. Consider using a reference type instead - --> $DIR/toplevel_ref_arg_non_rustfix.rs:15:24 + --> $DIR/toplevel_ref_arg_non_rustfix.rs:20:24 | LL | fn fun_example(ref _x: usize) {} | ^^^^^^ -... -LL | gen_function!(); - | --------------- in this macro invocation | - = note: this error originates in the macro `gen_function` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_fn_main` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors diff --git a/tests/ui/try_err.fixed b/tests/ui/try_err.fixed index 264194419c7..dc497b1690f 100644 --- a/tests/ui/try_err.fixed +++ b/tests/ui/try_err.fixed @@ -1,11 +1,11 @@ // run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![deny(clippy::try_err)] #![allow(clippy::unnecessary_wraps, clippy::needless_question_mark)] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::{external, inline_macros}; use std::io; use std::task::Poll; @@ -79,36 +79,22 @@ fn nested_error() -> Result { Ok(1) } -// Bad suggestion when in macro (see #6242) -macro_rules! try_validation { - ($e: expr) => {{ - match $e { +#[inline_macros] +fn calling_macro() -> Result { + // macro + inline!( + match $(Ok::<_, i32>(5)) { Ok(_) => 0, Err(_) => return Err(1), } - }}; -} - -macro_rules! ret_one { - () => { - 1 - }; -} - -macro_rules! try_validation_in_macro { - ($e: expr) => {{ - match $e { - Ok(_) => 0, - Err(_) => return Err(ret_one!()), - } - }}; -} - -fn calling_macro() -> Result { - // macro - try_validation!(Ok::<_, i32>(5)); + ); // `Err` arg is another macro - try_validation_in_macro!(Ok::<_, i32>(5)); + inline!( + match $(Ok::<_, i32>(5)) { + Ok(_) => 0, + Err(_) => return Err(inline!(1)), + } + ); Ok(5) } @@ -121,24 +107,19 @@ fn main() { calling_macro().unwrap(); // We don't want to lint in external macros - try_err!(); -} - -macro_rules! bar { - () => { - String::from("aasdfasdfasdfa") - }; -} - -macro_rules! foo { - () => { - bar!() - }; + external! { + pub fn try_err_fn() -> Result { + let err: i32 = 1; + // To avoid warnings during rustfix + if true { Err(err)? } else { Ok(2) } + } + } } +#[inline_macros] pub fn macro_inside(fail: bool) -> Result { if fail { - return Err(foo!()); + return Err(inline!(inline!(String::from("aasdfasdfasdfa")))); } Ok(0) } diff --git a/tests/ui/try_err.rs b/tests/ui/try_err.rs index bc6979bf457..86aeb75cd96 100644 --- a/tests/ui/try_err.rs +++ b/tests/ui/try_err.rs @@ -1,11 +1,11 @@ // run-rustfix -// aux-build:macro_rules.rs +// aux-build:proc_macros.rs #![deny(clippy::try_err)] #![allow(clippy::unnecessary_wraps, clippy::needless_question_mark)] -#[macro_use] -extern crate macro_rules; +extern crate proc_macros; +use proc_macros::{external, inline_macros}; use std::io; use std::task::Poll; @@ -79,36 +79,22 @@ fn nested_error() -> Result { Ok(1) } -// Bad suggestion when in macro (see #6242) -macro_rules! try_validation { - ($e: expr) => {{ - match $e { +#[inline_macros] +fn calling_macro() -> Result { + // macro + inline!( + match $(Ok::<_, i32>(5)) { Ok(_) => 0, Err(_) => Err(1)?, } - }}; -} - -macro_rules! ret_one { - () => { - 1 - }; -} - -macro_rules! try_validation_in_macro { - ($e: expr) => {{ - match $e { - Ok(_) => 0, - Err(_) => Err(ret_one!())?, - } - }}; -} - -fn calling_macro() -> Result { - // macro - try_validation!(Ok::<_, i32>(5)); + ); // `Err` arg is another macro - try_validation_in_macro!(Ok::<_, i32>(5)); + inline!( + match $(Ok::<_, i32>(5)) { + Ok(_) => 0, + Err(_) => Err(inline!(1))?, + } + ); Ok(5) } @@ -121,24 +107,19 @@ fn main() { calling_macro().unwrap(); // We don't want to lint in external macros - try_err!(); -} - -macro_rules! bar { - () => { - String::from("aasdfasdfasdfa") - }; -} - -macro_rules! foo { - () => { - bar!() - }; + external! { + pub fn try_err_fn() -> Result { + let err: i32 = 1; + // To avoid warnings during rustfix + if true { Err(err)? } else { Ok(2) } + } + } } +#[inline_macros] pub fn macro_inside(fail: bool) -> Result { if fail { - Err(foo!())?; + Err(inline!(inline!(String::from("aasdfasdfasdfa"))))?; } Ok(0) } diff --git a/tests/ui/try_err.stderr b/tests/ui/try_err.stderr index 0cb1328fbfc..4ad0e2e56a4 100644 --- a/tests/ui/try_err.stderr +++ b/tests/ui/try_err.stderr @@ -29,53 +29,47 @@ LL | Err(err)?; | ^^^^^^^^^ help: try this: `return Err(err.into())` error: returning an `Err(_)` with the `?` operator - --> $DIR/try_err.rs:87:23 + --> $DIR/try_err.rs:88:23 | LL | Err(_) => Err(1)?, | ^^^^^^^ help: try this: `return Err(1)` -... -LL | try_validation!(Ok::<_, i32>(5)); - | -------------------------------- in this macro invocation | - = note: this error originates in the macro `try_validation` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_fn_calling_macro` (in Nightly builds, run with -Z macro-backtrace for more info) error: returning an `Err(_)` with the `?` operator - --> $DIR/try_err.rs:102:23 + --> $DIR/try_err.rs:95:23 | -LL | Err(_) => Err(ret_one!())?, - | ^^^^^^^^^^^^^^^^ help: try this: `return Err(ret_one!())` -... -LL | try_validation_in_macro!(Ok::<_, i32>(5)); - | ----------------------------------------- in this macro invocation +LL | Err(_) => Err(inline!(1))?, + | ^^^^^^^^^^^^^^^^ help: try this: `return Err(inline!(1))` | - = note: this error originates in the macro `try_validation_in_macro` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `__inline_mac_fn_calling_macro` (in Nightly builds, run with -Z macro-backtrace for more info) error: returning an `Err(_)` with the `?` operator - --> $DIR/try_err.rs:141:9 + --> $DIR/try_err.rs:122:9 | -LL | Err(foo!())?; - | ^^^^^^^^^^^^ help: try this: `return Err(foo!())` +LL | Err(inline!(inline!(String::from("aasdfasdfasdfa"))))?; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `return Err(inline!(inline!(String::from("aasdfasdfasdfa"))))` error: returning an `Err(_)` with the `?` operator - --> $DIR/try_err.rs:148:9 + --> $DIR/try_err.rs:129:9 | LL | Err(io::ErrorKind::WriteZero)? | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `return Poll::Ready(Err(io::ErrorKind::WriteZero.into()))` error: returning an `Err(_)` with the `?` operator - --> $DIR/try_err.rs:150:9 + --> $DIR/try_err.rs:131:9 | LL | Err(io::Error::new(io::ErrorKind::InvalidInput, "error"))? | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `return Poll::Ready(Err(io::Error::new(io::ErrorKind::InvalidInput, "error")))` error: returning an `Err(_)` with the `?` operator - --> $DIR/try_err.rs:158:9 + --> $DIR/try_err.rs:139:9 | LL | Err(io::ErrorKind::NotFound)? | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `return Poll::Ready(Some(Err(io::ErrorKind::NotFound.into())))` error: returning an `Err(_)` with the `?` operator - --> $DIR/try_err.rs:167:16 + --> $DIR/try_err.rs:148:16 | LL | return Err(42)?; | ^^^^^^^^ help: try this: `Err(42)` diff --git a/tests/ui/uninlined_format_args.fixed b/tests/ui/uninlined_format_args.fixed index cbd5cc5fcee..1475d781c67 100644 --- a/tests/ui/uninlined_format_args.fixed +++ b/tests/ui/uninlined_format_args.fixed @@ -1,11 +1,11 @@ -// aux-build:proc_macro_with_span.rs +// aux-build:proc_macros.rs // run-rustfix #![warn(clippy::uninlined_format_args)] #![allow(named_arguments_used_positionally, unused_imports, unused_macros, unused_variables)] #![allow(clippy::eq_op, clippy::format_in_format_args, clippy::print_literal)] -extern crate proc_macro_with_span; -use proc_macro_with_span::with_span; +extern crate proc_macros; +use proc_macros::with_span; macro_rules! no_param_str { () => { diff --git a/tests/ui/uninlined_format_args.rs b/tests/ui/uninlined_format_args.rs index cf0ea5be481..835afac393f 100644 --- a/tests/ui/uninlined_format_args.rs +++ b/tests/ui/uninlined_format_args.rs @@ -1,11 +1,11 @@ -// aux-build:proc_macro_with_span.rs +// aux-build:proc_macros.rs // run-rustfix #![warn(clippy::uninlined_format_args)] #![allow(named_arguments_used_positionally, unused_imports, unused_macros, unused_variables)] #![allow(clippy::eq_op, clippy::format_in_format_args, clippy::print_literal)] -extern crate proc_macro_with_span; -use proc_macro_with_span::with_span; +extern crate proc_macros; +use proc_macros::with_span; macro_rules! no_param_str { () => { diff --git a/tests/ui/unit_arg.rs b/tests/ui/unit_arg.rs index 07e70873a81..674ae4f1df9 100644 --- a/tests/ui/unit_arg.rs +++ b/tests/ui/unit_arg.rs @@ -1,4 +1,4 @@ -// aux-build: proc_macro_with_span.rs +// aux-build: proc_macros.rs #![warn(clippy::unit_arg)] #![allow(unused_must_use, unused_variables)] #![allow( @@ -13,9 +13,9 @@ clippy::unused_unit )] -extern crate proc_macro_with_span; +extern crate proc_macros; -use proc_macro_with_span::with_span; +use proc_macros::with_span; use std::fmt::Debug; fn foo(t: T) { diff --git a/tests/ui/unnecessary_lazy_eval.fixed b/tests/ui/unnecessary_lazy_eval.fixed index 22e9bd8bdc5..3b93800f8b7 100644 --- a/tests/ui/unnecessary_lazy_eval.fixed +++ b/tests/ui/unnecessary_lazy_eval.fixed @@ -1,12 +1,12 @@ // run-rustfix -// aux-build: proc_macro_with_span.rs +// aux-build: proc_macros.rs #![warn(clippy::unnecessary_lazy_evaluations)] #![allow(clippy::redundant_closure)] #![allow(clippy::bind_instead_of_map)] #![allow(clippy::map_identity)] -extern crate proc_macro_with_span; -use proc_macro_with_span::with_span; +extern crate proc_macros; +use proc_macros::with_span; struct Deep(Option); diff --git a/tests/ui/unnecessary_lazy_eval.rs b/tests/ui/unnecessary_lazy_eval.rs index 8726d84a23f..2851c0c5190 100644 --- a/tests/ui/unnecessary_lazy_eval.rs +++ b/tests/ui/unnecessary_lazy_eval.rs @@ -1,12 +1,12 @@ // run-rustfix -// aux-build: proc_macro_with_span.rs +// aux-build: proc_macros.rs #![warn(clippy::unnecessary_lazy_evaluations)] #![allow(clippy::redundant_closure)] #![allow(clippy::bind_instead_of_map)] #![allow(clippy::map_identity)] -extern crate proc_macro_with_span; -use proc_macro_with_span::with_span; +extern crate proc_macros; +use proc_macros::with_span; struct Deep(Option); diff --git a/tests/ui/unnecessary_unsafety_doc.rs b/tests/ui/unnecessary_unsafety_doc.rs index c160e31afd3..431093ab369 100644 --- a/tests/ui/unnecessary_unsafety_doc.rs +++ b/tests/ui/unnecessary_unsafety_doc.rs @@ -1,10 +1,10 @@ -// aux-build:doc_unsafe_macros.rs +// aux-build:proc_macros.rs #![allow(clippy::let_unit_value)] #![warn(clippy::unnecessary_safety_doc)] -#[macro_use] -extern crate doc_unsafe_macros; +extern crate proc_macros; +use proc_macros::external; /// This is has no safety section, and does not need one either pub fn destroy_the_planet() { @@ -129,7 +129,11 @@ macro_rules! very_safe { very_safe!(); // we don't lint code from external macros -undocd_safe!(); +external!( + pub fn vey_oy() { + unimplemented!(); + } +); fn main() {} diff --git a/tests/ui/unnecessary_unsafety_doc.stderr b/tests/ui/unnecessary_unsafety_doc.stderr index 72898c93fa1..b0f20fdac5f 100644 --- a/tests/ui/unnecessary_unsafety_doc.stderr +++ b/tests/ui/unnecessary_unsafety_doc.stderr @@ -42,7 +42,7 @@ LL | very_safe!(); = note: this error originates in the macro `very_safe` (in Nightly builds, run with -Z macro-backtrace for more info) error: docs for safe trait have unnecessary `# Safety` section - --> $DIR/unnecessary_unsafety_doc.rs:147:1 + --> $DIR/unnecessary_unsafety_doc.rs:151:1 | LL | pub trait DocumentedSafeTraitWithImplementationHeader { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 8a9492aa03792f17c7b63b15d10ae9813daa4c4a Mon Sep 17 00:00:00 2001 From: J-ZhengLi Date: Thu, 16 Feb 2023 17:47:28 +0800 Subject: [PATCH 031/346] enhance [`ifs_same_cond`] to lint same immutable method calls as well --- clippy_lints/src/copies.rs | 26 +++++++++++++++++++++++--- tests/ui/ifs_same_cond.rs | 10 ++++++++++ tests/ui/ifs_same_cond.stderr | 14 +++++++++++++- 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/copies.rs b/clippy_lints/src/copies.rs index f10c35cde52..d729a5430c7 100644 --- a/clippy_lints/src/copies.rs +++ b/clippy_lints/src/copies.rs @@ -3,8 +3,8 @@ use clippy_utils::source::{first_line_of_span, indent_of, reindent_multiline, sn use clippy_utils::ty::needs_ordered_drop; use clippy_utils::visitors::for_each_expr; use clippy_utils::{ - capture_local_usage, eq_expr_value, get_enclosing_block, hash_expr, hash_stmt, if_sequence, is_else_clause, - is_lint_allowed, path_to_local, search_same, ContainsName, HirEqInterExpr, SpanlessEq, + capture_local_usage, eq_expr_value, find_binding_init, get_enclosing_block, hash_expr, hash_stmt, if_sequence, + is_else_clause, is_lint_allowed, path_to_local, search_same, ContainsName, HirEqInterExpr, SpanlessEq, }; use core::iter; use core::ops::ControlFlow; @@ -549,7 +549,27 @@ fn check_for_warn_of_moved_symbol(cx: &LateContext<'_>, symbols: &[(HirId, Symbo /// Implementation of `IFS_SAME_COND`. fn lint_same_cond(cx: &LateContext<'_>, conds: &[&Expr<'_>]) { - for (i, j) in search_same(conds, |e| hash_expr(cx, e), |lhs, rhs| eq_expr_value(cx, lhs, rhs)) { + for (i, j) in search_same( + conds, + |e| hash_expr(cx, e), + |lhs, rhs| { + // If any side (ex. lhs) is a method call, and the caller is not mutable, + // then we can ignore side effects? + if let ExprKind::MethodCall(_, caller, _, _) = lhs.kind { + if path_to_local(caller) + .and_then(|hir_id| find_binding_init(cx, hir_id)) + .is_some() + { + // caller is not declared as mutable + SpanlessEq::new(cx).eq_expr(lhs, rhs) + } else { + false + } + } else { + eq_expr_value(cx, lhs, rhs) + } + }, + ) { span_lint_and_note( cx, IFS_SAME_COND, diff --git a/tests/ui/ifs_same_cond.rs b/tests/ui/ifs_same_cond.rs index 9850fc0919e..e68ec6a8573 100644 --- a/tests/ui/ifs_same_cond.rs +++ b/tests/ui/ifs_same_cond.rs @@ -43,4 +43,14 @@ fn ifs_same_cond() { } } +fn issue10272() { + let a = String::from("ha"); + if a.contains("ah") { + } else if a.contains("ah") { + // Trigger this lint + } else if a.contains("ha") { + } else if a == "wow" { + } +} + fn main() {} diff --git a/tests/ui/ifs_same_cond.stderr b/tests/ui/ifs_same_cond.stderr index 4113087327a..9519f6904cb 100644 --- a/tests/ui/ifs_same_cond.stderr +++ b/tests/ui/ifs_same_cond.stderr @@ -35,5 +35,17 @@ note: same as this LL | if 2 * a == 1 { | ^^^^^^^^^^ -error: aborting due to 3 previous errors +error: this `if` has the same condition as a previous `if` + --> $DIR/ifs_same_cond.rs:49:15 + | +LL | } else if a.contains("ah") { + | ^^^^^^^^^^^^^^^^ + | +note: same as this + --> $DIR/ifs_same_cond.rs:48:8 + | +LL | if a.contains("ah") { + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors From f0ae2b71ca4053db3b86c20e7d612ecc11d50ee2 Mon Sep 17 00:00:00 2001 From: J-ZhengLi Date: Fri, 24 Feb 2023 10:46:07 +0800 Subject: [PATCH 032/346] make [`ifs_same_cond`] use `ignore_interior_mutablility` configuration --- clippy_lints/src/copies.rs | 70 +++++++++++++++----- clippy_lints/src/lib.rs | 3 +- clippy_lints/src/utils/conf.rs | 2 +- tests/ui-toml/ifs_same_cond/clippy.toml | 1 + tests/ui-toml/ifs_same_cond/ifs_same_cond.rs | 24 +++++++ tests/ui/ifs_same_cond.rs | 8 +++ 6 files changed, 91 insertions(+), 17 deletions(-) create mode 100644 tests/ui-toml/ifs_same_cond/clippy.toml create mode 100644 tests/ui-toml/ifs_same_cond/ifs_same_cond.rs diff --git a/clippy_lints/src/copies.rs b/clippy_lints/src/copies.rs index d729a5430c7..39f8f7220f1 100644 --- a/clippy_lints/src/copies.rs +++ b/clippy_lints/src/copies.rs @@ -3,16 +3,19 @@ use clippy_utils::source::{first_line_of_span, indent_of, reindent_multiline, sn use clippy_utils::ty::needs_ordered_drop; use clippy_utils::visitors::for_each_expr; use clippy_utils::{ - capture_local_usage, eq_expr_value, find_binding_init, get_enclosing_block, hash_expr, hash_stmt, if_sequence, - is_else_clause, is_lint_allowed, path_to_local, search_same, ContainsName, HirEqInterExpr, SpanlessEq, + capture_local_usage, def_path_def_ids, eq_expr_value, find_binding_init, get_enclosing_block, hash_expr, hash_stmt, + if_sequence, is_else_clause, is_lint_allowed, path_to_local, search_same, ContainsName, HirEqInterExpr, SpanlessEq, }; use core::iter; use core::ops::ControlFlow; +use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; +use rustc_hir::def_id::DefId; use rustc_hir::intravisit; use rustc_hir::{BinOpKind, Block, Expr, ExprKind, HirId, HirIdSet, Stmt, StmtKind}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_middle::query::Key; +use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::hygiene::walk_chain; use rustc_span::source_map::SourceMap; use rustc_span::{BytePos, Span, Symbol}; @@ -159,7 +162,19 @@ declare_clippy_lint! { "`if` statement with shared code in all blocks" } -declare_lint_pass!(CopyAndPaste => [ +pub struct CopyAndPaste { + ignore_interior_mutability: Vec, +} + +impl CopyAndPaste { + pub fn new(ignore_interior_mutability: Vec) -> Self { + Self { + ignore_interior_mutability, + } + } +} + +impl_lint_pass!(CopyAndPaste => [ IFS_SAME_COND, SAME_FUNCTIONS_IN_IF_CONDITION, IF_SAME_THEN_ELSE, @@ -170,7 +185,14 @@ impl<'tcx> LateLintPass<'tcx> for CopyAndPaste { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if !expr.span.from_expansion() && matches!(expr.kind, ExprKind::If(..)) && !is_else_clause(cx.tcx, expr) { let (conds, blocks) = if_sequence(expr); - lint_same_cond(cx, &conds); + let mut ignored_ty_ids = FxHashSet::default(); + for ignored_ty in &self.ignore_interior_mutability { + let path: Vec<&str> = ignored_ty.split("::").collect(); + for id in def_path_def_ids(cx, path.as_slice()) { + ignored_ty_ids.insert(id); + } + } + lint_same_cond(cx, &conds, &ignored_ty_ids); lint_same_fns_in_if_cond(cx, &conds); let all_same = !is_lint_allowed(cx, IF_SAME_THEN_ELSE, expr.hir_id) && lint_if_same_then_else(cx, &conds, &blocks); @@ -547,23 +569,41 @@ fn check_for_warn_of_moved_symbol(cx: &LateContext<'_>, symbols: &[(HirId, Symbo }) } +fn method_caller_is_ignored_or_mutable( + cx: &LateContext<'_>, + caller_expr: &Expr<'_>, + ignored_ty_ids: &FxHashSet, +) -> bool { + let caller_ty = cx.typeck_results().expr_ty(caller_expr); + let is_ignored_ty = if let Some(adt_id) = caller_ty.ty_adt_id() && ignored_ty_ids.contains(&adt_id) { + true + } else { + false + }; + + if is_ignored_ty + || caller_ty.is_mutable_ptr() + || path_to_local(caller_expr) + .and_then(|hid| find_binding_init(cx, hid)) + .is_none() + { + return true; + } + + false +} + /// Implementation of `IFS_SAME_COND`. -fn lint_same_cond(cx: &LateContext<'_>, conds: &[&Expr<'_>]) { +fn lint_same_cond(cx: &LateContext<'_>, conds: &[&Expr<'_>], ignored_ty_ids: &FxHashSet) { for (i, j) in search_same( conds, |e| hash_expr(cx, e), |lhs, rhs| { - // If any side (ex. lhs) is a method call, and the caller is not mutable, - // then we can ignore side effects? if let ExprKind::MethodCall(_, caller, _, _) = lhs.kind { - if path_to_local(caller) - .and_then(|hir_id| find_binding_init(cx, hir_id)) - .is_some() - { - // caller is not declared as mutable - SpanlessEq::new(cx).eq_expr(lhs, rhs) - } else { + if method_caller_is_ignored_or_mutable(cx, caller, ignored_ty_ids) { false + } else { + SpanlessEq::new(cx).eq_expr(lhs, rhs) } } else { eq_expr_value(cx, lhs, rhs) diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 491732be208..bde84686cc1 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -656,7 +656,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|_| Box::new(empty_enum::EmptyEnum)); store.register_late_pass(|_| Box::new(invalid_upcast_comparisons::InvalidUpcastComparisons)); store.register_late_pass(|_| Box::new(regex::Regex)); - store.register_late_pass(|_| Box::new(copies::CopyAndPaste)); + let ignore_interior_mutability = conf.ignore_interior_mutability.clone(); + store.register_late_pass(move |_| Box::new(copies::CopyAndPaste::new(ignore_interior_mutability.clone()))); store.register_late_pass(|_| Box::new(copy_iterator::CopyIterator)); store.register_late_pass(|_| Box::new(format::UselessFormat)); store.register_late_pass(|_| Box::new(swap::Swap)); diff --git a/clippy_lints/src/utils/conf.rs b/clippy_lints/src/utils/conf.rs index 1c7f3e96db8..8ba252425a3 100644 --- a/clippy_lints/src/utils/conf.rs +++ b/clippy_lints/src/utils/conf.rs @@ -437,7 +437,7 @@ define_Conf! { /// /// The maximum size of the `Err`-variant in a `Result` returned from a function (large_error_threshold: u64 = 128), - /// Lint: MUTABLE_KEY_TYPE. + /// Lint: MUTABLE_KEY_TYPE, IFS_SAME_COND. /// /// A list of paths to types that should be treated like `Arc`, i.e. ignored but /// for the generic parameters for determining interior mutability diff --git a/tests/ui-toml/ifs_same_cond/clippy.toml b/tests/ui-toml/ifs_same_cond/clippy.toml new file mode 100644 index 00000000000..1615d970c68 --- /dev/null +++ b/tests/ui-toml/ifs_same_cond/clippy.toml @@ -0,0 +1 @@ +ignore-interior-mutability = ["std::cell::Cell"] \ No newline at end of file diff --git a/tests/ui-toml/ifs_same_cond/ifs_same_cond.rs b/tests/ui-toml/ifs_same_cond/ifs_same_cond.rs new file mode 100644 index 00000000000..92438e7d1f2 --- /dev/null +++ b/tests/ui-toml/ifs_same_cond/ifs_same_cond.rs @@ -0,0 +1,24 @@ +#![warn(clippy::ifs_same_cond)] +#![allow(clippy::if_same_then_else, clippy::comparison_chain)] + +fn main() {} + +fn issue10272() { + use std::cell::Cell; + + let x = Cell::new(true); + if x.get() { + } else if !x.take() { + } else if x.get() { + // ok, x is interior mutable type + } else { + } + + let a = [Cell::new(true)]; + if a[0].get() { + } else if a[0].take() { + } else if a[0].get() { + // ok, a contains interior mutable type + } else { + } +} diff --git a/tests/ui/ifs_same_cond.rs b/tests/ui/ifs_same_cond.rs index e68ec6a8573..ae91611c472 100644 --- a/tests/ui/ifs_same_cond.rs +++ b/tests/ui/ifs_same_cond.rs @@ -51,6 +51,14 @@ fn issue10272() { } else if a.contains("ha") { } else if a == "wow" { } + + let p: *mut i8 = std::ptr::null_mut(); + if p.is_null() { + } else if p.align_offset(0) == 0 { + } else if p.is_null() { + // ok, p is mutable pointer + } else { + } } fn main() {} From f4ccb06d699b91b8de8b797a584ce185d6856ec2 Mon Sep 17 00:00:00 2001 From: J-ZhengLi Date: Mon, 13 Mar 2023 20:17:30 +0800 Subject: [PATCH 033/346] extract `is_interior_mutable_type` from [`mut_key`] to `clippy_utils::ty`; fix configuration of [`ifs_same_cond`]; add some style improvement for [`ifs_same_cond`]; --- clippy_lints/src/copies.rs | 52 +++++++--------- clippy_lints/src/mut_key.rs | 60 ++++--------------- clippy_utils/src/ty.rs | 44 ++++++++++++++ tests/ui-toml/ifs_same_cond/clippy.toml | 2 +- tests/ui-toml/ifs_same_cond/ifs_same_cond.rs | 12 +--- .../ifs_same_cond/ifs_same_cond.stderr | 15 +++++ tests/ui/ifs_same_cond.rs | 8 +++ 7 files changed, 107 insertions(+), 86 deletions(-) create mode 100644 tests/ui-toml/ifs_same_cond/ifs_same_cond.stderr diff --git a/clippy_lints/src/copies.rs b/clippy_lints/src/copies.rs index 39f8f7220f1..970f5004993 100644 --- a/clippy_lints/src/copies.rs +++ b/clippy_lints/src/copies.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::{span_lint_and_note, span_lint_and_then}; use clippy_utils::source::{first_line_of_span, indent_of, reindent_multiline, snippet, snippet_opt}; -use clippy_utils::ty::needs_ordered_drop; +use clippy_utils::ty::{is_interior_mut_ty, needs_ordered_drop}; use clippy_utils::visitors::for_each_expr; use clippy_utils::{ capture_local_usage, def_path_def_ids, eq_expr_value, find_binding_init, get_enclosing_block, hash_expr, hash_stmt, @@ -8,9 +8,8 @@ use clippy_utils::{ }; use core::iter; use core::ops::ControlFlow; -use rustc_data_structures::fx::FxHashSet; use rustc_errors::Applicability; -use rustc_hir::def_id::DefId; +use rustc_hir::def_id::DefIdSet; use rustc_hir::intravisit; use rustc_hir::{BinOpKind, Block, Expr, ExprKind, HirId, HirIdSet, Stmt, StmtKind}; use rustc_lint::{LateContext, LateLintPass}; @@ -164,12 +163,14 @@ declare_clippy_lint! { pub struct CopyAndPaste { ignore_interior_mutability: Vec, + ignored_ty_ids: DefIdSet, } impl CopyAndPaste { pub fn new(ignore_interior_mutability: Vec) -> Self { Self { ignore_interior_mutability, + ignored_ty_ids: DefIdSet::new(), } } } @@ -182,17 +183,18 @@ impl_lint_pass!(CopyAndPaste => [ ]); impl<'tcx> LateLintPass<'tcx> for CopyAndPaste { + fn check_crate(&mut self, cx: &LateContext<'tcx>) { + for ignored_ty in &self.ignore_interior_mutability { + let path: Vec<&str> = ignored_ty.split("::").collect(); + for id in def_path_def_ids(cx, path.as_slice()) { + self.ignored_ty_ids.insert(id); + } + } + } fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { if !expr.span.from_expansion() && matches!(expr.kind, ExprKind::If(..)) && !is_else_clause(cx.tcx, expr) { let (conds, blocks) = if_sequence(expr); - let mut ignored_ty_ids = FxHashSet::default(); - for ignored_ty in &self.ignore_interior_mutability { - let path: Vec<&str> = ignored_ty.split("::").collect(); - for id in def_path_def_ids(cx, path.as_slice()) { - ignored_ty_ids.insert(id); - } - } - lint_same_cond(cx, &conds, &ignored_ty_ids); + lint_same_cond(cx, &conds, &self.ignored_ty_ids); lint_same_fns_in_if_cond(cx, &conds); let all_same = !is_lint_allowed(cx, IF_SAME_THEN_ELSE, expr.hir_id) && lint_if_same_then_else(cx, &conds, &blocks); @@ -569,38 +571,30 @@ fn check_for_warn_of_moved_symbol(cx: &LateContext<'_>, symbols: &[(HirId, Symbo }) } -fn method_caller_is_ignored_or_mutable( - cx: &LateContext<'_>, - caller_expr: &Expr<'_>, - ignored_ty_ids: &FxHashSet, -) -> bool { +fn method_caller_is_mutable(cx: &LateContext<'_>, caller_expr: &Expr<'_>, ignored_ty_ids: &DefIdSet) -> bool { let caller_ty = cx.typeck_results().expr_ty(caller_expr); - let is_ignored_ty = if let Some(adt_id) = caller_ty.ty_adt_id() && ignored_ty_ids.contains(&adt_id) { - true - } else { - false - }; + // Check if given type has inner mutability and was not set to ignored by the configuration + let is_inner_mut_ty = is_interior_mut_ty(cx, caller_ty) + && !matches!(caller_ty.ty_adt_id(), Some(adt_id) if ignored_ty_ids.contains(&adt_id)); - if is_ignored_ty + is_inner_mut_ty || caller_ty.is_mutable_ptr() + // `find_binding_init` will return the binding iff its not mutable || path_to_local(caller_expr) .and_then(|hid| find_binding_init(cx, hid)) .is_none() - { - return true; - } - - false } /// Implementation of `IFS_SAME_COND`. -fn lint_same_cond(cx: &LateContext<'_>, conds: &[&Expr<'_>], ignored_ty_ids: &FxHashSet) { +fn lint_same_cond(cx: &LateContext<'_>, conds: &[&Expr<'_>], ignored_ty_ids: &DefIdSet) { for (i, j) in search_same( conds, |e| hash_expr(cx, e), |lhs, rhs| { + // Ignore eq_expr side effects iff one of the expressin kind is a method call + // and the caller is not a mutable, including inner mutable type. if let ExprKind::MethodCall(_, caller, _, _) = lhs.kind { - if method_caller_is_ignored_or_mutable(cx, caller, ignored_ty_ids) { + if method_caller_is_mutable(cx, caller, ignored_ty_ids) { false } else { SpanlessEq::new(cx).eq_expr(lhs, rhs) diff --git a/clippy_lints/src/mut_key.rs b/clippy_lints/src/mut_key.rs index 8aa814b7405..309f67521a3 100644 --- a/clippy_lints/src/mut_key.rs +++ b/clippy_lints/src/mut_key.rs @@ -1,10 +1,11 @@ use clippy_utils::diagnostics::span_lint; +use clippy_utils::ty::is_interior_mut_ty; use clippy_utils::{def_path_def_ids, trait_ref_of_method}; use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::TypeVisitableExt; -use rustc_middle::ty::{Adt, Array, Ref, Slice, Tuple, Ty}; +use rustc_middle::query::Key; +use rustc_middle::ty::{Adt, Ty}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::def_id::LocalDefId; use rustc_span::source_map::Span; @@ -153,53 +154,18 @@ impl MutableKeyType { let is_keyed_type = [sym::HashMap, sym::BTreeMap, sym::HashSet, sym::BTreeSet] .iter() .any(|diag_item| cx.tcx.is_diagnostic_item(*diag_item, def.did())); - if is_keyed_type && self.is_interior_mutable_type(cx, substs.type_at(0)) { + if !is_keyed_type { + return; + } + + let subst_ty = substs.type_at(0); + // Determines if a type contains interior mutability which would affect its implementation of + // [`Hash`] or [`Ord`]. + if is_interior_mut_ty(cx, subst_ty) + && !matches!(subst_ty.ty_adt_id(), Some(adt_id) if self.ignore_mut_def_ids.contains(&adt_id)) + { span_lint(cx, MUTABLE_KEY_TYPE, span, "mutable key type"); } } } - - /// Determines if a type contains interior mutability which would affect its implementation of - /// [`Hash`] or [`Ord`]. - fn is_interior_mutable_type<'tcx>(&self, cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { - match *ty.kind() { - Ref(_, inner_ty, mutbl) => mutbl == hir::Mutability::Mut || self.is_interior_mutable_type(cx, inner_ty), - Slice(inner_ty) => self.is_interior_mutable_type(cx, inner_ty), - Array(inner_ty, size) => { - size.try_eval_target_usize(cx.tcx, cx.param_env) - .map_or(true, |u| u != 0) - && self.is_interior_mutable_type(cx, inner_ty) - }, - Tuple(fields) => fields.iter().any(|ty| self.is_interior_mutable_type(cx, ty)), - Adt(def, substs) => { - // Special case for collections in `std` who's impl of `Hash` or `Ord` delegates to - // that of their type parameters. Note: we don't include `HashSet` and `HashMap` - // because they have no impl for `Hash` or `Ord`. - let def_id = def.did(); - let is_std_collection = [ - sym::Option, - sym::Result, - sym::LinkedList, - sym::Vec, - sym::VecDeque, - sym::BTreeMap, - sym::BTreeSet, - sym::Rc, - sym::Arc, - ] - .iter() - .any(|diag_item| cx.tcx.is_diagnostic_item(*diag_item, def_id)); - let is_box = Some(def_id) == cx.tcx.lang_items().owned_box(); - if is_std_collection || is_box || self.ignore_mut_def_ids.contains(&def_id) { - // The type is mutable if any of its type parameters are - substs.types().any(|ty| self.is_interior_mutable_type(cx, ty)) - } else { - !ty.has_escaping_bound_vars() - && cx.tcx.layout_of(cx.param_env.and(ty)).is_ok() - && !ty.is_freeze(cx.tcx, cx.param_env) - } - }, - _ => false, - } - } } diff --git a/clippy_utils/src/ty.rs b/clippy_utils/src/ty.rs index e0ea3952785..f1c6f1dddd8 100644 --- a/clippy_utils/src/ty.rs +++ b/clippy_utils/src/ty.rs @@ -1121,3 +1121,47 @@ pub fn make_normalized_projection<'tcx>( } helper(tcx, param_env, make_projection(tcx, container_id, assoc_ty, substs)?) } + +/// Check if given type has inner mutability such as [`std::cell::Cell`] or [`std::cell::RefCell`] +/// etc. +pub fn is_interior_mut_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { + match *ty.kind() { + ty::Ref(_, inner_ty, mutbl) => mutbl == Mutability::Mut || is_interior_mut_ty(cx, inner_ty), + ty::Slice(inner_ty) => is_interior_mut_ty(cx, inner_ty), + ty::Array(inner_ty, size) => { + size.try_eval_target_usize(cx.tcx, cx.param_env) + .map_or(true, |u| u != 0) + && is_interior_mut_ty(cx, inner_ty) + }, + ty::Tuple(fields) => fields.iter().any(|ty| is_interior_mut_ty(cx, ty)), + ty::Adt(def, substs) => { + // Special case for collections in `std` who's impl of `Hash` or `Ord` delegates to + // that of their type parameters. Note: we don't include `HashSet` and `HashMap` + // because they have no impl for `Hash` or `Ord`. + let def_id = def.did(); + let is_std_collection = [ + sym::Option, + sym::Result, + sym::LinkedList, + sym::Vec, + sym::VecDeque, + sym::BTreeMap, + sym::BTreeSet, + sym::Rc, + sym::Arc, + ] + .iter() + .any(|diag_item| cx.tcx.is_diagnostic_item(*diag_item, def_id)); + let is_box = Some(def_id) == cx.tcx.lang_items().owned_box(); + if is_std_collection || is_box { + // The type is mutable if any of its type parameters are + substs.types().any(|ty| is_interior_mut_ty(cx, ty)) + } else { + !ty.has_escaping_bound_vars() + && cx.tcx.layout_of(cx.param_env.and(ty)).is_ok() + && !ty.is_freeze(cx.tcx, cx.param_env) + } + }, + _ => false, + } +} diff --git a/tests/ui-toml/ifs_same_cond/clippy.toml b/tests/ui-toml/ifs_same_cond/clippy.toml index 1615d970c68..90a36ecd920 100644 --- a/tests/ui-toml/ifs_same_cond/clippy.toml +++ b/tests/ui-toml/ifs_same_cond/clippy.toml @@ -1 +1 @@ -ignore-interior-mutability = ["std::cell::Cell"] \ No newline at end of file +ignore-interior-mutability = ["std::cell::Cell"] diff --git a/tests/ui-toml/ifs_same_cond/ifs_same_cond.rs b/tests/ui-toml/ifs_same_cond/ifs_same_cond.rs index 92438e7d1f2..d623ac7e020 100644 --- a/tests/ui-toml/ifs_same_cond/ifs_same_cond.rs +++ b/tests/ui-toml/ifs_same_cond/ifs_same_cond.rs @@ -6,19 +6,13 @@ fn main() {} fn issue10272() { use std::cell::Cell; + // Because the `ignore-interior-mutability` configuration + // is set to ignore for `std::cell::Cell`, the following `get()` calls + // should trigger warning let x = Cell::new(true); if x.get() { } else if !x.take() { } else if x.get() { - // ok, x is interior mutable type - } else { - } - - let a = [Cell::new(true)]; - if a[0].get() { - } else if a[0].take() { - } else if a[0].get() { - // ok, a contains interior mutable type } else { } } diff --git a/tests/ui-toml/ifs_same_cond/ifs_same_cond.stderr b/tests/ui-toml/ifs_same_cond/ifs_same_cond.stderr new file mode 100644 index 00000000000..2841f62bc94 --- /dev/null +++ b/tests/ui-toml/ifs_same_cond/ifs_same_cond.stderr @@ -0,0 +1,15 @@ +error: this `if` has the same condition as a previous `if` + --> $DIR/ifs_same_cond.rs:15:15 + | +LL | } else if x.get() { + | ^^^^^^^ + | +note: same as this + --> $DIR/ifs_same_cond.rs:13:8 + | +LL | if x.get() { + | ^^^^^^^ + = note: `-D clippy::ifs-same-cond` implied by `-D warnings` + +error: aborting due to previous error + diff --git a/tests/ui/ifs_same_cond.rs b/tests/ui/ifs_same_cond.rs index ae91611c472..9ce9a87626a 100644 --- a/tests/ui/ifs_same_cond.rs +++ b/tests/ui/ifs_same_cond.rs @@ -59,6 +59,14 @@ fn issue10272() { // ok, p is mutable pointer } else { } + + let x = std::cell::Cell::new(true); + if x.get() { + } else if !x.take() { + } else if x.get() { + // ok, x is interior mutable type + } else { + } } fn main() {} From 555f56862e10cda545c9b7de21f68c7d62266c35 Mon Sep 17 00:00:00 2001 From: Alex Macleod Date: Thu, 9 Mar 2023 17:31:10 +0000 Subject: [PATCH 034/346] Fix semicolon insertion in `match_single_binding` --- .../src/matches/match_single_binding.rs | 21 ++-- tests/ui/match_single_binding.fixed | 41 +++++-- tests/ui/match_single_binding.rs | 55 ++++++++- tests/ui/match_single_binding.stderr | 111 +++++++++++++++--- tests/ui/match_single_binding2.fixed | 4 +- tests/ui/match_single_binding2.stderr | 4 +- 6 files changed, 192 insertions(+), 44 deletions(-) diff --git a/clippy_lints/src/matches/match_single_binding.rs b/clippy_lints/src/matches/match_single_binding.rs index eec5c1143d4..89da7a55cbd 100644 --- a/clippy_lints/src/matches/match_single_binding.rs +++ b/clippy_lints/src/matches/match_single_binding.rs @@ -3,7 +3,7 @@ use clippy_utils::macros::HirNode; use clippy_utils::source::{indent_of, snippet, snippet_block_with_context, snippet_with_applicability}; use clippy_utils::{get_parent_expr, is_refutable, peel_blocks}; use rustc_errors::Applicability; -use rustc_hir::{Arm, Expr, ExprKind, Node, PatKind}; +use rustc_hir::{Arm, Expr, ExprKind, Node, PatKind, StmtKind}; use rustc_lint::LateContext; use rustc_span::Span; @@ -24,22 +24,27 @@ pub(crate) fn check<'a>(cx: &LateContext<'a>, ex: &Expr<'a>, arms: &[Arm<'_>], e let bind_names = arms[0].pat.span; let match_body = peel_blocks(arms[0].body); let mut app = Applicability::MaybeIncorrect; - let (snippet_body, from_macro) = snippet_block_with_context( + let mut snippet_body = snippet_block_with_context( cx, match_body.span, arms[0].span.ctxt(), "..", Some(expr.span), &mut app, - ); - let mut snippet_body = snippet_body.to_string(); + ) + .0 + .to_string(); // Do we need to add ';' to suggestion ? - if matches!(match_body.kind, ExprKind::Block(..)) { - // macro + expr_ty(body) == () - if from_macro && cx.typeck_results().expr_ty(match_body).is_unit() { - snippet_body.push(';'); + if let Node::Stmt(stmt) = cx.tcx.hir().get_parent(expr.hir_id) + && let StmtKind::Expr(_) = stmt.kind + && match match_body.kind { + // We don't need to add a ; to blocks, unless that block is from a macro expansion + ExprKind::Block(block, _) => block.span.from_expansion(), + _ => true, } + { + snippet_body.push(';'); } match arms[0].pat.kind { diff --git a/tests/ui/match_single_binding.fixed b/tests/ui/match_single_binding.fixed index 6cfb6661a03..201301cc9b7 100644 --- a/tests/ui/match_single_binding.fixed +++ b/tests/ui/match_single_binding.fixed @@ -1,7 +1,12 @@ // run-rustfix #![warn(clippy::match_single_binding)] -#![allow(unused_variables)] -#![allow(clippy::toplevel_ref_arg, clippy::uninlined_format_args)] +#![allow( + unused, + clippy::let_unit_value, + clippy::no_effect, + clippy::toplevel_ref_arg, + clippy::uninlined_format_args +)] struct Point { x: i32, @@ -109,10 +114,9 @@ fn main() { // Lint let x = 1; - println!("Not an array index start"); + println!("Not an array index start") } -#[allow(dead_code)] fn issue_8723() { let (mut val, idx) = ("a b", 1); @@ -125,16 +129,15 @@ fn issue_8723() { let _ = val; } -#[allow(dead_code)] +fn side_effects() {} + fn issue_9575() { - fn side_effects() {} let _ = || { side_effects(); - println!("Needs curlies"); + println!("Needs curlies") }; } -#[allow(dead_code)] fn issue_9725(r: Option) { let x = r; match x { @@ -146,3 +149,25 @@ fn issue_9725(r: Option) { }, }; } + +fn issue_10447() -> usize { + (); + + let a = (); + + side_effects(); + + let b = side_effects(); + + println!("1"); + + let c = println!("1"); + + let in_expr = [ + (), + side_effects(), + println!("1"), + ]; + + 2 +} diff --git a/tests/ui/match_single_binding.rs b/tests/ui/match_single_binding.rs index f188aeb5f2f..8b047b19ce9 100644 --- a/tests/ui/match_single_binding.rs +++ b/tests/ui/match_single_binding.rs @@ -1,7 +1,12 @@ // run-rustfix #![warn(clippy::match_single_binding)] -#![allow(unused_variables)] -#![allow(clippy::toplevel_ref_arg, clippy::uninlined_format_args)] +#![allow( + unused, + clippy::let_unit_value, + clippy::no_effect, + clippy::toplevel_ref_arg, + clippy::uninlined_format_args +)] struct Point { x: i32, @@ -127,7 +132,6 @@ fn main() { } } -#[allow(dead_code)] fn issue_8723() { let (mut val, idx) = ("a b", 1); @@ -141,15 +145,14 @@ fn issue_8723() { let _ = val; } -#[allow(dead_code)] +fn side_effects() {} + fn issue_9575() { - fn side_effects() {} let _ = || match side_effects() { _ => println!("Needs curlies"), }; } -#[allow(dead_code)] fn issue_9725(r: Option) { match r { x => match x { @@ -162,3 +165,43 @@ fn issue_9725(r: Option) { }, }; } + +fn issue_10447() -> usize { + match 1 { + _ => (), + } + + let a = match 1 { + _ => (), + }; + + match 1 { + _ => side_effects(), + } + + let b = match 1 { + _ => side_effects(), + }; + + match 1 { + _ => println!("1"), + } + + let c = match 1 { + _ => println!("1"), + }; + + let in_expr = [ + match 1 { + _ => (), + }, + match 1 { + _ => side_effects(), + }, + match 1 { + _ => println!("1"), + }, + ]; + + 2 +} diff --git a/tests/ui/match_single_binding.stderr b/tests/ui/match_single_binding.stderr index e960d64ad2b..9d16af76c6a 100644 --- a/tests/ui/match_single_binding.stderr +++ b/tests/ui/match_single_binding.stderr @@ -1,5 +1,5 @@ error: this match could be written as a `let` statement - --> $DIR/match_single_binding.rs:28:5 + --> $DIR/match_single_binding.rs:33:5 | LL | / match (a, b, c) { LL | | (x, y, z) => { @@ -18,7 +18,7 @@ LL + } | error: this match could be written as a `let` statement - --> $DIR/match_single_binding.rs:34:5 + --> $DIR/match_single_binding.rs:39:5 | LL | / match (a, b, c) { LL | | (x, y, z) => println!("{} {} {}", x, y, z), @@ -32,7 +32,7 @@ LL + println!("{} {} {}", x, y, z); | error: this match could be replaced by its body itself - --> $DIR/match_single_binding.rs:51:5 + --> $DIR/match_single_binding.rs:56:5 | LL | / match a { LL | | _ => println!("whatever"), @@ -40,7 +40,7 @@ LL | | } | |_____^ help: consider using the match body instead: `println!("whatever");` error: this match could be replaced by its body itself - --> $DIR/match_single_binding.rs:55:5 + --> $DIR/match_single_binding.rs:60:5 | LL | / match a { LL | | _ => { @@ -59,7 +59,7 @@ LL + } | error: this match could be replaced by its body itself - --> $DIR/match_single_binding.rs:62:5 + --> $DIR/match_single_binding.rs:67:5 | LL | / match a { LL | | _ => { @@ -81,7 +81,7 @@ LL + } | error: this match could be written as a `let` statement - --> $DIR/match_single_binding.rs:72:5 + --> $DIR/match_single_binding.rs:77:5 | LL | / match p { LL | | Point { x, y } => println!("Coords: ({}, {})", x, y), @@ -95,7 +95,7 @@ LL + println!("Coords: ({}, {})", x, y); | error: this match could be written as a `let` statement - --> $DIR/match_single_binding.rs:76:5 + --> $DIR/match_single_binding.rs:81:5 | LL | / match p { LL | | Point { x: x1, y: y1 } => println!("Coords: ({}, {})", x1, y1), @@ -109,7 +109,7 @@ LL + println!("Coords: ({}, {})", x1, y1); | error: this match could be written as a `let` statement - --> $DIR/match_single_binding.rs:81:5 + --> $DIR/match_single_binding.rs:86:5 | LL | / match x { LL | | ref r => println!("Got a reference to {}", r), @@ -123,7 +123,7 @@ LL + println!("Got a reference to {}", r); | error: this match could be written as a `let` statement - --> $DIR/match_single_binding.rs:86:5 + --> $DIR/match_single_binding.rs:91:5 | LL | / match x { LL | | ref mut mr => println!("Got a mutable reference to {}", mr), @@ -137,7 +137,7 @@ LL + println!("Got a mutable reference to {}", mr); | error: this match could be written as a `let` statement - --> $DIR/match_single_binding.rs:90:5 + --> $DIR/match_single_binding.rs:95:5 | LL | / let product = match coords() { LL | | Point { x, y } => x * y, @@ -151,7 +151,7 @@ LL + let product = x * y; | error: this match could be written as a `let` statement - --> $DIR/match_single_binding.rs:98:18 + --> $DIR/match_single_binding.rs:103:18 | LL | .map(|i| match i.unwrap() { | __________________^ @@ -168,16 +168,16 @@ LL ~ }) | error: this match could be replaced by its body itself - --> $DIR/match_single_binding.rs:124:5 + --> $DIR/match_single_binding.rs:129:5 | LL | / match x { LL | | // => LL | | _ => println!("Not an array index start"), LL | | } - | |_____^ help: consider using the match body instead: `println!("Not an array index start");` + | |_____^ help: consider using the match body instead: `println!("Not an array index start")` error: this assignment could be simplified - --> $DIR/match_single_binding.rs:134:5 + --> $DIR/match_single_binding.rs:138:5 | LL | / val = match val.split_at(idx) { LL | | (pre, suf) => { @@ -197,7 +197,7 @@ LL ~ }; | error: this match could be replaced by its scrutinee and body - --> $DIR/match_single_binding.rs:147:16 + --> $DIR/match_single_binding.rs:151:16 | LL | let _ = || match side_effects() { | ________________^ @@ -209,12 +209,12 @@ help: consider using the scrutinee and body instead | LL ~ let _ = || { LL + side_effects(); -LL + println!("Needs curlies"); +LL + println!("Needs curlies") LL ~ }; | error: this match could be written as a `let` statement - --> $DIR/match_single_binding.rs:154:5 + --> $DIR/match_single_binding.rs:157:5 | LL | / match r { LL | | x => match x { @@ -238,5 +238,80 @@ LL + }, LL ~ }; | -error: aborting due to 15 previous errors +error: this match could be replaced by its body itself + --> $DIR/match_single_binding.rs:170:5 + | +LL | / match 1 { +LL | | _ => (), +LL | | } + | |_____^ help: consider using the match body instead: `();` + +error: this match could be replaced by its body itself + --> $DIR/match_single_binding.rs:174:13 + | +LL | let a = match 1 { + | _____________^ +LL | | _ => (), +LL | | }; + | |_____^ help: consider using the match body instead: `()` + +error: this match could be replaced by its body itself + --> $DIR/match_single_binding.rs:178:5 + | +LL | / match 1 { +LL | | _ => side_effects(), +LL | | } + | |_____^ help: consider using the match body instead: `side_effects();` + +error: this match could be replaced by its body itself + --> $DIR/match_single_binding.rs:182:13 + | +LL | let b = match 1 { + | _____________^ +LL | | _ => side_effects(), +LL | | }; + | |_____^ help: consider using the match body instead: `side_effects()` + +error: this match could be replaced by its body itself + --> $DIR/match_single_binding.rs:186:5 + | +LL | / match 1 { +LL | | _ => println!("1"), +LL | | } + | |_____^ help: consider using the match body instead: `println!("1");` + +error: this match could be replaced by its body itself + --> $DIR/match_single_binding.rs:190:13 + | +LL | let c = match 1 { + | _____________^ +LL | | _ => println!("1"), +LL | | }; + | |_____^ help: consider using the match body instead: `println!("1")` + +error: this match could be replaced by its body itself + --> $DIR/match_single_binding.rs:195:9 + | +LL | / match 1 { +LL | | _ => (), +LL | | }, + | |_________^ help: consider using the match body instead: `()` + +error: this match could be replaced by its body itself + --> $DIR/match_single_binding.rs:198:9 + | +LL | / match 1 { +LL | | _ => side_effects(), +LL | | }, + | |_________^ help: consider using the match body instead: `side_effects()` + +error: this match could be replaced by its body itself + --> $DIR/match_single_binding.rs:201:9 + | +LL | / match 1 { +LL | | _ => println!("1"), +LL | | }, + | |_________^ help: consider using the match body instead: `println!("1")` + +error: aborting due to 24 previous errors diff --git a/tests/ui/match_single_binding2.fixed b/tests/ui/match_single_binding2.fixed index 6a7db67e311..e3cf56a4293 100644 --- a/tests/ui/match_single_binding2.fixed +++ b/tests/ui/match_single_binding2.fixed @@ -30,7 +30,7 @@ fn main() { #[rustfmt::skip] Some((first, _second)) => { let (a, b) = get_tup(); - println!("a {:?} and b {:?}", a, b); + println!("a {:?} and b {:?}", a, b) }, None => println!("nothing"), } @@ -49,5 +49,5 @@ fn main() { 0 => 1, _ => 2, }; - println!("Single branch"); + println!("Single branch") } diff --git a/tests/ui/match_single_binding2.stderr b/tests/ui/match_single_binding2.stderr index 22bf7d8be4a..e180b93e76d 100644 --- a/tests/ui/match_single_binding2.stderr +++ b/tests/ui/match_single_binding2.stderr @@ -27,7 +27,7 @@ LL | | } help: consider using a `let` statement | LL ~ let (a, b) = get_tup(); -LL + println!("a {:?} and b {:?}", a, b); +LL + println!("a {:?} and b {:?}", a, b) | error: this match could be replaced by its scrutinee and body @@ -61,7 +61,7 @@ LL ~ match x { LL + 0 => 1, LL + _ => 2, LL + }; -LL + println!("Single branch"); +LL + println!("Single branch") | error: aborting due to 4 previous errors From 6631480a7b7cb7b3e7d53c9c4cd7915f7ebc3110 Mon Sep 17 00:00:00 2001 From: blyxyas Date: Mon, 13 Mar 2023 19:13:56 +0100 Subject: [PATCH 035/346] Fix false positive with `a = a` --- clippy_lints/src/swap.rs | 1 + tests/ui/swap.fixed | 8 ++++++++ tests/ui/swap.rs | 8 ++++++++ 3 files changed, 17 insertions(+) diff --git a/clippy_lints/src/swap.rs b/clippy_lints/src/swap.rs index 1aeac724ab1..5087c19e5f3 100644 --- a/clippy_lints/src/swap.rs +++ b/clippy_lints/src/swap.rs @@ -190,6 +190,7 @@ fn check_suspicious_swap(cx: &LateContext<'_>, block: &Block<'_>) { && first.span.eq_ctxt(second.span) && is_same(cx, lhs0, rhs1) && is_same(cx, lhs1, rhs0) + && !is_same(cx, lhs1, rhs1) // Ignore a = b; a = a (#10421) && let Some(lhs_sugg) = match &lhs0 { ExprOrIdent::Expr(expr) => Sugg::hir_opt(cx, expr), ExprOrIdent::Ident(ident) => Some(Sugg::NonParen(ident.as_str().into())), diff --git a/tests/ui/swap.fixed b/tests/ui/swap.fixed index 04008c0d9b3..775b0dbde88 100644 --- a/tests/ui/swap.fixed +++ b/tests/ui/swap.fixed @@ -186,3 +186,11 @@ const fn issue_9864(mut u: u32) -> u32 { v = temp; u + v } + +#[allow(clippy::let_and_return)] +const fn issue_10421(x: u32) -> u32 { + let a = x; + let a = a; + let a = a; + a +} diff --git a/tests/ui/swap.rs b/tests/ui/swap.rs index ef8a81c8341..bc9a78b49c7 100644 --- a/tests/ui/swap.rs +++ b/tests/ui/swap.rs @@ -215,3 +215,11 @@ const fn issue_9864(mut u: u32) -> u32 { v = temp; u + v } + +#[allow(clippy::let_and_return)] +const fn issue_10421(x: u32) -> u32 { + let a = x; + let a = a; + let a = a; + a +} From 011bb463370aceee33d7f00a39d87ae8fc856a1c Mon Sep 17 00:00:00 2001 From: J-ZhengLi Date: Tue, 14 Mar 2023 10:24:28 +0800 Subject: [PATCH 036/346] update lint configuration doc for [`ifs_same_cond`] --- book/src/lint_configuration.md | 1 + 1 file changed, 1 insertion(+) diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index 995dd2f04b1..9ed6627b741 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -519,6 +519,7 @@ for the generic parameters for determining interior mutability **Default Value:** `["bytes::Bytes"]` (`Vec`) * [mutable_key_type](https://rust-lang.github.io/rust-clippy/master/index.html#mutable_key_type) +* [ifs_same_cond](https://rust-lang.github.io/rust-clippy/master/index.html#ifs_same_cond) ### allow-mixed-uninlined-format-args From e4ab642e8ce42324798f0ba0e05e139221c2da6d Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Mon, 13 Mar 2023 19:23:11 +0000 Subject: [PATCH 037/346] Use match instead of if in codegen_attrs --- .../rustc_codegen_ssa/src/codegen_attrs.rs | 592 +++++++++--------- 1 file changed, 313 insertions(+), 279 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index f9bb8359208..00eab8d7eb6 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -10,6 +10,7 @@ use rustc_middle::mir::mono::Linkage; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self as ty, TyCtxt}; use rustc_session::{lint, parse::feature_err}; +use rustc_span::symbol::Ident; use rustc_span::{sym, Span}; use rustc_target::spec::{abi, SanitizerSet}; @@ -84,96 +85,115 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs { } }; - if attr.has_name(sym::cold) { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD; - } else if attr.has_name(sym::rustc_allocator) { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR; - } else if attr.has_name(sym::ffi_returns_twice) { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_RETURNS_TWICE; - } else if attr.has_name(sym::ffi_pure) { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_PURE; - } else if attr.has_name(sym::ffi_const) { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_CONST; - } else if attr.has_name(sym::rustc_nounwind) { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND; - } else if attr.has_name(sym::rustc_reallocator) { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::REALLOCATOR; - } else if attr.has_name(sym::rustc_deallocator) { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::DEALLOCATOR; - } else if attr.has_name(sym::rustc_allocator_zeroed) { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR_ZEROED; - } else if attr.has_name(sym::naked) { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED; - } else if attr.has_name(sym::no_mangle) { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE; - } else if attr.has_name(sym::no_coverage) { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_COVERAGE; - } else if attr.has_name(sym::rustc_std_internal_symbol) { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL; - } else if attr.has_name(sym::used) { - let inner = attr.meta_item_list(); - match inner.as_deref() { - Some([item]) if item.has_name(sym::linker) => { - if !tcx.features().used_with_arg { - feature_err( - &tcx.sess.parse_sess, - sym::used_with_arg, - attr.span, - "`#[used(linker)]` is currently unstable", - ) - .emit(); + let Some(Ident { name, .. }) = attr.ident() else { + continue; + }; + + match name { + sym::cold => { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD; + } + sym::rustc_allocator => { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR; + } + sym::ffi_returns_twice => { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_RETURNS_TWICE; + } + sym::ffi_pure => { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_PURE; + } + sym::ffi_const => { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_CONST; + } + sym::rustc_nounwind => { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND; + } + sym::rustc_reallocator => { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::REALLOCATOR; + } + sym::rustc_deallocator => { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::DEALLOCATOR; + } + sym::rustc_allocator_zeroed => { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR_ZEROED; + } + sym::naked => { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED; + } + sym::no_mangle => { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE; + } + sym::no_coverage => { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_COVERAGE; + } + sym::rustc_std_internal_symbol => { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL; + } + sym::used => { + let inner = attr.meta_item_list(); + match inner.as_deref() { + Some([item]) if item.has_name(sym::linker) => { + if !tcx.features().used_with_arg { + feature_err( + &tcx.sess.parse_sess, + sym::used_with_arg, + attr.span, + "`#[used(linker)]` is currently unstable", + ) + .emit(); + } + codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_LINKER; } - codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_LINKER; - } - Some([item]) if item.has_name(sym::compiler) => { - if !tcx.features().used_with_arg { - feature_err( - &tcx.sess.parse_sess, - sym::used_with_arg, - attr.span, - "`#[used(compiler)]` is currently unstable", - ) - .emit(); + Some([item]) if item.has_name(sym::compiler) => { + if !tcx.features().used_with_arg { + feature_err( + &tcx.sess.parse_sess, + sym::used_with_arg, + attr.span, + "`#[used(compiler)]` is currently unstable", + ) + .emit(); + } + codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED; + } + Some(_) => { + tcx.sess.emit_err(ExpectedUsedSymbol { span: attr.span }); + } + None => { + // Unfortunately, unconditionally using `llvm.used` causes + // issues in handling `.init_array` with the gold linker, + // but using `llvm.compiler.used` caused a nontrival amount + // of unintentional ecosystem breakage -- particularly on + // Mach-O targets. + // + // As a result, we emit `llvm.compiler.used` only on ELF + // targets. This is somewhat ad-hoc, but actually follows + // our pre-LLVM 13 behavior (prior to the ecosystem + // breakage), and seems to match `clang`'s behavior as well + // (both before and after LLVM 13), possibly because they + // have similar compatibility concerns to us. See + // https://github.com/rust-lang/rust/issues/47384#issuecomment-1019080146 + // and following comments for some discussion of this, as + // well as the comments in `rustc_codegen_llvm` where these + // flags are handled. + // + // Anyway, to be clear: this is still up in the air + // somewhat, and is subject to change in the future (which + // is a good thing, because this would ideally be a bit + // more firmed up). + let is_like_elf = !(tcx.sess.target.is_like_osx + || tcx.sess.target.is_like_windows + || tcx.sess.target.is_like_wasm); + codegen_fn_attrs.flags |= if is_like_elf { + CodegenFnAttrFlags::USED + } else { + CodegenFnAttrFlags::USED_LINKER + }; } - codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED; - } - Some(_) => { - tcx.sess.emit_err(ExpectedUsedSymbol { span: attr.span }); - } - None => { - // Unfortunately, unconditionally using `llvm.used` causes - // issues in handling `.init_array` with the gold linker, - // but using `llvm.compiler.used` caused a nontrival amount - // of unintentional ecosystem breakage -- particularly on - // Mach-O targets. - // - // As a result, we emit `llvm.compiler.used` only on ELF - // targets. This is somewhat ad-hoc, but actually follows - // our pre-LLVM 13 behavior (prior to the ecosystem - // breakage), and seems to match `clang`'s behavior as well - // (both before and after LLVM 13), possibly because they - // have similar compatibility concerns to us. See - // https://github.com/rust-lang/rust/issues/47384#issuecomment-1019080146 - // and following comments for some discussion of this, as - // well as the comments in `rustc_codegen_llvm` where these - // flags are handled. - // - // Anyway, to be clear: this is still up in the air - // somewhat, and is subject to change in the future (which - // is a good thing, because this would ideally be a bit - // more firmed up). - let is_like_elf = !(tcx.sess.target.is_like_osx - || tcx.sess.target.is_like_windows - || tcx.sess.target.is_like_wasm); - codegen_fn_attrs.flags |= if is_like_elf { - CodegenFnAttrFlags::USED - } else { - CodegenFnAttrFlags::USED_LINKER - }; } } - } else if attr.has_name(sym::cmse_nonsecure_entry) { - if let Some(fn_sig) = fn_sig() + sym::cmse_nonsecure_entry => { + if let Some(fn_sig) = fn_sig() && !matches!(fn_sig.skip_binder().abi(), abi::Abi::C { .. }) { struct_span_err!( @@ -184,236 +204,250 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs { ) .emit(); } - if !tcx.sess.target.llvm_target.contains("thumbv8m") { - struct_span_err!(tcx.sess, attr.span, E0775, "`#[cmse_nonsecure_entry]` is only valid for targets with the TrustZone-M extension") + if !tcx.sess.target.llvm_target.contains("thumbv8m") { + struct_span_err!(tcx.sess, attr.span, E0775, "`#[cmse_nonsecure_entry]` is only valid for targets with the TrustZone-M extension") .emit(); + } + codegen_fn_attrs.flags |= CodegenFnAttrFlags::CMSE_NONSECURE_ENTRY; } - codegen_fn_attrs.flags |= CodegenFnAttrFlags::CMSE_NONSECURE_ENTRY; - } else if attr.has_name(sym::thread_local) { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL; - } else if attr.has_name(sym::track_caller) { - if !tcx.is_closure(did.to_def_id()) + sym::thread_local => { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL; + } + sym::track_caller => { + if !tcx.is_closure(did.to_def_id()) && let Some(fn_sig) = fn_sig() && fn_sig.skip_binder().abi() != abi::Abi::Rust { struct_span_err!(tcx.sess, attr.span, E0737, "`#[track_caller]` requires Rust ABI") .emit(); } - if tcx.is_closure(did.to_def_id()) && !tcx.features().closure_track_caller { - feature_err( - &tcx.sess.parse_sess, - sym::closure_track_caller, - attr.span, - "`#[track_caller]` on closures is currently unstable", - ) - .emit(); - } - codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER; - } else if attr.has_name(sym::export_name) { - if let Some(s) = attr.value_str() { - if s.as_str().contains('\0') { - // `#[export_name = ...]` will be converted to a null-terminated string, - // so it may not contain any null characters. - struct_span_err!( - tcx.sess, + if tcx.is_closure(did.to_def_id()) && !tcx.features().closure_track_caller { + feature_err( + &tcx.sess.parse_sess, + sym::closure_track_caller, attr.span, - E0648, - "`export_name` may not contain null characters" + "`#[track_caller]` on closures is currently unstable", ) .emit(); } - codegen_fn_attrs.export_name = Some(s); + codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER; } - } else if attr.has_name(sym::target_feature) { - if !tcx.is_closure(did.to_def_id()) - && let Some(fn_sig) = fn_sig() - && fn_sig.skip_binder().unsafety() == hir::Unsafety::Normal - { - if tcx.sess.target.is_like_wasm || tcx.sess.opts.actually_rustdoc { - // The `#[target_feature]` attribute is allowed on - // WebAssembly targets on all functions, including safe - // ones. Other targets require that `#[target_feature]` is - // only applied to unsafe functions (pending the - // `target_feature_11` feature) because on most targets - // execution of instructions that are not supported is - // considered undefined behavior. For WebAssembly which is a - // 100% safe target at execution time it's not possible to - // execute undefined instructions, and even if a future - // feature was added in some form for this it would be a - // deterministic trap. There is no undefined behavior when - // executing WebAssembly so `#[target_feature]` is allowed - // on safe functions (but again, only for WebAssembly) - // - // Note that this is also allowed if `actually_rustdoc` so - // if a target is documenting some wasm-specific code then - // it's not spuriously denied. - // - // This exception needs to be kept in sync with allowing - // `#[target_feature]` on `main` and `start`. - } else if !tcx.features().target_feature_11 { - let mut err = feature_err( - &tcx.sess.parse_sess, - sym::target_feature_11, - attr.span, - "`#[target_feature(..)]` can only be applied to `unsafe` functions", - ); - err.span_label(tcx.def_span(did), "not an `unsafe` function"); - err.emit(); - } else { - check_target_feature_trait_unsafe(tcx, did, attr.span); + sym::export_name => { + if let Some(s) = attr.value_str() { + if s.as_str().contains('\0') { + // `#[export_name = ...]` will be converted to a null-terminated string, + // so it may not contain any null characters. + struct_span_err!( + tcx.sess, + attr.span, + E0648, + "`export_name` may not contain null characters" + ) + .emit(); + } + codegen_fn_attrs.export_name = Some(s); } } - from_target_feature( - tcx, - attr, - supported_target_features, - &mut codegen_fn_attrs.target_features, - ); - } else if attr.has_name(sym::linkage) { - if let Some(val) = attr.value_str() { - let linkage = Some(linkage_by_name(tcx, did, val.as_str())); - if tcx.is_foreign_item(did) { - codegen_fn_attrs.import_linkage = linkage; - } else { - codegen_fn_attrs.linkage = linkage; - } - } - } else if attr.has_name(sym::link_section) { - if let Some(val) = attr.value_str() { - if val.as_str().bytes().any(|b| b == 0) { - let msg = format!( - "illegal null byte in link_section \ - value: `{}`", - &val - ); - tcx.sess.span_err(attr.span, &msg); - } else { - codegen_fn_attrs.link_section = Some(val); - } - } - } else if attr.has_name(sym::link_name) { - codegen_fn_attrs.link_name = attr.value_str(); - } else if attr.has_name(sym::link_ordinal) { - link_ordinal_span = Some(attr.span); - if let ordinal @ Some(_) = check_link_ordinal(tcx, attr) { - codegen_fn_attrs.link_ordinal = ordinal; - } - } else if attr.has_name(sym::no_sanitize) { - no_sanitize_span = Some(attr.span); - if let Some(list) = attr.meta_item_list() { - for item in list.iter() { - if item.has_name(sym::address) { - codegen_fn_attrs.no_sanitize |= - SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS; - } else if item.has_name(sym::cfi) { - codegen_fn_attrs.no_sanitize |= SanitizerSet::CFI; - } else if item.has_name(sym::kcfi) { - codegen_fn_attrs.no_sanitize |= SanitizerSet::KCFI; - } else if item.has_name(sym::memory) { - codegen_fn_attrs.no_sanitize |= SanitizerSet::MEMORY; - } else if item.has_name(sym::memtag) { - codegen_fn_attrs.no_sanitize |= SanitizerSet::MEMTAG; - } else if item.has_name(sym::shadow_call_stack) { - codegen_fn_attrs.no_sanitize |= SanitizerSet::SHADOWCALLSTACK; - } else if item.has_name(sym::thread) { - codegen_fn_attrs.no_sanitize |= SanitizerSet::THREAD; - } else if item.has_name(sym::hwaddress) { - codegen_fn_attrs.no_sanitize |= SanitizerSet::HWADDRESS; + sym::target_feature => { + if !tcx.is_closure(did.to_def_id()) + && let Some(fn_sig) = fn_sig() + && fn_sig.skip_binder().unsafety() == hir::Unsafety::Normal + { + if tcx.sess.target.is_like_wasm || tcx.sess.opts.actually_rustdoc { + // The `#[target_feature]` attribute is allowed on + // WebAssembly targets on all functions, including safe + // ones. Other targets require that `#[target_feature]` is + // only applied to unsafe functions (pending the + // `target_feature_11` feature) because on most targets + // execution of instructions that are not supported is + // considered undefined behavior. For WebAssembly which is a + // 100% safe target at execution time it's not possible to + // execute undefined instructions, and even if a future + // feature was added in some form for this it would be a + // deterministic trap. There is no undefined behavior when + // executing WebAssembly so `#[target_feature]` is allowed + // on safe functions (but again, only for WebAssembly) + // + // Note that this is also allowed if `actually_rustdoc` so + // if a target is documenting some wasm-specific code then + // it's not spuriously denied. + // + // This exception needs to be kept in sync with allowing + // `#[target_feature]` on `main` and `start`. + } else if !tcx.features().target_feature_11 { + let mut err = feature_err( + &tcx.sess.parse_sess, + sym::target_feature_11, + attr.span, + "`#[target_feature(..)]` can only be applied to `unsafe` functions", + ); + err.span_label(tcx.def_span(did), "not an `unsafe` function"); + err.emit(); } else { - tcx.sess - .struct_span_err(item.span(), "invalid argument for `no_sanitize`") - .note("expected one of: `address`, `cfi`, `hwaddress`, `kcfi`, `memory`, `memtag`, `shadow-call-stack`, or `thread`") - .emit(); + check_target_feature_trait_unsafe(tcx, did, attr.span); + } + } + from_target_feature( + tcx, + attr, + supported_target_features, + &mut codegen_fn_attrs.target_features, + ); + } + sym::linkage => { + if let Some(val) = attr.value_str() { + let linkage = Some(linkage_by_name(tcx, did, val.as_str())); + if tcx.is_foreign_item(did) { + codegen_fn_attrs.import_linkage = linkage; + } else { + codegen_fn_attrs.linkage = linkage; } } } - } else if attr.has_name(sym::instruction_set) { - codegen_fn_attrs.instruction_set = attr.meta_item_list().and_then(|l| match &l[..] { - [NestedMetaItem::MetaItem(set)] => { - let segments = - set.path.segments.iter().map(|x| x.ident.name).collect::>(); - match segments.as_slice() { - [sym::arm, sym::a32] | [sym::arm, sym::t32] => { - if !tcx.sess.target.has_thumb_interworking { - struct_span_err!( - tcx.sess.diagnostic(), - attr.span, - E0779, - "target does not support `#[instruction_set]`" - ) + sym::link_section => { + if let Some(val) = attr.value_str() { + if val.as_str().bytes().any(|b| b == 0) { + let msg = format!( + "illegal null byte in link_section \ + value: `{}`", + &val + ); + tcx.sess.span_err(attr.span, &msg); + } else { + codegen_fn_attrs.link_section = Some(val); + } + } + } + sym::link_name => { + codegen_fn_attrs.link_name = attr.value_str(); + } + sym::link_ordinal => { + link_ordinal_span = Some(attr.span); + if let ordinal @ Some(_) = check_link_ordinal(tcx, attr) { + codegen_fn_attrs.link_ordinal = ordinal; + } + } + sym::no_sanitize => { + no_sanitize_span = Some(attr.span); + if let Some(list) = attr.meta_item_list() { + for item in list.iter() { + if item.has_name(sym::address) { + codegen_fn_attrs.no_sanitize |= + SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS; + } else if item.has_name(sym::cfi) { + codegen_fn_attrs.no_sanitize |= SanitizerSet::CFI; + } else if item.has_name(sym::kcfi) { + codegen_fn_attrs.no_sanitize |= SanitizerSet::KCFI; + } else if item.has_name(sym::memory) { + codegen_fn_attrs.no_sanitize |= SanitizerSet::MEMORY; + } else if item.has_name(sym::memtag) { + codegen_fn_attrs.no_sanitize |= SanitizerSet::MEMTAG; + } else if item.has_name(sym::shadow_call_stack) { + codegen_fn_attrs.no_sanitize |= SanitizerSet::SHADOWCALLSTACK; + } else if item.has_name(sym::thread) { + codegen_fn_attrs.no_sanitize |= SanitizerSet::THREAD; + } else if item.has_name(sym::hwaddress) { + codegen_fn_attrs.no_sanitize |= SanitizerSet::HWADDRESS; + } else { + tcx.sess + .struct_span_err(item.span(), "invalid argument for `no_sanitize`") + .note("expected one of: `address`, `cfi`, `hwaddress`, `kcfi`, `memory`, `memtag`, `shadow-call-stack`, or `thread`") .emit(); - None - } else if segments[1] == sym::a32 { - Some(InstructionSetAttr::ArmA32) - } else if segments[1] == sym::t32 { - Some(InstructionSetAttr::ArmT32) - } else { - unreachable!() + } + } + } + } + sym::instruction_set => { + codegen_fn_attrs.instruction_set = + attr.meta_item_list().and_then(|l| match &l[..] { + [NestedMetaItem::MetaItem(set)] => { + let segments = + set.path.segments.iter().map(|x| x.ident.name).collect::>(); + match segments.as_slice() { + [sym::arm, sym::a32] | [sym::arm, sym::t32] => { + if !tcx.sess.target.has_thumb_interworking { + struct_span_err!( + tcx.sess.diagnostic(), + attr.span, + E0779, + "target does not support `#[instruction_set]`" + ) + .emit(); + None + } else if segments[1] == sym::a32 { + Some(InstructionSetAttr::ArmA32) + } else if segments[1] == sym::t32 { + Some(InstructionSetAttr::ArmT32) + } else { + unreachable!() + } + } + _ => { + struct_span_err!( + tcx.sess.diagnostic(), + attr.span, + E0779, + "invalid instruction set specified", + ) + .emit(); + None + } } } + [] => { + struct_span_err!( + tcx.sess.diagnostic(), + attr.span, + E0778, + "`#[instruction_set]` requires an argument" + ) + .emit(); + None + } _ => { struct_span_err!( tcx.sess.diagnostic(), attr.span, E0779, - "invalid instruction set specified", + "cannot specify more than one instruction set" ) .emit(); None } - } - } - [] => { - struct_span_err!( - tcx.sess.diagnostic(), - attr.span, - E0778, - "`#[instruction_set]` requires an argument" - ) - .emit(); - None - } - _ => { - struct_span_err!( - tcx.sess.diagnostic(), - attr.span, - E0779, - "cannot specify more than one instruction set" - ) - .emit(); - None - } - }) - } else if attr.has_name(sym::repr) { - codegen_fn_attrs.alignment = match attr.meta_item_list() { - Some(items) => match items.as_slice() { - [item] => match item.name_value_literal() { - Some((sym::align, literal)) => { - let alignment = rustc_attr::parse_alignment(&literal.kind); + }) + } + sym::repr => { + codegen_fn_attrs.alignment = match attr.meta_item_list() { + Some(items) => match items.as_slice() { + [item] => match item.name_value_literal() { + Some((sym::align, literal)) => { + let alignment = rustc_attr::parse_alignment(&literal.kind); - match alignment { - Ok(align) => Some(align), - Err(msg) => { - struct_span_err!( - tcx.sess.diagnostic(), - attr.span, - E0589, - "invalid `repr(align)` attribute: {}", - msg - ) - .emit(); + match alignment { + Ok(align) => Some(align), + Err(msg) => { + struct_span_err!( + tcx.sess.diagnostic(), + attr.span, + E0589, + "invalid `repr(align)` attribute: {}", + msg + ) + .emit(); - None + None + } } } - } + _ => None, + }, + [] => None, _ => None, }, - [] => None, - _ => None, - }, - None => None, - }; + None => None, + }; + } + _ => {} } } From 1d70bd497007e86b0c7713b66402057487ed68f9 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Mon, 13 Mar 2023 19:35:24 +0000 Subject: [PATCH 038/346] Further codegen_attrs cleanups --- .../rustc_codegen_ssa/src/codegen_attrs.rs | 125 +++++++++--------- 1 file changed, 62 insertions(+), 63 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 00eab8d7eb6..352128da3ef 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -194,16 +194,16 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs { } sym::cmse_nonsecure_entry => { if let Some(fn_sig) = fn_sig() - && !matches!(fn_sig.skip_binder().abi(), abi::Abi::C { .. }) - { - struct_span_err!( - tcx.sess, - attr.span, - E0776, - "`#[cmse_nonsecure_entry]` requires C ABI" - ) - .emit(); - } + && !matches!(fn_sig.skip_binder().abi(), abi::Abi::C { .. }) + { + struct_span_err!( + tcx.sess, + attr.span, + E0776, + "`#[cmse_nonsecure_entry]` requires C ABI" + ) + .emit(); + } if !tcx.sess.target.llvm_target.contains("thumbv8m") { struct_span_err!(tcx.sess, attr.span, E0775, "`#[cmse_nonsecure_entry]` is only valid for targets with the TrustZone-M extension") .emit(); @@ -215,12 +215,12 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs { } sym::track_caller => { if !tcx.is_closure(did.to_def_id()) - && let Some(fn_sig) = fn_sig() - && fn_sig.skip_binder().abi() != abi::Abi::Rust - { - struct_span_err!(tcx.sess, attr.span, E0737, "`#[track_caller]` requires Rust ABI") - .emit(); - } + && let Some(fn_sig) = fn_sig() + && fn_sig.skip_binder().abi() != abi::Abi::Rust + { + struct_span_err!(tcx.sess, attr.span, E0737, "`#[track_caller]` requires Rust ABI") + .emit(); + } if tcx.is_closure(did.to_def_id()) && !tcx.features().closure_track_caller { feature_err( &tcx.sess.parse_sess, @@ -331,28 +331,38 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs { no_sanitize_span = Some(attr.span); if let Some(list) = attr.meta_item_list() { for item in list.iter() { - if item.has_name(sym::address) { - codegen_fn_attrs.no_sanitize |= - SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS; - } else if item.has_name(sym::cfi) { - codegen_fn_attrs.no_sanitize |= SanitizerSet::CFI; - } else if item.has_name(sym::kcfi) { - codegen_fn_attrs.no_sanitize |= SanitizerSet::KCFI; - } else if item.has_name(sym::memory) { - codegen_fn_attrs.no_sanitize |= SanitizerSet::MEMORY; - } else if item.has_name(sym::memtag) { - codegen_fn_attrs.no_sanitize |= SanitizerSet::MEMTAG; - } else if item.has_name(sym::shadow_call_stack) { - codegen_fn_attrs.no_sanitize |= SanitizerSet::SHADOWCALLSTACK; - } else if item.has_name(sym::thread) { - codegen_fn_attrs.no_sanitize |= SanitizerSet::THREAD; - } else if item.has_name(sym::hwaddress) { - codegen_fn_attrs.no_sanitize |= SanitizerSet::HWADDRESS; - } else { - tcx.sess + match item.ident().map(|ident| ident.name) { + Some(sym::address) => { + codegen_fn_attrs.no_sanitize |= + SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS; + } + Some(sym::cfi) => { + codegen_fn_attrs.no_sanitize |= SanitizerSet::CFI; + } + Some(sym::kcfi) => { + codegen_fn_attrs.no_sanitize |= SanitizerSet::KCFI; + } + Some(sym::memory) => { + codegen_fn_attrs.no_sanitize |= SanitizerSet::MEMORY; + } + Some(sym::memtag) => { + codegen_fn_attrs.no_sanitize |= SanitizerSet::MEMTAG; + } + Some(sym::shadow_call_stack) => { + codegen_fn_attrs.no_sanitize |= SanitizerSet::SHADOWCALLSTACK; + } + Some(sym::thread) => { + codegen_fn_attrs.no_sanitize |= SanitizerSet::THREAD; + } + Some(sym::hwaddress) => { + codegen_fn_attrs.no_sanitize |= SanitizerSet::HWADDRESS; + } + _ => { + tcx.sess .struct_span_err(item.span(), "invalid argument for `no_sanitize`") .note("expected one of: `address`, `cfi`, `hwaddress`, `kcfi`, `memory`, `memtag`, `shadow-call-stack`, or `thread`") .emit(); + } } } } @@ -417,34 +427,23 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs { }) } sym::repr => { - codegen_fn_attrs.alignment = match attr.meta_item_list() { - Some(items) => match items.as_slice() { - [item] => match item.name_value_literal() { - Some((sym::align, literal)) => { - let alignment = rustc_attr::parse_alignment(&literal.kind); - - match alignment { - Ok(align) => Some(align), - Err(msg) => { - struct_span_err!( - tcx.sess.diagnostic(), - attr.span, - E0589, - "invalid `repr(align)` attribute: {}", - msg - ) - .emit(); - - None - } - } - } - _ => None, - }, - [] => None, - _ => None, - }, - None => None, + codegen_fn_attrs.alignment = if let Some(items) = attr.meta_item_list() + && let [item] = items.as_slice() + && let Some((sym::align, literal)) = item.name_value_literal() + { + rustc_attr::parse_alignment(&literal.kind).map_err(|msg| { + struct_span_err!( + tcx.sess.diagnostic(), + attr.span, + E0589, + "invalid `repr(align)` attribute: {}", + msg + ) + .emit(); + }) + .ok() + } else { + None }; } _ => {} From 5924b46543853ea8d8bbbe886a09036c4fa5a087 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Tue, 14 Mar 2023 12:44:23 +0200 Subject: [PATCH 039/346] Fix documentation for `derived_hash_with_manual_eq` The documentation retained "vice versa" from the previous incarnation of the lint but the lint itself no longer lints against manual `Hash` implementations with a derived `PartialEq`. I also adjusted the documentation for `PartialOrd`-`Ord` lint as "vice versa" seemed a little confusing to me there (as to what it was refering to exactly.) --- clippy_lints/src/derive.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/derive.rs b/clippy_lints/src/derive.rs index b8428d66a5d..1a9dad47839 100644 --- a/clippy_lints/src/derive.rs +++ b/clippy_lints/src/derive.rs @@ -24,8 +24,8 @@ use rustc_span::sym; declare_clippy_lint! { /// ### What it does - /// Checks for deriving `Hash` but implementing `PartialEq` - /// explicitly or vice versa. + /// Lints against manual `PartialEq` implementations for types with a derived `Hash` + /// implementation. /// /// ### Why is this bad? /// The implementation of these traits must agree (for @@ -54,8 +54,8 @@ declare_clippy_lint! { declare_clippy_lint! { /// ### What it does - /// Checks for deriving `Ord` but implementing `PartialOrd` - /// explicitly or vice versa. + /// Lints against manual `PartialOrd` and `Ord` implementations for types with a derived `Ord` + /// or `PartialOrd` implementation. /// /// ### Why is this bad? /// The implementation of these traits must agree (for From e3036613d1151ce64ae32839a785a8b972495e3e Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Wed, 18 Jan 2023 10:20:27 +0100 Subject: [PATCH 040/346] Use getentropy() instead of /dev/urandom on Emscripten `/dev/urandom` is usually available on Emscripten, except when using the special `NODERAWFS` filesystem backend, which replaces all normal filesystem access with direct Node.js operations. Since this filesystem backend directly access the filesystem on the OS, it is not recommended to depend on `/dev/urandom`, especially when trying to run the Wasm binary on OSes that are not Unix-based. This can be considered a non-functional change, since Emscripten implements `/dev/urandom` in the same way as `getentropy()` when not linking with `-sNODERAWFS`. --- library/std/src/sys/unix/rand.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys/unix/rand.rs b/library/std/src/sys/unix/rand.rs index a6fe07873d7..0f347ffab42 100644 --- a/library/std/src/sys/unix/rand.rs +++ b/library/std/src/sys/unix/rand.rs @@ -20,7 +20,8 @@ pub fn hashmap_random_keys() -> (u64, u64) { not(target_os = "netbsd"), not(target_os = "fuchsia"), not(target_os = "redox"), - not(target_os = "vxworks") + not(target_os = "vxworks"), + not(target_os = "emscripten") ))] mod imp { use crate::fs::File; @@ -174,7 +175,7 @@ mod imp { } } -#[cfg(target_os = "openbsd")] +#[cfg(any(target_os = "openbsd", target_os = "emscripten"))] mod imp { use crate::sys::os::errno; From 4d40cdfe2bed80f1fa7c1fe2a1526adb284d1c1d Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Tue, 14 Mar 2023 12:57:38 +0100 Subject: [PATCH 041/346] Update libc dependency of std to 0.2.140 --- Cargo.lock | 4 ++-- library/std/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 51332919fe7..745209c82ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2879,9 +2879,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.139" +version = "0.2.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" dependencies = [ "rustc-std-workspace-core", ] diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 598a4bf9282..6345db24054 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -15,7 +15,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] } panic_unwind = { path = "../panic_unwind", optional = true } panic_abort = { path = "../panic_abort" } core = { path = "../core" } -libc = { version = "0.2.139", default-features = false, features = ['rustc-dep-of-std'] } +libc = { version = "0.2.140", default-features = false, features = ['rustc-dep-of-std'] } compiler_builtins = { version = "0.1.87" } profiler_builtins = { path = "../profiler_builtins", optional = true } unwind = { path = "../unwind" } From e919f0f20e61d6eb0abbd514bf2dd5b35428a2e7 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Fri, 10 Mar 2023 13:13:08 -0500 Subject: [PATCH 042/346] the fix (fixed build by adding missing import.) --- compiler/rustc_target/src/spec/wasm_base.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/compiler/rustc_target/src/spec/wasm_base.rs b/compiler/rustc_target/src/spec/wasm_base.rs index 625d3b37c4f..341763aadba 100644 --- a/compiler/rustc_target/src/spec/wasm_base.rs +++ b/compiler/rustc_target/src/spec/wasm_base.rs @@ -1,3 +1,4 @@ +use super::crt_objects::LinkSelfContainedDefault; use super::{cvs, Cc, LinkerFlavor, PanicStrategy, RelocModel, TargetOptions, TlsModel}; pub fn options() -> TargetOptions { @@ -94,6 +95,13 @@ pub fn options() -> TargetOptions { pre_link_args, + // FIXME: Figure out cases in which WASM needs to link with a native toolchain. + // + // rust-lang/rust#104137: cannot blindly remove this without putting in + // some other way to compensate for lack of `-nostartfiles` in linker + // invocation. + link_self_contained: LinkSelfContainedDefault::True, + // This has no effect in LLVM 8 or prior, but in LLVM 9 and later when // PIC code is implemented this has quite a drastic effect if it stays // at the default, `pic`. In an effort to keep wasm binaries as minimal From f2eddc5924756bbef97e0a02f5120139ca74ecb6 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Tue, 14 Mar 2023 17:18:26 +0000 Subject: [PATCH 043/346] Remove box expressions from HIR --- clippy_lints/src/infinite_iter.rs | 2 +- clippy_lints/src/loops/never_loop.rs | 3 +-- clippy_lints/src/matches/significant_drop_in_scrutinee.rs | 1 - clippy_lints/src/methods/unnecessary_sort_by.rs | 4 ---- clippy_lints/src/no_effect.rs | 6 ++---- clippy_lints/src/shadow.rs | 3 +-- clippy_lints/src/significant_drop_tightening.rs | 1 - clippy_lints/src/utils/author.rs | 5 ----- clippy_utils/src/check_proc_macro.rs | 1 - clippy_utils/src/eager_or_lazy.rs | 3 +-- clippy_utils/src/hir_utils.rs | 3 +-- clippy_utils/src/sugg.rs | 1 - clippy_utils/src/visitors.rs | 1 - 13 files changed, 7 insertions(+), 27 deletions(-) diff --git a/clippy_lints/src/infinite_iter.rs b/clippy_lints/src/infinite_iter.rs index d1d2db27c6f..fe28c526be3 100644 --- a/clippy_lints/src/infinite_iter.rs +++ b/clippy_lints/src/infinite_iter.rs @@ -167,7 +167,7 @@ fn is_infinite(cx: &LateContext<'_>, expr: &Expr<'_>) -> Finiteness { Finite }, ExprKind::Block(block, _) => block.expr.as_ref().map_or(Finite, |e| is_infinite(cx, e)), - ExprKind::Box(e) | ExprKind::AddrOf(BorrowKind::Ref, _, e) => is_infinite(cx, e), + ExprKind::AddrOf(BorrowKind::Ref, _, e) => is_infinite(cx, e), ExprKind::Call(path, _) => { if let ExprKind::Path(ref qpath) = path.kind { cx.qpath_res(qpath, path.hir_id) diff --git a/clippy_lints/src/loops/never_loop.rs b/clippy_lints/src/loops/never_loop.rs index b1bc10802e1..f0a1b1dfe56 100644 --- a/clippy_lints/src/loops/never_loop.rs +++ b/clippy_lints/src/loops/never_loop.rs @@ -124,8 +124,7 @@ fn stmt_to_expr<'tcx>(stmt: &Stmt<'tcx>) -> Option<(&'tcx Expr<'tcx>, Option<&'t #[allow(clippy::too_many_lines)] fn never_loop_expr(expr: &Expr<'_>, ignore_ids: &mut Vec, main_loop_id: HirId) -> NeverLoopResult { match expr.kind { - ExprKind::Box(e) - | ExprKind::Unary(_, e) + ExprKind::Unary(_, e) | ExprKind::Cast(e, _) | ExprKind::Type(e, _) | ExprKind::Field(e, _) diff --git a/clippy_lints/src/matches/significant_drop_in_scrutinee.rs b/clippy_lints/src/matches/significant_drop_in_scrutinee.rs index b33a2478172..04225beeb70 100644 --- a/clippy_lints/src/matches/significant_drop_in_scrutinee.rs +++ b/clippy_lints/src/matches/significant_drop_in_scrutinee.rs @@ -321,7 +321,6 @@ impl<'a, 'tcx> Visitor<'tcx> for SigDropHelper<'a, 'tcx> { self.has_significant_drop = true; } } - ExprKind::Box(..) | ExprKind::Array(..) | ExprKind::Call(..) | ExprKind::Unary(..) | diff --git a/clippy_lints/src/methods/unnecessary_sort_by.rs b/clippy_lints/src/methods/unnecessary_sort_by.rs index 5201da52bbf..67618f7038a 100644 --- a/clippy_lints/src/methods/unnecessary_sort_by.rs +++ b/clippy_lints/src/methods/unnecessary_sort_by.rs @@ -33,10 +33,6 @@ struct SortByKeyDetection { /// contains a and the other replaces it with b) fn mirrored_exprs(a_expr: &Expr<'_>, a_ident: &Ident, b_expr: &Expr<'_>, b_ident: &Ident) -> bool { match (&a_expr.kind, &b_expr.kind) { - // Two boxes with mirrored contents - (ExprKind::Box(left_expr), ExprKind::Box(right_expr)) => { - mirrored_exprs(left_expr, a_ident, right_expr, b_ident) - }, // Two arrays with mirrored contents (ExprKind::Array(left_exprs), ExprKind::Array(right_exprs)) => { iter::zip(*left_exprs, *right_exprs).all(|(left, right)| mirrored_exprs(left, a_ident, right, b_ident)) diff --git a/clippy_lints/src/no_effect.rs b/clippy_lints/src/no_effect.rs index 79c1ae4861e..e3712190e67 100644 --- a/clippy_lints/src/no_effect.rs +++ b/clippy_lints/src/no_effect.rs @@ -127,8 +127,7 @@ fn has_no_effect(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { | ExprKind::Type(inner, _) | ExprKind::Unary(_, inner) | ExprKind::Field(inner, _) - | ExprKind::AddrOf(_, _, inner) - | ExprKind::Box(inner) => has_no_effect(cx, inner), + | ExprKind::AddrOf(_, _, inner) => has_no_effect(cx, inner), ExprKind::Struct(_, fields, ref base) => { !has_drop(cx, cx.typeck_results().expr_ty(expr)) && fields.iter().all(|field| has_no_effect(cx, field.expr)) @@ -234,8 +233,7 @@ fn reduce_expression<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option reduce_expression(cx, inner).or_else(|| Some(vec![inner])), + | ExprKind::AddrOf(_, _, inner) => reduce_expression(cx, inner).or_else(|| Some(vec![inner])), ExprKind::Struct(_, fields, ref base) => { if has_drop(cx, cx.typeck_results().expr_ty(expr)) { None diff --git a/clippy_lints/src/shadow.rs b/clippy_lints/src/shadow.rs index 87f966ced0d..ae7d19624ba 100644 --- a/clippy_lints/src/shadow.rs +++ b/clippy_lints/src/shadow.rs @@ -213,8 +213,7 @@ fn is_self_shadow(cx: &LateContext<'_>, pat: &Pat<'_>, mut expr: &Expr<'_>, hir_ } loop { expr = match expr.kind { - ExprKind::Box(e) - | ExprKind::AddrOf(_, _, e) + ExprKind::AddrOf(_, _, e) | ExprKind::Block( &Block { stmts: [], diff --git a/clippy_lints/src/significant_drop_tightening.rs b/clippy_lints/src/significant_drop_tightening.rs index e2d90edec5a..e12681c0a0c 100644 --- a/clippy_lints/src/significant_drop_tightening.rs +++ b/clippy_lints/src/significant_drop_tightening.rs @@ -380,7 +380,6 @@ impl<'cx, 'sdt, 'tcx> Visitor<'tcx> for SigDropFinder<'cx, 'sdt, 'tcx> { | hir::ExprKind::Assign(..) | hir::ExprKind::AssignOp(..) | hir::ExprKind::Binary(..) - | hir::ExprKind::Box(..) | hir::ExprKind::Call(..) | hir::ExprKind::Field(..) | hir::ExprKind::If(..) diff --git a/clippy_lints/src/utils/author.rs b/clippy_lints/src/utils/author.rs index f31c3fdb095..bc4adf1596d 100644 --- a/clippy_lints/src/utils/author.rs +++ b/clippy_lints/src/utils/author.rs @@ -395,11 +395,6 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { } self.expr(field!(let_expr.init)); }, - ExprKind::Box(inner) => { - bind!(self, inner); - kind!("Box({inner})"); - self.expr(inner); - }, ExprKind::Array(elements) => { bind!(self, elements); kind!("Array({elements})"); diff --git a/clippy_utils/src/check_proc_macro.rs b/clippy_utils/src/check_proc_macro.rs index 43f0df145f0..d3a6929f67e 100644 --- a/clippy_utils/src/check_proc_macro.rs +++ b/clippy_utils/src/check_proc_macro.rs @@ -112,7 +112,6 @@ fn qpath_search_pat(path: &QPath<'_>) -> (Pat, Pat) { /// Get the search patterns to use for the given expression fn expr_search_pat(tcx: TyCtxt<'_>, e: &Expr<'_>) -> (Pat, Pat) { match e.kind { - ExprKind::Box(e) => (Pat::Str("box"), expr_search_pat(tcx, e).1), ExprKind::ConstBlock(_) => (Pat::Str("const"), Pat::Str("}")), ExprKind::Tup([]) => (Pat::Str(")"), Pat::Str("(")), ExprKind::Unary(UnOp::Deref, e) => (Pat::Str("*"), expr_search_pat(tcx, e).1), diff --git a/clippy_utils/src/eager_or_lazy.rs b/clippy_utils/src/eager_or_lazy.rs index ee2f816f181..babbc7294a1 100644 --- a/clippy_utils/src/eager_or_lazy.rs +++ b/clippy_utils/src/eager_or_lazy.rs @@ -199,8 +199,7 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS }, // Memory allocation, custom operator, loop, or call to an unknown function - ExprKind::Box(_) - | ExprKind::Unary(..) + ExprKind::Unary(..) | ExprKind::Binary(..) | ExprKind::Loop(..) | ExprKind::Call(..) => self.eagerness = Lazy, diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs index 0603755f8a9..3a6d23ca5c1 100644 --- a/clippy_utils/src/hir_utils.rs +++ b/clippy_utils/src/hir_utils.rs @@ -249,7 +249,6 @@ impl HirEqInterExpr<'_, '_, '_> { both(&li.label, &ri.label, |l, r| l.ident.name == r.ident.name) && both(le, re, |l, r| self.eq_expr(l, r)) }, - (&ExprKind::Box(l), &ExprKind::Box(r)) => self.eq_expr(l, r), (&ExprKind::Call(l_fun, l_args), &ExprKind::Call(r_fun, r_args)) => { self.inner.allow_side_effects && self.eq_expr(l_fun, r_fun) && self.eq_exprs(l_args, r_args) }, @@ -628,7 +627,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { self.hash_expr(j); } }, - ExprKind::Box(e) | ExprKind::DropTemps(e) | ExprKind::Yield(e, _) => { + ExprKind::DropTemps(e) | ExprKind::Yield(e, _) => { self.hash_expr(e); }, ExprKind::Call(fun, args) => { diff --git a/clippy_utils/src/sugg.rs b/clippy_utils/src/sugg.rs index 85bf28b708b..44cb5d5756a 100644 --- a/clippy_utils/src/sugg.rs +++ b/clippy_utils/src/sugg.rs @@ -133,7 +133,6 @@ impl<'a> Sugg<'a> { match expr.kind { hir::ExprKind::AddrOf(..) - | hir::ExprKind::Box(..) | hir::ExprKind::If(..) | hir::ExprKind::Let(..) | hir::ExprKind::Closure { .. } diff --git a/clippy_utils/src/visitors.rs b/clippy_utils/src/visitors.rs index d27a20bd4df..86a93f64fb7 100644 --- a/clippy_utils/src/visitors.rs +++ b/clippy_utils/src/visitors.rs @@ -600,7 +600,6 @@ pub fn for_each_unconsumed_temporary<'tcx, B>( helper(typeck, false, e, f)?; }, ExprKind::Block(&Block { expr: Some(e), .. }, _) - | ExprKind::Box(e) | ExprKind::Cast(e, _) | ExprKind::Unary(_, e) => { helper(typeck, true, e, f)?; From 568b7221402b348fe65fd87ade2e1174b356bd74 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Fri, 10 Mar 2023 13:13:45 -0500 Subject: [PATCH 044/346] Test using pattern established in run-make/wasm-stringify-ints-small. Replicates problem on my machine. To exercise the test, I had to use a config.toml that has: ``` [build] target = ["x86_64-unknown-linux-gnu","wasm32-unknown-unknown"] nodejs = "node" [rust] lld = true ``` --- tests/run-make/wasm-override-linker/Makefile | 11 +++++++++++ tests/run-make/wasm-override-linker/foo.rs | 1 + 2 files changed, 12 insertions(+) create mode 100644 tests/run-make/wasm-override-linker/Makefile create mode 100644 tests/run-make/wasm-override-linker/foo.rs diff --git a/tests/run-make/wasm-override-linker/Makefile b/tests/run-make/wasm-override-linker/Makefile new file mode 100644 index 00000000000..d6163b1e04f --- /dev/null +++ b/tests/run-make/wasm-override-linker/Makefile @@ -0,0 +1,11 @@ +include ../../run-make-fulldeps/tools.mk + +ifeq ($(TARGET),wasm32-unknown-unknown) +all: + $(RUSTC) foo.rs --crate-type cdylib --target $(TARGET) -C linker=clang +else ifeq ($(TARGET),wasm64-unknown-unknown) +all: + $(RUSTC) foo.rs --crate-type cdylib --target $(TARGET) -C linker=clang +else +all: +endif diff --git a/tests/run-make/wasm-override-linker/foo.rs b/tests/run-make/wasm-override-linker/foo.rs new file mode 100644 index 00000000000..4bd8276f349 --- /dev/null +++ b/tests/run-make/wasm-override-linker/foo.rs @@ -0,0 +1 @@ +// empty file From 3eea49446bae42709b96bd36a0eb2c0966b6b4ac Mon Sep 17 00:00:00 2001 From: blyxyas Date: Tue, 14 Mar 2023 20:59:39 +0100 Subject: [PATCH 045/346] Ignore external macros --- clippy_lints/src/swap.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/swap.rs b/clippy_lints/src/swap.rs index 5087c19e5f3..938ca3a6cee 100644 --- a/clippy_lints/src/swap.rs +++ b/clippy_lints/src/swap.rs @@ -6,7 +6,8 @@ use clippy_utils::{can_mut_borrow_both, eq_expr_value, in_constant, std_or_core} use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::{BinOpKind, Block, Expr, ExprKind, PatKind, QPath, Stmt, StmtKind}; -use rustc_lint::{LateContext, LateLintPass}; +use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_middle::lint::in_external_macro; use rustc_middle::ty; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::source_map::Spanned; @@ -75,7 +76,9 @@ declare_lint_pass!(Swap => [MANUAL_SWAP, ALMOST_SWAPPED]); impl<'tcx> LateLintPass<'tcx> for Swap { fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'_>) { check_manual_swap(cx, block); - check_suspicious_swap(cx, block); + if !in_external_macro(cx.sess(), block.span) { + check_suspicious_swap(cx, block); + } check_xor_swap(cx, block); } } From e2ba75d69da533775f8db90a3348521458cf4fed Mon Sep 17 00:00:00 2001 From: blyxyas Date: Wed, 15 Mar 2023 16:27:46 +0100 Subject: [PATCH 046/346] Add macro test --- tests/ui/swap.fixed | 13 +++++++++++-- tests/ui/swap.rs | 13 +++++++++++-- tests/ui/swap.stderr | 34 +++++++++++++++++----------------- 3 files changed, 39 insertions(+), 21 deletions(-) diff --git a/tests/ui/swap.fixed b/tests/ui/swap.fixed index 775b0dbde88..78d8eedc38a 100644 --- a/tests/ui/swap.fixed +++ b/tests/ui/swap.fixed @@ -8,7 +8,8 @@ redundant_semicolons, dead_code, unused_assignments, - unused_variables + unused_variables, + clippy::let_and_return )] struct Foo(u32); @@ -187,8 +188,16 @@ const fn issue_9864(mut u: u32) -> u32 { u + v } -#[allow(clippy::let_and_return)] +macro_rules! issue_10421 { + () => { + let a = 1; + let b = a; + let b = b; + }; +} + const fn issue_10421(x: u32) -> u32 { + issue_10421!(); let a = x; let a = a; let a = a; diff --git a/tests/ui/swap.rs b/tests/ui/swap.rs index bc9a78b49c7..c995af8ecf9 100644 --- a/tests/ui/swap.rs +++ b/tests/ui/swap.rs @@ -8,7 +8,8 @@ redundant_semicolons, dead_code, unused_assignments, - unused_variables + unused_variables, + clippy::let_and_return )] struct Foo(u32); @@ -216,8 +217,16 @@ const fn issue_9864(mut u: u32) -> u32 { u + v } -#[allow(clippy::let_and_return)] +macro_rules! issue_10421 { + () => { + let a = 1; + let b = a; + let b = b; + }; +} + const fn issue_10421(x: u32) -> u32 { + issue_10421!(); let a = x; let a = a; let a = a; diff --git a/tests/ui/swap.stderr b/tests/ui/swap.stderr index 825c9261e19..e9dacb3119e 100644 --- a/tests/ui/swap.stderr +++ b/tests/ui/swap.stderr @@ -1,5 +1,5 @@ error: this looks like you are swapping `bar.a` and `bar.b` manually - --> $DIR/swap.rs:25:5 + --> $DIR/swap.rs:26:5 | LL | / let temp = bar.a; LL | | bar.a = bar.b; @@ -10,7 +10,7 @@ LL | | bar.b = temp; = note: `-D clippy::manual-swap` implied by `-D warnings` error: this looks like you are swapping elements of `foo` manually - --> $DIR/swap.rs:37:5 + --> $DIR/swap.rs:38:5 | LL | / let temp = foo[0]; LL | | foo[0] = foo[1]; @@ -18,7 +18,7 @@ LL | | foo[1] = temp; | |__________________^ help: try: `foo.swap(0, 1);` error: this looks like you are swapping elements of `foo` manually - --> $DIR/swap.rs:46:5 + --> $DIR/swap.rs:47:5 | LL | / let temp = foo[0]; LL | | foo[0] = foo[1]; @@ -26,7 +26,7 @@ LL | | foo[1] = temp; | |__________________^ help: try: `foo.swap(0, 1);` error: this looks like you are swapping elements of `foo` manually - --> $DIR/swap.rs:65:5 + --> $DIR/swap.rs:66:5 | LL | / let temp = foo[0]; LL | | foo[0] = foo[1]; @@ -34,7 +34,7 @@ LL | | foo[1] = temp; | |__________________^ help: try: `foo.swap(0, 1);` error: this looks like you are swapping `a` and `b` manually - --> $DIR/swap.rs:76:5 + --> $DIR/swap.rs:77:5 | LL | / a ^= b; LL | | b ^= a; @@ -42,7 +42,7 @@ LL | | a ^= b; | |___________^ help: try: `std::mem::swap(&mut a, &mut b);` error: this looks like you are swapping `bar.a` and `bar.b` manually - --> $DIR/swap.rs:84:5 + --> $DIR/swap.rs:85:5 | LL | / bar.a ^= bar.b; LL | | bar.b ^= bar.a; @@ -50,7 +50,7 @@ LL | | bar.a ^= bar.b; | |___________________^ help: try: `std::mem::swap(&mut bar.a, &mut bar.b);` error: this looks like you are swapping elements of `foo` manually - --> $DIR/swap.rs:92:5 + --> $DIR/swap.rs:93:5 | LL | / foo[0] ^= foo[1]; LL | | foo[1] ^= foo[0]; @@ -58,7 +58,7 @@ LL | | foo[0] ^= foo[1]; | |_____________________^ help: try: `foo.swap(0, 1);` error: this looks like you are swapping `foo[0][1]` and `bar[1][0]` manually - --> $DIR/swap.rs:121:5 + --> $DIR/swap.rs:122:5 | LL | / let temp = foo[0][1]; LL | | foo[0][1] = bar[1][0]; @@ -68,7 +68,7 @@ LL | | bar[1][0] = temp; = note: or maybe you should use `std::mem::replace`? error: this looks like you are swapping `a` and `b` manually - --> $DIR/swap.rs:135:7 + --> $DIR/swap.rs:136:7 | LL | ; let t = a; | _______^ @@ -79,7 +79,7 @@ LL | | b = t; = note: or maybe you should use `std::mem::replace`? error: this looks like you are swapping `c.0` and `a` manually - --> $DIR/swap.rs:144:7 + --> $DIR/swap.rs:145:7 | LL | ; let t = c.0; | _______^ @@ -90,7 +90,7 @@ LL | | a = t; = note: or maybe you should use `std::mem::replace`? error: this looks like you are swapping `b` and `a` manually - --> $DIR/swap.rs:170:5 + --> $DIR/swap.rs:171:5 | LL | / let t = b; LL | | b = a; @@ -100,7 +100,7 @@ LL | | a = t; = note: or maybe you should use `std::mem::replace`? error: this looks like you are trying to swap `a` and `b` - --> $DIR/swap.rs:132:5 + --> $DIR/swap.rs:133:5 | LL | / a = b; LL | | b = a; @@ -110,7 +110,7 @@ LL | | b = a; = note: `-D clippy::almost-swapped` implied by `-D warnings` error: this looks like you are trying to swap `c.0` and `a` - --> $DIR/swap.rs:141:5 + --> $DIR/swap.rs:142:5 | LL | / c.0 = a; LL | | a = c.0; @@ -119,7 +119,7 @@ LL | | a = c.0; = note: or maybe you should use `std::mem::replace`? error: this looks like you are trying to swap `a` and `b` - --> $DIR/swap.rs:148:5 + --> $DIR/swap.rs:149:5 | LL | / let a = b; LL | | let b = a; @@ -128,7 +128,7 @@ LL | | let b = a; = note: or maybe you should use `std::mem::replace`? error: this looks like you are trying to swap `d` and `c` - --> $DIR/swap.rs:153:5 + --> $DIR/swap.rs:154:5 | LL | / d = c; LL | | c = d; @@ -137,7 +137,7 @@ LL | | c = d; = note: or maybe you should use `std::mem::replace`? error: this looks like you are trying to swap `a` and `b` - --> $DIR/swap.rs:157:5 + --> $DIR/swap.rs:158:5 | LL | / let a = b; LL | | b = a; @@ -146,7 +146,7 @@ LL | | b = a; = note: or maybe you should use `std::mem::replace`? error: this looks like you are swapping `s.0.x` and `s.0.y` manually - --> $DIR/swap.rs:205:5 + --> $DIR/swap.rs:206:5 | LL | / let t = s.0.x; LL | | s.0.x = s.0.y; From 8a4eb9e3a87b1fb9a5078f6f45cf62e2f9f8bc2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gammels=C3=A6ter?= Date: Wed, 15 Mar 2023 17:23:48 +0100 Subject: [PATCH 047/346] Skip serializing ascii chars in case LUTs Since ascii chars are already handled by a special case in the `to_lower` and `to_upper` functions, there's no need to waste space on them in the LUTs. --- library/core/src/unicode/unicode_data.rs | 26 ------------------- .../src/case_mapping.rs | 25 ++++++++---------- 2 files changed, 11 insertions(+), 40 deletions(-) diff --git a/library/core/src/unicode/unicode_data.rs b/library/core/src/unicode/unicode_data.rs index bd69ca520c2..aac706f3173 100644 --- a/library/core/src/unicode/unicode_data.rs +++ b/library/core/src/unicode/unicode_data.rs @@ -606,19 +606,6 @@ pub mod conversions { 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}']), @@ -1456,19 +1443,6 @@ pub mod conversions { ]; 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}']), diff --git a/src/tools/unicode-table-generator/src/case_mapping.rs b/src/tools/unicode-table-generator/src/case_mapping.rs index 992aac1f857..b8153a71118 100644 --- a/src/tools/unicode-table-generator/src/case_mapping.rs +++ b/src/tools/unicode-table-generator/src/case_mapping.rs @@ -1,27 +1,24 @@ use crate::{fmt_list, UnicodeData}; -use std::fmt; +use std::{collections::BTreeMap, 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(&generate_table("LOWER", &data.to_lower)); file.push_str("\n\n"); - file.push_str(&format!( - "static UPPERCASE_TABLE: {} = &[{}];", - decl_type, - fmt_list(data.to_upper.iter().map(to_mapping)) - )); + file.push_str(&generate_table("UPPER", &data.to_upper)); file } +fn generate_table(case: &str, data: &BTreeMap) -> String { + format!( + "static {}CASE_TABLE: &[(char, [char; 3])] = &[{}];", + case, + fmt_list(data.iter().map(to_mapping).filter(|(k, _)| !k.0.is_ascii())) + ) +} + fn to_mapping((key, (a, b, c)): (&u32, &(u32, u32, u32))) -> (CharEscape, [CharEscape; 3]) { ( CharEscape(std::char::from_u32(*key).unwrap()), From 4b9cb857f9b6da4e3b274601a6c439aac8a2c425 Mon Sep 17 00:00:00 2001 From: blyxyas Date: Wed, 15 Mar 2023 23:18:25 +0100 Subject: [PATCH 048/346] Rename lint --- CHANGELOG.md | 2 +- .../src/{allow_attribute.rs => allow_attributes.rs} | 6 +++--- clippy_lints/src/declared_lints.rs | 2 +- clippy_lints/src/lib.rs | 4 ++-- tests/ui/{allow_attribute.fixed => allow_attributes.fixed} | 2 +- tests/ui/{allow_attribute.rs => allow_attributes.rs} | 2 +- .../ui/{allow_attribute.stderr => allow_attributes.stderr} | 6 +++--- 7 files changed, 12 insertions(+), 12 deletions(-) rename clippy_lints/src/{allow_attribute.rs => allow_attributes.rs} (95%) rename tests/ui/{allow_attribute.fixed => allow_attributes.fixed} (93%) rename tests/ui/{allow_attribute.rs => allow_attributes.rs} (93%) rename tests/ui/{allow_attribute.stderr => allow_attributes.stderr} (69%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b00fd962ca..c090a844858 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4382,7 +4382,7 @@ Released 2018-09-13 [`absurd_extreme_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#absurd_extreme_comparisons [`alloc_instead_of_core`]: https://rust-lang.github.io/rust-clippy/master/index.html#alloc_instead_of_core -[`allow_attribute`]: https://rust-lang.github.io/rust-clippy/master/index.html#allow_attribute +[`allow_attributes`]: https://rust-lang.github.io/rust-clippy/master/index.html#allow_attributes [`allow_attributes_without_reason`]: https://rust-lang.github.io/rust-clippy/master/index.html#allow_attributes_without_reason [`almost_complete_letter_range`]: https://rust-lang.github.io/rust-clippy/master/index.html#almost_complete_letter_range [`almost_complete_range`]: https://rust-lang.github.io/rust-clippy/master/index.html#almost_complete_range diff --git a/clippy_lints/src/allow_attribute.rs b/clippy_lints/src/allow_attributes.rs similarity index 95% rename from clippy_lints/src/allow_attribute.rs rename to clippy_lints/src/allow_attributes.rs index 28fc45d0554..3d660a11ea3 100644 --- a/clippy_lints/src/allow_attribute.rs +++ b/clippy_lints/src/allow_attributes.rs @@ -40,12 +40,12 @@ declare_clippy_lint! { /// } /// ``` #[clippy::version = "1.69.0"] - pub ALLOW_ATTRIBUTE, + pub ALLOW_ATTRIBUTES, restriction, "`#[allow]` will not trigger if a warning isn't found. `#[expect]` triggers if there are no warnings." } -declare_lint_pass!(AllowAttribute => [ALLOW_ATTRIBUTE]); +declare_lint_pass!(AllowAttribute => [ALLOW_ATTRIBUTES]); impl LateLintPass<'_> for AllowAttribute { // Separate each crate's features. @@ -58,7 +58,7 @@ impl LateLintPass<'_> for AllowAttribute { then { span_lint_and_sugg( cx, - ALLOW_ATTRIBUTE, + ALLOW_ATTRIBUTES, ident.span, "#[allow] attribute found", "replace it with", "expect".into() diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 73f74d59f4a..25f15973490 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -35,7 +35,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::utils::internal_lints::produce_ice::PRODUCE_ICE_INFO, #[cfg(feature = "internal")] crate::utils::internal_lints::unnecessary_def_path::UNNECESSARY_DEF_PATH_INFO, - crate::allow_attribute::ALLOW_ATTRIBUTE_INFO, + crate::allow_attributes::ALLOW_ATTRIBUTES_INFO, crate::almost_complete_range::ALMOST_COMPLETE_RANGE_INFO, crate::approx_const::APPROX_CONSTANT_INFO, crate::as_conversions::AS_CONVERSIONS_INFO, diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index a3c65a69c99..c455c3e3058 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -67,7 +67,7 @@ mod declared_lints; mod renamed_lints; // begin lints modules, do not remove this comment, it’s used in `update_lints` -mod allow_attribute; +mod allow_attributes; mod almost_complete_range; mod approx_const; mod as_conversions; @@ -934,7 +934,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|_| Box::new(missing_assert_message::MissingAssertMessage)); store.register_early_pass(|| Box::new(redundant_async_block::RedundantAsyncBlock)); store.register_late_pass(|_| Box::new(let_with_type_underscore::UnderscoreTyped)); - store.register_late_pass(|_| Box::new(allow_attribute::AllowAttribute)); + store.register_late_pass(|_| Box::new(allow_attributes::AllowAttribute)); // add lints here, do not remove this comment, it's used in `new_lint` } diff --git a/tests/ui/allow_attribute.fixed b/tests/ui/allow_attributes.fixed similarity index 93% rename from tests/ui/allow_attribute.fixed rename to tests/ui/allow_attributes.fixed index 01759ced09d..b8dd0619e6d 100644 --- a/tests/ui/allow_attribute.fixed +++ b/tests/ui/allow_attributes.fixed @@ -1,6 +1,6 @@ // run-rustfix #![allow(unused)] -#![warn(clippy::allow_attribute)] +#![warn(clippy::allow_attributes)] #![feature(lint_reasons)] fn main() {} diff --git a/tests/ui/allow_attribute.rs b/tests/ui/allow_attributes.rs similarity index 93% rename from tests/ui/allow_attribute.rs rename to tests/ui/allow_attributes.rs index b8e341fe9e4..295f560906a 100644 --- a/tests/ui/allow_attribute.rs +++ b/tests/ui/allow_attributes.rs @@ -1,6 +1,6 @@ // run-rustfix #![allow(unused)] -#![warn(clippy::allow_attribute)] +#![warn(clippy::allow_attributes)] #![feature(lint_reasons)] fn main() {} diff --git a/tests/ui/allow_attribute.stderr b/tests/ui/allow_attributes.stderr similarity index 69% rename from tests/ui/allow_attribute.stderr rename to tests/ui/allow_attributes.stderr index 58b7323b068..681837e9ed7 100644 --- a/tests/ui/allow_attribute.stderr +++ b/tests/ui/allow_attributes.stderr @@ -1,13 +1,13 @@ error: #[allow] attribute found - --> $DIR/allow_attribute.rs:11:3 + --> $DIR/allow_attributes.rs:11:3 | LL | #[allow(dead_code)] | ^^^^^ help: replace it with: `expect` | - = note: `-D clippy::allow-attribute` implied by `-D warnings` + = note: `-D clippy::allow-attributes` implied by `-D warnings` error: #[allow] attribute found - --> $DIR/allow_attribute.rs:20:30 + --> $DIR/allow_attributes.rs:20:30 | LL | #[cfg_attr(panic = "unwind", allow(dead_code))] | ^^^^^ help: replace it with: `expect` From 1cab0cbaf0dddb4cd403c4a0c391315801a22835 Mon Sep 17 00:00:00 2001 From: blyxyas Date: Wed, 15 Mar 2023 23:20:52 +0100 Subject: [PATCH 049/346] Fix formatting, remove commented code, etc... --- clippy_lints/src/allow_attributes.rs | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/clippy_lints/src/allow_attributes.rs b/clippy_lints/src/allow_attributes.rs index 3d660a11ea3..15d46e954a9 100644 --- a/clippy_lints/src/allow_attributes.rs +++ b/clippy_lints/src/allow_attributes.rs @@ -6,7 +6,7 @@ use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { - /// Detects uses of the `#[allow]` attribute and suggests replacing it with + /// Detects uses of the `#[allow]` attribute and suggests replacing it with /// the `#[expect]` (See [RFC 2383](https://rust-lang.github.io/rfcs/2383-lint-reasons.html)) /// /// The expect attribute is still unstable and requires the `lint_reasons` @@ -28,11 +28,11 @@ declare_clippy_lint! { /// fn foo() -> usize { /// let mut a = Vec::new(); /// a.len() - ///} + /// } /// ``` /// Use instead: /// ```rust,ignore - /// # #![feature(lint_reasons)] + /// #![feature(lint_reasons)] /// #[expect(unused_mut)] /// fn foo() -> usize { /// let mut a = Vec::new(); @@ -61,18 +61,10 @@ impl LateLintPass<'_> for AllowAttribute { ALLOW_ATTRIBUTES, ident.span, "#[allow] attribute found", - "replace it with", "expect".into() - // format!("expect{}", snippet( - // cx, - // ident.span - // .with_lo( - // ident.span.hi() + BytePos(2) // Cut *( - // ) - // .with_hi( - // attr.meta().unwrap().span.hi() - BytePos(1) // Cut ) - // ) - // , "...")) - , Applicability::MachineApplicable); + "replace it with", + "expect".into(), + Applicability::MachineApplicable, + ); } } } From d1b28f3a5f6c9836a3a1018427739a5a0cfc3f06 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Thu, 16 Mar 2023 12:08:07 +0100 Subject: [PATCH 050/346] Fix clippy. --- clippy_utils/src/macros.rs | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/clippy_utils/src/macros.rs b/clippy_utils/src/macros.rs index e135bd9feee..c0e32068eca 100644 --- a/clippy_utils/src/macros.rs +++ b/clippy_utils/src/macros.rs @@ -533,6 +533,14 @@ struct FormatArgsValues<'tcx> { } impl<'tcx> FormatArgsValues<'tcx> { + fn new_empty(format_string_span: SpanData) -> Self { + Self { + value_args: Vec::new(), + pos_to_value_index: Vec::new(), + format_string_span, + } + } + fn new(args: &'tcx Expr<'tcx>, format_string_span: SpanData) -> Self { let mut pos_to_value_index = Vec::new(); let mut value_args = Vec::new(); @@ -997,12 +1005,13 @@ impl<'tcx> FormatArgsExpn<'tcx> { .find(|&name| matches!(name, sym::const_format_args | sym::format_args | sym::format_args_nl))?; let newline = macro_name == sym::format_args_nl; + // ::core::fmt::Arguments::new_const(pieces) // ::core::fmt::Arguments::new_v1(pieces, args) // ::core::fmt::Arguments::new_v1_formatted(pieces, args, fmt, _unsafe_arg) - if let ExprKind::Call(callee, [pieces, args, rest @ ..]) = expr.kind + if let ExprKind::Call(callee, [pieces, rest @ ..]) = expr.kind && let ExprKind::Path(QPath::TypeRelative(ty, seg)) = callee.kind && let TyKind::Path(QPath::LangItem(LangItem::FormatArguments, _, _)) = ty.kind - && matches!(seg.ident.as_str(), "new_v1" | "new_v1_formatted") + && matches!(seg.ident.as_str(), "new_const" | "new_v1" | "new_v1_formatted") { let format_string = FormatString::new(cx, pieces)?; @@ -1026,7 +1035,7 @@ impl<'tcx> FormatArgsExpn<'tcx> { return None; } - let positions = if let Some(fmt_arg) = rest.first() { + let positions = if let Some(fmt_arg) = rest.get(1) { // If the argument contains format specs, `new_v1_formatted(_, _, fmt, _)`, parse // them. @@ -1042,7 +1051,11 @@ impl<'tcx> FormatArgsExpn<'tcx> { })) }; - let values = FormatArgsValues::new(args, format_string.span.data()); + let values = if let Some(args) = rest.first() { + FormatArgsValues::new(args, format_string.span.data()) + } else { + FormatArgsValues::new_empty(format_string.span.data()) + }; let args = izip!(positions, parsed_args, parser.arg_places) .map(|(position, parsed_arg, arg_span)| { From f9bd88438589fa6fcc8eefe97061a7a3703ca625 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gammels=C3=A6ter?= Date: Thu, 16 Mar 2023 11:56:33 +0100 Subject: [PATCH 051/346] Split unicode case LUTs in single and multi variants The majority of char case replacements are single char replacements, so storing them as [char; 3] wastes a lot of space. This commit splits the replacement tables for both `to_lower` and `to_upper` into two separate tables, one with single-character mappings and one with multi-character mappings. This reduces the binary size for programs using all of these tables with roughly 24K bytes. --- library/core/src/unicode/unicode_data.rs | 2645 ++++++----------- .../src/case_mapping.rs | 58 +- 2 files changed, 1008 insertions(+), 1695 deletions(-) diff --git a/library/core/src/unicode/unicode_data.rs b/library/core/src/unicode/unicode_data.rs index aac706f3173..20b3587ab65 100644 --- a/library/core/src/unicode/unicode_data.rs +++ b/library/core/src/unicode/unicode_data.rs @@ -584,9 +584,9 @@ pub mod conversions { if c.is_ascii() { [(c as u8).to_ascii_lowercase() as char, '\0', '\0'] } else { - match bsearch_case_table(c, LOWERCASE_TABLE) { + match bsearch_case_tables(c, LOWERCASE_TABLE_SINGLE, LOWERCASE_TABLE_MULTI) { + Some(replacement) => replacement, None => [c, '\0', '\0'], - Some(index) => LOWERCASE_TABLE[index].1, } } } @@ -595,1224 +595,973 @@ pub mod conversions { if c.is_ascii() { [(c as u8).to_ascii_uppercase() as char, '\0', '\0'] } else { - match bsearch_case_table(c, UPPERCASE_TABLE) { + match bsearch_case_tables(c, UPPERCASE_TABLE_SINGLE, UPPERCASE_TABLE_MULTI) { + Some(replacement) => replacement, 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() + fn bsearch_case_tables( + c: char, + single: &[(char, char)], + multi: &[(char, [char; 3])], + ) -> Option<[char; 3]> { + match single.binary_search_by(|&(key, _)| key.cmp(&c)) { + Ok(i) => Some([single[i].1, '\0', '\0']), + Err(_) => multi.binary_search_by(|&(key, _)| key.cmp(&c)).map(|i| multi[i].1).ok(), + } } - static LOWERCASE_TABLE: &[(char, [char; 3])] = &[ - ('\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{2c2f}', ['\u{2c5f}', '\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{a7c0}', ['\u{a7c1}', '\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{a7c7}', ['\u{a7c8}', '\u{0}', '\u{0}']), - ('\u{a7c9}', ['\u{a7ca}', '\u{0}', '\u{0}']), ('\u{a7d0}', ['\u{a7d1}', '\u{0}', '\u{0}']), - ('\u{a7d6}', ['\u{a7d7}', '\u{0}', '\u{0}']), ('\u{a7d8}', ['\u{a7d9}', '\u{0}', '\u{0}']), - ('\u{a7f5}', ['\u{a7f6}', '\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{10570}', ['\u{10597}', '\u{0}', '\u{0}']), - ('\u{10571}', ['\u{10598}', '\u{0}', '\u{0}']), - ('\u{10572}', ['\u{10599}', '\u{0}', '\u{0}']), - ('\u{10573}', ['\u{1059a}', '\u{0}', '\u{0}']), - ('\u{10574}', ['\u{1059b}', '\u{0}', '\u{0}']), - ('\u{10575}', ['\u{1059c}', '\u{0}', '\u{0}']), - ('\u{10576}', ['\u{1059d}', '\u{0}', '\u{0}']), - ('\u{10577}', ['\u{1059e}', '\u{0}', '\u{0}']), - ('\u{10578}', ['\u{1059f}', '\u{0}', '\u{0}']), - ('\u{10579}', ['\u{105a0}', '\u{0}', '\u{0}']), - ('\u{1057a}', ['\u{105a1}', '\u{0}', '\u{0}']), - ('\u{1057c}', ['\u{105a3}', '\u{0}', '\u{0}']), - ('\u{1057d}', ['\u{105a4}', '\u{0}', '\u{0}']), - ('\u{1057e}', ['\u{105a5}', '\u{0}', '\u{0}']), - ('\u{1057f}', ['\u{105a6}', '\u{0}', '\u{0}']), - ('\u{10580}', ['\u{105a7}', '\u{0}', '\u{0}']), - ('\u{10581}', ['\u{105a8}', '\u{0}', '\u{0}']), - ('\u{10582}', ['\u{105a9}', '\u{0}', '\u{0}']), - ('\u{10583}', ['\u{105aa}', '\u{0}', '\u{0}']), - ('\u{10584}', ['\u{105ab}', '\u{0}', '\u{0}']), - ('\u{10585}', ['\u{105ac}', '\u{0}', '\u{0}']), - ('\u{10586}', ['\u{105ad}', '\u{0}', '\u{0}']), - ('\u{10587}', ['\u{105ae}', '\u{0}', '\u{0}']), - ('\u{10588}', ['\u{105af}', '\u{0}', '\u{0}']), - ('\u{10589}', ['\u{105b0}', '\u{0}', '\u{0}']), - ('\u{1058a}', ['\u{105b1}', '\u{0}', '\u{0}']), - ('\u{1058c}', ['\u{105b3}', '\u{0}', '\u{0}']), - ('\u{1058d}', ['\u{105b4}', '\u{0}', '\u{0}']), - ('\u{1058e}', ['\u{105b5}', '\u{0}', '\u{0}']), - ('\u{1058f}', ['\u{105b6}', '\u{0}', '\u{0}']), - ('\u{10590}', ['\u{105b7}', '\u{0}', '\u{0}']), - ('\u{10591}', ['\u{105b8}', '\u{0}', '\u{0}']), - ('\u{10592}', ['\u{105b9}', '\u{0}', '\u{0}']), - ('\u{10594}', ['\u{105bb}', '\u{0}', '\u{0}']), - ('\u{10595}', ['\u{105bc}', '\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 LOWERCASE_TABLE_SINGLE: &[(char, char)] = &[ + ('\u{c0}', '\u{e0}'), ('\u{c1}', '\u{e1}'), ('\u{c2}', '\u{e2}'), ('\u{c3}', '\u{e3}'), + ('\u{c4}', '\u{e4}'), ('\u{c5}', '\u{e5}'), ('\u{c6}', '\u{e6}'), ('\u{c7}', '\u{e7}'), + ('\u{c8}', '\u{e8}'), ('\u{c9}', '\u{e9}'), ('\u{ca}', '\u{ea}'), ('\u{cb}', '\u{eb}'), + ('\u{cc}', '\u{ec}'), ('\u{cd}', '\u{ed}'), ('\u{ce}', '\u{ee}'), ('\u{cf}', '\u{ef}'), + ('\u{d0}', '\u{f0}'), ('\u{d1}', '\u{f1}'), ('\u{d2}', '\u{f2}'), ('\u{d3}', '\u{f3}'), + ('\u{d4}', '\u{f4}'), ('\u{d5}', '\u{f5}'), ('\u{d6}', '\u{f6}'), ('\u{d8}', '\u{f8}'), + ('\u{d9}', '\u{f9}'), ('\u{da}', '\u{fa}'), ('\u{db}', '\u{fb}'), ('\u{dc}', '\u{fc}'), + ('\u{dd}', '\u{fd}'), ('\u{de}', '\u{fe}'), ('\u{100}', '\u{101}'), ('\u{102}', '\u{103}'), + ('\u{104}', '\u{105}'), ('\u{106}', '\u{107}'), ('\u{108}', '\u{109}'), + ('\u{10a}', '\u{10b}'), ('\u{10c}', '\u{10d}'), ('\u{10e}', '\u{10f}'), + ('\u{110}', '\u{111}'), ('\u{112}', '\u{113}'), ('\u{114}', '\u{115}'), + ('\u{116}', '\u{117}'), ('\u{118}', '\u{119}'), ('\u{11a}', '\u{11b}'), + ('\u{11c}', '\u{11d}'), ('\u{11e}', '\u{11f}'), ('\u{120}', '\u{121}'), + ('\u{122}', '\u{123}'), ('\u{124}', '\u{125}'), ('\u{126}', '\u{127}'), + ('\u{128}', '\u{129}'), ('\u{12a}', '\u{12b}'), ('\u{12c}', '\u{12d}'), + ('\u{12e}', '\u{12f}'), ('\u{132}', '\u{133}'), ('\u{134}', '\u{135}'), + ('\u{136}', '\u{137}'), ('\u{139}', '\u{13a}'), ('\u{13b}', '\u{13c}'), + ('\u{13d}', '\u{13e}'), ('\u{13f}', '\u{140}'), ('\u{141}', '\u{142}'), + ('\u{143}', '\u{144}'), ('\u{145}', '\u{146}'), ('\u{147}', '\u{148}'), + ('\u{14a}', '\u{14b}'), ('\u{14c}', '\u{14d}'), ('\u{14e}', '\u{14f}'), + ('\u{150}', '\u{151}'), ('\u{152}', '\u{153}'), ('\u{154}', '\u{155}'), + ('\u{156}', '\u{157}'), ('\u{158}', '\u{159}'), ('\u{15a}', '\u{15b}'), + ('\u{15c}', '\u{15d}'), ('\u{15e}', '\u{15f}'), ('\u{160}', '\u{161}'), + ('\u{162}', '\u{163}'), ('\u{164}', '\u{165}'), ('\u{166}', '\u{167}'), + ('\u{168}', '\u{169}'), ('\u{16a}', '\u{16b}'), ('\u{16c}', '\u{16d}'), + ('\u{16e}', '\u{16f}'), ('\u{170}', '\u{171}'), ('\u{172}', '\u{173}'), + ('\u{174}', '\u{175}'), ('\u{176}', '\u{177}'), ('\u{178}', '\u{ff}'), + ('\u{179}', '\u{17a}'), ('\u{17b}', '\u{17c}'), ('\u{17d}', '\u{17e}'), + ('\u{181}', '\u{253}'), ('\u{182}', '\u{183}'), ('\u{184}', '\u{185}'), + ('\u{186}', '\u{254}'), ('\u{187}', '\u{188}'), ('\u{189}', '\u{256}'), + ('\u{18a}', '\u{257}'), ('\u{18b}', '\u{18c}'), ('\u{18e}', '\u{1dd}'), + ('\u{18f}', '\u{259}'), ('\u{190}', '\u{25b}'), ('\u{191}', '\u{192}'), + ('\u{193}', '\u{260}'), ('\u{194}', '\u{263}'), ('\u{196}', '\u{269}'), + ('\u{197}', '\u{268}'), ('\u{198}', '\u{199}'), ('\u{19c}', '\u{26f}'), + ('\u{19d}', '\u{272}'), ('\u{19f}', '\u{275}'), ('\u{1a0}', '\u{1a1}'), + ('\u{1a2}', '\u{1a3}'), ('\u{1a4}', '\u{1a5}'), ('\u{1a6}', '\u{280}'), + ('\u{1a7}', '\u{1a8}'), ('\u{1a9}', '\u{283}'), ('\u{1ac}', '\u{1ad}'), + ('\u{1ae}', '\u{288}'), ('\u{1af}', '\u{1b0}'), ('\u{1b1}', '\u{28a}'), + ('\u{1b2}', '\u{28b}'), ('\u{1b3}', '\u{1b4}'), ('\u{1b5}', '\u{1b6}'), + ('\u{1b7}', '\u{292}'), ('\u{1b8}', '\u{1b9}'), ('\u{1bc}', '\u{1bd}'), + ('\u{1c4}', '\u{1c6}'), ('\u{1c5}', '\u{1c6}'), ('\u{1c7}', '\u{1c9}'), + ('\u{1c8}', '\u{1c9}'), ('\u{1ca}', '\u{1cc}'), ('\u{1cb}', '\u{1cc}'), + ('\u{1cd}', '\u{1ce}'), ('\u{1cf}', '\u{1d0}'), ('\u{1d1}', '\u{1d2}'), + ('\u{1d3}', '\u{1d4}'), ('\u{1d5}', '\u{1d6}'), ('\u{1d7}', '\u{1d8}'), + ('\u{1d9}', '\u{1da}'), ('\u{1db}', '\u{1dc}'), ('\u{1de}', '\u{1df}'), + ('\u{1e0}', '\u{1e1}'), ('\u{1e2}', '\u{1e3}'), ('\u{1e4}', '\u{1e5}'), + ('\u{1e6}', '\u{1e7}'), ('\u{1e8}', '\u{1e9}'), ('\u{1ea}', '\u{1eb}'), + ('\u{1ec}', '\u{1ed}'), ('\u{1ee}', '\u{1ef}'), ('\u{1f1}', '\u{1f3}'), + ('\u{1f2}', '\u{1f3}'), ('\u{1f4}', '\u{1f5}'), ('\u{1f6}', '\u{195}'), + ('\u{1f7}', '\u{1bf}'), ('\u{1f8}', '\u{1f9}'), ('\u{1fa}', '\u{1fb}'), + ('\u{1fc}', '\u{1fd}'), ('\u{1fe}', '\u{1ff}'), ('\u{200}', '\u{201}'), + ('\u{202}', '\u{203}'), ('\u{204}', '\u{205}'), ('\u{206}', '\u{207}'), + ('\u{208}', '\u{209}'), ('\u{20a}', '\u{20b}'), ('\u{20c}', '\u{20d}'), + ('\u{20e}', '\u{20f}'), ('\u{210}', '\u{211}'), ('\u{212}', '\u{213}'), + ('\u{214}', '\u{215}'), ('\u{216}', '\u{217}'), ('\u{218}', '\u{219}'), + ('\u{21a}', '\u{21b}'), ('\u{21c}', '\u{21d}'), ('\u{21e}', '\u{21f}'), + ('\u{220}', '\u{19e}'), ('\u{222}', '\u{223}'), ('\u{224}', '\u{225}'), + ('\u{226}', '\u{227}'), ('\u{228}', '\u{229}'), ('\u{22a}', '\u{22b}'), + ('\u{22c}', '\u{22d}'), ('\u{22e}', '\u{22f}'), ('\u{230}', '\u{231}'), + ('\u{232}', '\u{233}'), ('\u{23a}', '\u{2c65}'), ('\u{23b}', '\u{23c}'), + ('\u{23d}', '\u{19a}'), ('\u{23e}', '\u{2c66}'), ('\u{241}', '\u{242}'), + ('\u{243}', '\u{180}'), ('\u{244}', '\u{289}'), ('\u{245}', '\u{28c}'), + ('\u{246}', '\u{247}'), ('\u{248}', '\u{249}'), ('\u{24a}', '\u{24b}'), + ('\u{24c}', '\u{24d}'), ('\u{24e}', '\u{24f}'), ('\u{370}', '\u{371}'), + ('\u{372}', '\u{373}'), ('\u{376}', '\u{377}'), ('\u{37f}', '\u{3f3}'), + ('\u{386}', '\u{3ac}'), ('\u{388}', '\u{3ad}'), ('\u{389}', '\u{3ae}'), + ('\u{38a}', '\u{3af}'), ('\u{38c}', '\u{3cc}'), ('\u{38e}', '\u{3cd}'), + ('\u{38f}', '\u{3ce}'), ('\u{391}', '\u{3b1}'), ('\u{392}', '\u{3b2}'), + ('\u{393}', '\u{3b3}'), ('\u{394}', '\u{3b4}'), ('\u{395}', '\u{3b5}'), + ('\u{396}', '\u{3b6}'), ('\u{397}', '\u{3b7}'), ('\u{398}', '\u{3b8}'), + ('\u{399}', '\u{3b9}'), ('\u{39a}', '\u{3ba}'), ('\u{39b}', '\u{3bb}'), + ('\u{39c}', '\u{3bc}'), ('\u{39d}', '\u{3bd}'), ('\u{39e}', '\u{3be}'), + ('\u{39f}', '\u{3bf}'), ('\u{3a0}', '\u{3c0}'), ('\u{3a1}', '\u{3c1}'), + ('\u{3a3}', '\u{3c3}'), ('\u{3a4}', '\u{3c4}'), ('\u{3a5}', '\u{3c5}'), + ('\u{3a6}', '\u{3c6}'), ('\u{3a7}', '\u{3c7}'), ('\u{3a8}', '\u{3c8}'), + ('\u{3a9}', '\u{3c9}'), ('\u{3aa}', '\u{3ca}'), ('\u{3ab}', '\u{3cb}'), + ('\u{3cf}', '\u{3d7}'), ('\u{3d8}', '\u{3d9}'), ('\u{3da}', '\u{3db}'), + ('\u{3dc}', '\u{3dd}'), ('\u{3de}', '\u{3df}'), ('\u{3e0}', '\u{3e1}'), + ('\u{3e2}', '\u{3e3}'), ('\u{3e4}', '\u{3e5}'), ('\u{3e6}', '\u{3e7}'), + ('\u{3e8}', '\u{3e9}'), ('\u{3ea}', '\u{3eb}'), ('\u{3ec}', '\u{3ed}'), + ('\u{3ee}', '\u{3ef}'), ('\u{3f4}', '\u{3b8}'), ('\u{3f7}', '\u{3f8}'), + ('\u{3f9}', '\u{3f2}'), ('\u{3fa}', '\u{3fb}'), ('\u{3fd}', '\u{37b}'), + ('\u{3fe}', '\u{37c}'), ('\u{3ff}', '\u{37d}'), ('\u{400}', '\u{450}'), + ('\u{401}', '\u{451}'), ('\u{402}', '\u{452}'), ('\u{403}', '\u{453}'), + ('\u{404}', '\u{454}'), ('\u{405}', '\u{455}'), ('\u{406}', '\u{456}'), + ('\u{407}', '\u{457}'), ('\u{408}', '\u{458}'), ('\u{409}', '\u{459}'), + ('\u{40a}', '\u{45a}'), ('\u{40b}', '\u{45b}'), ('\u{40c}', '\u{45c}'), + ('\u{40d}', '\u{45d}'), ('\u{40e}', '\u{45e}'), ('\u{40f}', '\u{45f}'), + ('\u{410}', '\u{430}'), ('\u{411}', '\u{431}'), ('\u{412}', '\u{432}'), + ('\u{413}', '\u{433}'), ('\u{414}', '\u{434}'), ('\u{415}', '\u{435}'), + ('\u{416}', '\u{436}'), ('\u{417}', '\u{437}'), ('\u{418}', '\u{438}'), + ('\u{419}', '\u{439}'), ('\u{41a}', '\u{43a}'), ('\u{41b}', '\u{43b}'), + ('\u{41c}', '\u{43c}'), ('\u{41d}', '\u{43d}'), ('\u{41e}', '\u{43e}'), + ('\u{41f}', '\u{43f}'), ('\u{420}', '\u{440}'), ('\u{421}', '\u{441}'), + ('\u{422}', '\u{442}'), ('\u{423}', '\u{443}'), ('\u{424}', '\u{444}'), + ('\u{425}', '\u{445}'), ('\u{426}', '\u{446}'), ('\u{427}', '\u{447}'), + ('\u{428}', '\u{448}'), ('\u{429}', '\u{449}'), ('\u{42a}', '\u{44a}'), + ('\u{42b}', '\u{44b}'), ('\u{42c}', '\u{44c}'), ('\u{42d}', '\u{44d}'), + ('\u{42e}', '\u{44e}'), ('\u{42f}', '\u{44f}'), ('\u{460}', '\u{461}'), + ('\u{462}', '\u{463}'), ('\u{464}', '\u{465}'), ('\u{466}', '\u{467}'), + ('\u{468}', '\u{469}'), ('\u{46a}', '\u{46b}'), ('\u{46c}', '\u{46d}'), + ('\u{46e}', '\u{46f}'), ('\u{470}', '\u{471}'), ('\u{472}', '\u{473}'), + ('\u{474}', '\u{475}'), ('\u{476}', '\u{477}'), ('\u{478}', '\u{479}'), + ('\u{47a}', '\u{47b}'), ('\u{47c}', '\u{47d}'), ('\u{47e}', '\u{47f}'), + ('\u{480}', '\u{481}'), ('\u{48a}', '\u{48b}'), ('\u{48c}', '\u{48d}'), + ('\u{48e}', '\u{48f}'), ('\u{490}', '\u{491}'), ('\u{492}', '\u{493}'), + ('\u{494}', '\u{495}'), ('\u{496}', '\u{497}'), ('\u{498}', '\u{499}'), + ('\u{49a}', '\u{49b}'), ('\u{49c}', '\u{49d}'), ('\u{49e}', '\u{49f}'), + ('\u{4a0}', '\u{4a1}'), ('\u{4a2}', '\u{4a3}'), ('\u{4a4}', '\u{4a5}'), + ('\u{4a6}', '\u{4a7}'), ('\u{4a8}', '\u{4a9}'), ('\u{4aa}', '\u{4ab}'), + ('\u{4ac}', '\u{4ad}'), ('\u{4ae}', '\u{4af}'), ('\u{4b0}', '\u{4b1}'), + ('\u{4b2}', '\u{4b3}'), ('\u{4b4}', '\u{4b5}'), ('\u{4b6}', '\u{4b7}'), + ('\u{4b8}', '\u{4b9}'), ('\u{4ba}', '\u{4bb}'), ('\u{4bc}', '\u{4bd}'), + ('\u{4be}', '\u{4bf}'), ('\u{4c0}', '\u{4cf}'), ('\u{4c1}', '\u{4c2}'), + ('\u{4c3}', '\u{4c4}'), ('\u{4c5}', '\u{4c6}'), ('\u{4c7}', '\u{4c8}'), + ('\u{4c9}', '\u{4ca}'), ('\u{4cb}', '\u{4cc}'), ('\u{4cd}', '\u{4ce}'), + ('\u{4d0}', '\u{4d1}'), ('\u{4d2}', '\u{4d3}'), ('\u{4d4}', '\u{4d5}'), + ('\u{4d6}', '\u{4d7}'), ('\u{4d8}', '\u{4d9}'), ('\u{4da}', '\u{4db}'), + ('\u{4dc}', '\u{4dd}'), ('\u{4de}', '\u{4df}'), ('\u{4e0}', '\u{4e1}'), + ('\u{4e2}', '\u{4e3}'), ('\u{4e4}', '\u{4e5}'), ('\u{4e6}', '\u{4e7}'), + ('\u{4e8}', '\u{4e9}'), ('\u{4ea}', '\u{4eb}'), ('\u{4ec}', '\u{4ed}'), + ('\u{4ee}', '\u{4ef}'), ('\u{4f0}', '\u{4f1}'), ('\u{4f2}', '\u{4f3}'), + ('\u{4f4}', '\u{4f5}'), ('\u{4f6}', '\u{4f7}'), ('\u{4f8}', '\u{4f9}'), + ('\u{4fa}', '\u{4fb}'), ('\u{4fc}', '\u{4fd}'), ('\u{4fe}', '\u{4ff}'), + ('\u{500}', '\u{501}'), ('\u{502}', '\u{503}'), ('\u{504}', '\u{505}'), + ('\u{506}', '\u{507}'), ('\u{508}', '\u{509}'), ('\u{50a}', '\u{50b}'), + ('\u{50c}', '\u{50d}'), ('\u{50e}', '\u{50f}'), ('\u{510}', '\u{511}'), + ('\u{512}', '\u{513}'), ('\u{514}', '\u{515}'), ('\u{516}', '\u{517}'), + ('\u{518}', '\u{519}'), ('\u{51a}', '\u{51b}'), ('\u{51c}', '\u{51d}'), + ('\u{51e}', '\u{51f}'), ('\u{520}', '\u{521}'), ('\u{522}', '\u{523}'), + ('\u{524}', '\u{525}'), ('\u{526}', '\u{527}'), ('\u{528}', '\u{529}'), + ('\u{52a}', '\u{52b}'), ('\u{52c}', '\u{52d}'), ('\u{52e}', '\u{52f}'), + ('\u{531}', '\u{561}'), ('\u{532}', '\u{562}'), ('\u{533}', '\u{563}'), + ('\u{534}', '\u{564}'), ('\u{535}', '\u{565}'), ('\u{536}', '\u{566}'), + ('\u{537}', '\u{567}'), ('\u{538}', '\u{568}'), ('\u{539}', '\u{569}'), + ('\u{53a}', '\u{56a}'), ('\u{53b}', '\u{56b}'), ('\u{53c}', '\u{56c}'), + ('\u{53d}', '\u{56d}'), ('\u{53e}', '\u{56e}'), ('\u{53f}', '\u{56f}'), + ('\u{540}', '\u{570}'), ('\u{541}', '\u{571}'), ('\u{542}', '\u{572}'), + ('\u{543}', '\u{573}'), ('\u{544}', '\u{574}'), ('\u{545}', '\u{575}'), + ('\u{546}', '\u{576}'), ('\u{547}', '\u{577}'), ('\u{548}', '\u{578}'), + ('\u{549}', '\u{579}'), ('\u{54a}', '\u{57a}'), ('\u{54b}', '\u{57b}'), + ('\u{54c}', '\u{57c}'), ('\u{54d}', '\u{57d}'), ('\u{54e}', '\u{57e}'), + ('\u{54f}', '\u{57f}'), ('\u{550}', '\u{580}'), ('\u{551}', '\u{581}'), + ('\u{552}', '\u{582}'), ('\u{553}', '\u{583}'), ('\u{554}', '\u{584}'), + ('\u{555}', '\u{585}'), ('\u{556}', '\u{586}'), ('\u{10a0}', '\u{2d00}'), + ('\u{10a1}', '\u{2d01}'), ('\u{10a2}', '\u{2d02}'), ('\u{10a3}', '\u{2d03}'), + ('\u{10a4}', '\u{2d04}'), ('\u{10a5}', '\u{2d05}'), ('\u{10a6}', '\u{2d06}'), + ('\u{10a7}', '\u{2d07}'), ('\u{10a8}', '\u{2d08}'), ('\u{10a9}', '\u{2d09}'), + ('\u{10aa}', '\u{2d0a}'), ('\u{10ab}', '\u{2d0b}'), ('\u{10ac}', '\u{2d0c}'), + ('\u{10ad}', '\u{2d0d}'), ('\u{10ae}', '\u{2d0e}'), ('\u{10af}', '\u{2d0f}'), + ('\u{10b0}', '\u{2d10}'), ('\u{10b1}', '\u{2d11}'), ('\u{10b2}', '\u{2d12}'), + ('\u{10b3}', '\u{2d13}'), ('\u{10b4}', '\u{2d14}'), ('\u{10b5}', '\u{2d15}'), + ('\u{10b6}', '\u{2d16}'), ('\u{10b7}', '\u{2d17}'), ('\u{10b8}', '\u{2d18}'), + ('\u{10b9}', '\u{2d19}'), ('\u{10ba}', '\u{2d1a}'), ('\u{10bb}', '\u{2d1b}'), + ('\u{10bc}', '\u{2d1c}'), ('\u{10bd}', '\u{2d1d}'), ('\u{10be}', '\u{2d1e}'), + ('\u{10bf}', '\u{2d1f}'), ('\u{10c0}', '\u{2d20}'), ('\u{10c1}', '\u{2d21}'), + ('\u{10c2}', '\u{2d22}'), ('\u{10c3}', '\u{2d23}'), ('\u{10c4}', '\u{2d24}'), + ('\u{10c5}', '\u{2d25}'), ('\u{10c7}', '\u{2d27}'), ('\u{10cd}', '\u{2d2d}'), + ('\u{13a0}', '\u{ab70}'), ('\u{13a1}', '\u{ab71}'), ('\u{13a2}', '\u{ab72}'), + ('\u{13a3}', '\u{ab73}'), ('\u{13a4}', '\u{ab74}'), ('\u{13a5}', '\u{ab75}'), + ('\u{13a6}', '\u{ab76}'), ('\u{13a7}', '\u{ab77}'), ('\u{13a8}', '\u{ab78}'), + ('\u{13a9}', '\u{ab79}'), ('\u{13aa}', '\u{ab7a}'), ('\u{13ab}', '\u{ab7b}'), + ('\u{13ac}', '\u{ab7c}'), ('\u{13ad}', '\u{ab7d}'), ('\u{13ae}', '\u{ab7e}'), + ('\u{13af}', '\u{ab7f}'), ('\u{13b0}', '\u{ab80}'), ('\u{13b1}', '\u{ab81}'), + ('\u{13b2}', '\u{ab82}'), ('\u{13b3}', '\u{ab83}'), ('\u{13b4}', '\u{ab84}'), + ('\u{13b5}', '\u{ab85}'), ('\u{13b6}', '\u{ab86}'), ('\u{13b7}', '\u{ab87}'), + ('\u{13b8}', '\u{ab88}'), ('\u{13b9}', '\u{ab89}'), ('\u{13ba}', '\u{ab8a}'), + ('\u{13bb}', '\u{ab8b}'), ('\u{13bc}', '\u{ab8c}'), ('\u{13bd}', '\u{ab8d}'), + ('\u{13be}', '\u{ab8e}'), ('\u{13bf}', '\u{ab8f}'), ('\u{13c0}', '\u{ab90}'), + ('\u{13c1}', '\u{ab91}'), ('\u{13c2}', '\u{ab92}'), ('\u{13c3}', '\u{ab93}'), + ('\u{13c4}', '\u{ab94}'), ('\u{13c5}', '\u{ab95}'), ('\u{13c6}', '\u{ab96}'), + ('\u{13c7}', '\u{ab97}'), ('\u{13c8}', '\u{ab98}'), ('\u{13c9}', '\u{ab99}'), + ('\u{13ca}', '\u{ab9a}'), ('\u{13cb}', '\u{ab9b}'), ('\u{13cc}', '\u{ab9c}'), + ('\u{13cd}', '\u{ab9d}'), ('\u{13ce}', '\u{ab9e}'), ('\u{13cf}', '\u{ab9f}'), + ('\u{13d0}', '\u{aba0}'), ('\u{13d1}', '\u{aba1}'), ('\u{13d2}', '\u{aba2}'), + ('\u{13d3}', '\u{aba3}'), ('\u{13d4}', '\u{aba4}'), ('\u{13d5}', '\u{aba5}'), + ('\u{13d6}', '\u{aba6}'), ('\u{13d7}', '\u{aba7}'), ('\u{13d8}', '\u{aba8}'), + ('\u{13d9}', '\u{aba9}'), ('\u{13da}', '\u{abaa}'), ('\u{13db}', '\u{abab}'), + ('\u{13dc}', '\u{abac}'), ('\u{13dd}', '\u{abad}'), ('\u{13de}', '\u{abae}'), + ('\u{13df}', '\u{abaf}'), ('\u{13e0}', '\u{abb0}'), ('\u{13e1}', '\u{abb1}'), + ('\u{13e2}', '\u{abb2}'), ('\u{13e3}', '\u{abb3}'), ('\u{13e4}', '\u{abb4}'), + ('\u{13e5}', '\u{abb5}'), ('\u{13e6}', '\u{abb6}'), ('\u{13e7}', '\u{abb7}'), + ('\u{13e8}', '\u{abb8}'), ('\u{13e9}', '\u{abb9}'), ('\u{13ea}', '\u{abba}'), + ('\u{13eb}', '\u{abbb}'), ('\u{13ec}', '\u{abbc}'), ('\u{13ed}', '\u{abbd}'), + ('\u{13ee}', '\u{abbe}'), ('\u{13ef}', '\u{abbf}'), ('\u{13f0}', '\u{13f8}'), + ('\u{13f1}', '\u{13f9}'), ('\u{13f2}', '\u{13fa}'), ('\u{13f3}', '\u{13fb}'), + ('\u{13f4}', '\u{13fc}'), ('\u{13f5}', '\u{13fd}'), ('\u{1c90}', '\u{10d0}'), + ('\u{1c91}', '\u{10d1}'), ('\u{1c92}', '\u{10d2}'), ('\u{1c93}', '\u{10d3}'), + ('\u{1c94}', '\u{10d4}'), ('\u{1c95}', '\u{10d5}'), ('\u{1c96}', '\u{10d6}'), + ('\u{1c97}', '\u{10d7}'), ('\u{1c98}', '\u{10d8}'), ('\u{1c99}', '\u{10d9}'), + ('\u{1c9a}', '\u{10da}'), ('\u{1c9b}', '\u{10db}'), ('\u{1c9c}', '\u{10dc}'), + ('\u{1c9d}', '\u{10dd}'), ('\u{1c9e}', '\u{10de}'), ('\u{1c9f}', '\u{10df}'), + ('\u{1ca0}', '\u{10e0}'), ('\u{1ca1}', '\u{10e1}'), ('\u{1ca2}', '\u{10e2}'), + ('\u{1ca3}', '\u{10e3}'), ('\u{1ca4}', '\u{10e4}'), ('\u{1ca5}', '\u{10e5}'), + ('\u{1ca6}', '\u{10e6}'), ('\u{1ca7}', '\u{10e7}'), ('\u{1ca8}', '\u{10e8}'), + ('\u{1ca9}', '\u{10e9}'), ('\u{1caa}', '\u{10ea}'), ('\u{1cab}', '\u{10eb}'), + ('\u{1cac}', '\u{10ec}'), ('\u{1cad}', '\u{10ed}'), ('\u{1cae}', '\u{10ee}'), + ('\u{1caf}', '\u{10ef}'), ('\u{1cb0}', '\u{10f0}'), ('\u{1cb1}', '\u{10f1}'), + ('\u{1cb2}', '\u{10f2}'), ('\u{1cb3}', '\u{10f3}'), ('\u{1cb4}', '\u{10f4}'), + ('\u{1cb5}', '\u{10f5}'), ('\u{1cb6}', '\u{10f6}'), ('\u{1cb7}', '\u{10f7}'), + ('\u{1cb8}', '\u{10f8}'), ('\u{1cb9}', '\u{10f9}'), ('\u{1cba}', '\u{10fa}'), + ('\u{1cbd}', '\u{10fd}'), ('\u{1cbe}', '\u{10fe}'), ('\u{1cbf}', '\u{10ff}'), + ('\u{1e00}', '\u{1e01}'), ('\u{1e02}', '\u{1e03}'), ('\u{1e04}', '\u{1e05}'), + ('\u{1e06}', '\u{1e07}'), ('\u{1e08}', '\u{1e09}'), ('\u{1e0a}', '\u{1e0b}'), + ('\u{1e0c}', '\u{1e0d}'), ('\u{1e0e}', '\u{1e0f}'), ('\u{1e10}', '\u{1e11}'), + ('\u{1e12}', '\u{1e13}'), ('\u{1e14}', '\u{1e15}'), ('\u{1e16}', '\u{1e17}'), + ('\u{1e18}', '\u{1e19}'), ('\u{1e1a}', '\u{1e1b}'), ('\u{1e1c}', '\u{1e1d}'), + ('\u{1e1e}', '\u{1e1f}'), ('\u{1e20}', '\u{1e21}'), ('\u{1e22}', '\u{1e23}'), + ('\u{1e24}', '\u{1e25}'), ('\u{1e26}', '\u{1e27}'), ('\u{1e28}', '\u{1e29}'), + ('\u{1e2a}', '\u{1e2b}'), ('\u{1e2c}', '\u{1e2d}'), ('\u{1e2e}', '\u{1e2f}'), + ('\u{1e30}', '\u{1e31}'), ('\u{1e32}', '\u{1e33}'), ('\u{1e34}', '\u{1e35}'), + ('\u{1e36}', '\u{1e37}'), ('\u{1e38}', '\u{1e39}'), ('\u{1e3a}', '\u{1e3b}'), + ('\u{1e3c}', '\u{1e3d}'), ('\u{1e3e}', '\u{1e3f}'), ('\u{1e40}', '\u{1e41}'), + ('\u{1e42}', '\u{1e43}'), ('\u{1e44}', '\u{1e45}'), ('\u{1e46}', '\u{1e47}'), + ('\u{1e48}', '\u{1e49}'), ('\u{1e4a}', '\u{1e4b}'), ('\u{1e4c}', '\u{1e4d}'), + ('\u{1e4e}', '\u{1e4f}'), ('\u{1e50}', '\u{1e51}'), ('\u{1e52}', '\u{1e53}'), + ('\u{1e54}', '\u{1e55}'), ('\u{1e56}', '\u{1e57}'), ('\u{1e58}', '\u{1e59}'), + ('\u{1e5a}', '\u{1e5b}'), ('\u{1e5c}', '\u{1e5d}'), ('\u{1e5e}', '\u{1e5f}'), + ('\u{1e60}', '\u{1e61}'), ('\u{1e62}', '\u{1e63}'), ('\u{1e64}', '\u{1e65}'), + ('\u{1e66}', '\u{1e67}'), ('\u{1e68}', '\u{1e69}'), ('\u{1e6a}', '\u{1e6b}'), + ('\u{1e6c}', '\u{1e6d}'), ('\u{1e6e}', '\u{1e6f}'), ('\u{1e70}', '\u{1e71}'), + ('\u{1e72}', '\u{1e73}'), ('\u{1e74}', '\u{1e75}'), ('\u{1e76}', '\u{1e77}'), + ('\u{1e78}', '\u{1e79}'), ('\u{1e7a}', '\u{1e7b}'), ('\u{1e7c}', '\u{1e7d}'), + ('\u{1e7e}', '\u{1e7f}'), ('\u{1e80}', '\u{1e81}'), ('\u{1e82}', '\u{1e83}'), + ('\u{1e84}', '\u{1e85}'), ('\u{1e86}', '\u{1e87}'), ('\u{1e88}', '\u{1e89}'), + ('\u{1e8a}', '\u{1e8b}'), ('\u{1e8c}', '\u{1e8d}'), ('\u{1e8e}', '\u{1e8f}'), + ('\u{1e90}', '\u{1e91}'), ('\u{1e92}', '\u{1e93}'), ('\u{1e94}', '\u{1e95}'), + ('\u{1e9e}', '\u{df}'), ('\u{1ea0}', '\u{1ea1}'), ('\u{1ea2}', '\u{1ea3}'), + ('\u{1ea4}', '\u{1ea5}'), ('\u{1ea6}', '\u{1ea7}'), ('\u{1ea8}', '\u{1ea9}'), + ('\u{1eaa}', '\u{1eab}'), ('\u{1eac}', '\u{1ead}'), ('\u{1eae}', '\u{1eaf}'), + ('\u{1eb0}', '\u{1eb1}'), ('\u{1eb2}', '\u{1eb3}'), ('\u{1eb4}', '\u{1eb5}'), + ('\u{1eb6}', '\u{1eb7}'), ('\u{1eb8}', '\u{1eb9}'), ('\u{1eba}', '\u{1ebb}'), + ('\u{1ebc}', '\u{1ebd}'), ('\u{1ebe}', '\u{1ebf}'), ('\u{1ec0}', '\u{1ec1}'), + ('\u{1ec2}', '\u{1ec3}'), ('\u{1ec4}', '\u{1ec5}'), ('\u{1ec6}', '\u{1ec7}'), + ('\u{1ec8}', '\u{1ec9}'), ('\u{1eca}', '\u{1ecb}'), ('\u{1ecc}', '\u{1ecd}'), + ('\u{1ece}', '\u{1ecf}'), ('\u{1ed0}', '\u{1ed1}'), ('\u{1ed2}', '\u{1ed3}'), + ('\u{1ed4}', '\u{1ed5}'), ('\u{1ed6}', '\u{1ed7}'), ('\u{1ed8}', '\u{1ed9}'), + ('\u{1eda}', '\u{1edb}'), ('\u{1edc}', '\u{1edd}'), ('\u{1ede}', '\u{1edf}'), + ('\u{1ee0}', '\u{1ee1}'), ('\u{1ee2}', '\u{1ee3}'), ('\u{1ee4}', '\u{1ee5}'), + ('\u{1ee6}', '\u{1ee7}'), ('\u{1ee8}', '\u{1ee9}'), ('\u{1eea}', '\u{1eeb}'), + ('\u{1eec}', '\u{1eed}'), ('\u{1eee}', '\u{1eef}'), ('\u{1ef0}', '\u{1ef1}'), + ('\u{1ef2}', '\u{1ef3}'), ('\u{1ef4}', '\u{1ef5}'), ('\u{1ef6}', '\u{1ef7}'), + ('\u{1ef8}', '\u{1ef9}'), ('\u{1efa}', '\u{1efb}'), ('\u{1efc}', '\u{1efd}'), + ('\u{1efe}', '\u{1eff}'), ('\u{1f08}', '\u{1f00}'), ('\u{1f09}', '\u{1f01}'), + ('\u{1f0a}', '\u{1f02}'), ('\u{1f0b}', '\u{1f03}'), ('\u{1f0c}', '\u{1f04}'), + ('\u{1f0d}', '\u{1f05}'), ('\u{1f0e}', '\u{1f06}'), ('\u{1f0f}', '\u{1f07}'), + ('\u{1f18}', '\u{1f10}'), ('\u{1f19}', '\u{1f11}'), ('\u{1f1a}', '\u{1f12}'), + ('\u{1f1b}', '\u{1f13}'), ('\u{1f1c}', '\u{1f14}'), ('\u{1f1d}', '\u{1f15}'), + ('\u{1f28}', '\u{1f20}'), ('\u{1f29}', '\u{1f21}'), ('\u{1f2a}', '\u{1f22}'), + ('\u{1f2b}', '\u{1f23}'), ('\u{1f2c}', '\u{1f24}'), ('\u{1f2d}', '\u{1f25}'), + ('\u{1f2e}', '\u{1f26}'), ('\u{1f2f}', '\u{1f27}'), ('\u{1f38}', '\u{1f30}'), + ('\u{1f39}', '\u{1f31}'), ('\u{1f3a}', '\u{1f32}'), ('\u{1f3b}', '\u{1f33}'), + ('\u{1f3c}', '\u{1f34}'), ('\u{1f3d}', '\u{1f35}'), ('\u{1f3e}', '\u{1f36}'), + ('\u{1f3f}', '\u{1f37}'), ('\u{1f48}', '\u{1f40}'), ('\u{1f49}', '\u{1f41}'), + ('\u{1f4a}', '\u{1f42}'), ('\u{1f4b}', '\u{1f43}'), ('\u{1f4c}', '\u{1f44}'), + ('\u{1f4d}', '\u{1f45}'), ('\u{1f59}', '\u{1f51}'), ('\u{1f5b}', '\u{1f53}'), + ('\u{1f5d}', '\u{1f55}'), ('\u{1f5f}', '\u{1f57}'), ('\u{1f68}', '\u{1f60}'), + ('\u{1f69}', '\u{1f61}'), ('\u{1f6a}', '\u{1f62}'), ('\u{1f6b}', '\u{1f63}'), + ('\u{1f6c}', '\u{1f64}'), ('\u{1f6d}', '\u{1f65}'), ('\u{1f6e}', '\u{1f66}'), + ('\u{1f6f}', '\u{1f67}'), ('\u{1f88}', '\u{1f80}'), ('\u{1f89}', '\u{1f81}'), + ('\u{1f8a}', '\u{1f82}'), ('\u{1f8b}', '\u{1f83}'), ('\u{1f8c}', '\u{1f84}'), + ('\u{1f8d}', '\u{1f85}'), ('\u{1f8e}', '\u{1f86}'), ('\u{1f8f}', '\u{1f87}'), + ('\u{1f98}', '\u{1f90}'), ('\u{1f99}', '\u{1f91}'), ('\u{1f9a}', '\u{1f92}'), + ('\u{1f9b}', '\u{1f93}'), ('\u{1f9c}', '\u{1f94}'), ('\u{1f9d}', '\u{1f95}'), + ('\u{1f9e}', '\u{1f96}'), ('\u{1f9f}', '\u{1f97}'), ('\u{1fa8}', '\u{1fa0}'), + ('\u{1fa9}', '\u{1fa1}'), ('\u{1faa}', '\u{1fa2}'), ('\u{1fab}', '\u{1fa3}'), + ('\u{1fac}', '\u{1fa4}'), ('\u{1fad}', '\u{1fa5}'), ('\u{1fae}', '\u{1fa6}'), + ('\u{1faf}', '\u{1fa7}'), ('\u{1fb8}', '\u{1fb0}'), ('\u{1fb9}', '\u{1fb1}'), + ('\u{1fba}', '\u{1f70}'), ('\u{1fbb}', '\u{1f71}'), ('\u{1fbc}', '\u{1fb3}'), + ('\u{1fc8}', '\u{1f72}'), ('\u{1fc9}', '\u{1f73}'), ('\u{1fca}', '\u{1f74}'), + ('\u{1fcb}', '\u{1f75}'), ('\u{1fcc}', '\u{1fc3}'), ('\u{1fd8}', '\u{1fd0}'), + ('\u{1fd9}', '\u{1fd1}'), ('\u{1fda}', '\u{1f76}'), ('\u{1fdb}', '\u{1f77}'), + ('\u{1fe8}', '\u{1fe0}'), ('\u{1fe9}', '\u{1fe1}'), ('\u{1fea}', '\u{1f7a}'), + ('\u{1feb}', '\u{1f7b}'), ('\u{1fec}', '\u{1fe5}'), ('\u{1ff8}', '\u{1f78}'), + ('\u{1ff9}', '\u{1f79}'), ('\u{1ffa}', '\u{1f7c}'), ('\u{1ffb}', '\u{1f7d}'), + ('\u{1ffc}', '\u{1ff3}'), ('\u{2126}', '\u{3c9}'), ('\u{212a}', 'k'), + ('\u{212b}', '\u{e5}'), ('\u{2132}', '\u{214e}'), ('\u{2160}', '\u{2170}'), + ('\u{2161}', '\u{2171}'), ('\u{2162}', '\u{2172}'), ('\u{2163}', '\u{2173}'), + ('\u{2164}', '\u{2174}'), ('\u{2165}', '\u{2175}'), ('\u{2166}', '\u{2176}'), + ('\u{2167}', '\u{2177}'), ('\u{2168}', '\u{2178}'), ('\u{2169}', '\u{2179}'), + ('\u{216a}', '\u{217a}'), ('\u{216b}', '\u{217b}'), ('\u{216c}', '\u{217c}'), + ('\u{216d}', '\u{217d}'), ('\u{216e}', '\u{217e}'), ('\u{216f}', '\u{217f}'), + ('\u{2183}', '\u{2184}'), ('\u{24b6}', '\u{24d0}'), ('\u{24b7}', '\u{24d1}'), + ('\u{24b8}', '\u{24d2}'), ('\u{24b9}', '\u{24d3}'), ('\u{24ba}', '\u{24d4}'), + ('\u{24bb}', '\u{24d5}'), ('\u{24bc}', '\u{24d6}'), ('\u{24bd}', '\u{24d7}'), + ('\u{24be}', '\u{24d8}'), ('\u{24bf}', '\u{24d9}'), ('\u{24c0}', '\u{24da}'), + ('\u{24c1}', '\u{24db}'), ('\u{24c2}', '\u{24dc}'), ('\u{24c3}', '\u{24dd}'), + ('\u{24c4}', '\u{24de}'), ('\u{24c5}', '\u{24df}'), ('\u{24c6}', '\u{24e0}'), + ('\u{24c7}', '\u{24e1}'), ('\u{24c8}', '\u{24e2}'), ('\u{24c9}', '\u{24e3}'), + ('\u{24ca}', '\u{24e4}'), ('\u{24cb}', '\u{24e5}'), ('\u{24cc}', '\u{24e6}'), + ('\u{24cd}', '\u{24e7}'), ('\u{24ce}', '\u{24e8}'), ('\u{24cf}', '\u{24e9}'), + ('\u{2c00}', '\u{2c30}'), ('\u{2c01}', '\u{2c31}'), ('\u{2c02}', '\u{2c32}'), + ('\u{2c03}', '\u{2c33}'), ('\u{2c04}', '\u{2c34}'), ('\u{2c05}', '\u{2c35}'), + ('\u{2c06}', '\u{2c36}'), ('\u{2c07}', '\u{2c37}'), ('\u{2c08}', '\u{2c38}'), + ('\u{2c09}', '\u{2c39}'), ('\u{2c0a}', '\u{2c3a}'), ('\u{2c0b}', '\u{2c3b}'), + ('\u{2c0c}', '\u{2c3c}'), ('\u{2c0d}', '\u{2c3d}'), ('\u{2c0e}', '\u{2c3e}'), + ('\u{2c0f}', '\u{2c3f}'), ('\u{2c10}', '\u{2c40}'), ('\u{2c11}', '\u{2c41}'), + ('\u{2c12}', '\u{2c42}'), ('\u{2c13}', '\u{2c43}'), ('\u{2c14}', '\u{2c44}'), + ('\u{2c15}', '\u{2c45}'), ('\u{2c16}', '\u{2c46}'), ('\u{2c17}', '\u{2c47}'), + ('\u{2c18}', '\u{2c48}'), ('\u{2c19}', '\u{2c49}'), ('\u{2c1a}', '\u{2c4a}'), + ('\u{2c1b}', '\u{2c4b}'), ('\u{2c1c}', '\u{2c4c}'), ('\u{2c1d}', '\u{2c4d}'), + ('\u{2c1e}', '\u{2c4e}'), ('\u{2c1f}', '\u{2c4f}'), ('\u{2c20}', '\u{2c50}'), + ('\u{2c21}', '\u{2c51}'), ('\u{2c22}', '\u{2c52}'), ('\u{2c23}', '\u{2c53}'), + ('\u{2c24}', '\u{2c54}'), ('\u{2c25}', '\u{2c55}'), ('\u{2c26}', '\u{2c56}'), + ('\u{2c27}', '\u{2c57}'), ('\u{2c28}', '\u{2c58}'), ('\u{2c29}', '\u{2c59}'), + ('\u{2c2a}', '\u{2c5a}'), ('\u{2c2b}', '\u{2c5b}'), ('\u{2c2c}', '\u{2c5c}'), + ('\u{2c2d}', '\u{2c5d}'), ('\u{2c2e}', '\u{2c5e}'), ('\u{2c2f}', '\u{2c5f}'), + ('\u{2c60}', '\u{2c61}'), ('\u{2c62}', '\u{26b}'), ('\u{2c63}', '\u{1d7d}'), + ('\u{2c64}', '\u{27d}'), ('\u{2c67}', '\u{2c68}'), ('\u{2c69}', '\u{2c6a}'), + ('\u{2c6b}', '\u{2c6c}'), ('\u{2c6d}', '\u{251}'), ('\u{2c6e}', '\u{271}'), + ('\u{2c6f}', '\u{250}'), ('\u{2c70}', '\u{252}'), ('\u{2c72}', '\u{2c73}'), + ('\u{2c75}', '\u{2c76}'), ('\u{2c7e}', '\u{23f}'), ('\u{2c7f}', '\u{240}'), + ('\u{2c80}', '\u{2c81}'), ('\u{2c82}', '\u{2c83}'), ('\u{2c84}', '\u{2c85}'), + ('\u{2c86}', '\u{2c87}'), ('\u{2c88}', '\u{2c89}'), ('\u{2c8a}', '\u{2c8b}'), + ('\u{2c8c}', '\u{2c8d}'), ('\u{2c8e}', '\u{2c8f}'), ('\u{2c90}', '\u{2c91}'), + ('\u{2c92}', '\u{2c93}'), ('\u{2c94}', '\u{2c95}'), ('\u{2c96}', '\u{2c97}'), + ('\u{2c98}', '\u{2c99}'), ('\u{2c9a}', '\u{2c9b}'), ('\u{2c9c}', '\u{2c9d}'), + ('\u{2c9e}', '\u{2c9f}'), ('\u{2ca0}', '\u{2ca1}'), ('\u{2ca2}', '\u{2ca3}'), + ('\u{2ca4}', '\u{2ca5}'), ('\u{2ca6}', '\u{2ca7}'), ('\u{2ca8}', '\u{2ca9}'), + ('\u{2caa}', '\u{2cab}'), ('\u{2cac}', '\u{2cad}'), ('\u{2cae}', '\u{2caf}'), + ('\u{2cb0}', '\u{2cb1}'), ('\u{2cb2}', '\u{2cb3}'), ('\u{2cb4}', '\u{2cb5}'), + ('\u{2cb6}', '\u{2cb7}'), ('\u{2cb8}', '\u{2cb9}'), ('\u{2cba}', '\u{2cbb}'), + ('\u{2cbc}', '\u{2cbd}'), ('\u{2cbe}', '\u{2cbf}'), ('\u{2cc0}', '\u{2cc1}'), + ('\u{2cc2}', '\u{2cc3}'), ('\u{2cc4}', '\u{2cc5}'), ('\u{2cc6}', '\u{2cc7}'), + ('\u{2cc8}', '\u{2cc9}'), ('\u{2cca}', '\u{2ccb}'), ('\u{2ccc}', '\u{2ccd}'), + ('\u{2cce}', '\u{2ccf}'), ('\u{2cd0}', '\u{2cd1}'), ('\u{2cd2}', '\u{2cd3}'), + ('\u{2cd4}', '\u{2cd5}'), ('\u{2cd6}', '\u{2cd7}'), ('\u{2cd8}', '\u{2cd9}'), + ('\u{2cda}', '\u{2cdb}'), ('\u{2cdc}', '\u{2cdd}'), ('\u{2cde}', '\u{2cdf}'), + ('\u{2ce0}', '\u{2ce1}'), ('\u{2ce2}', '\u{2ce3}'), ('\u{2ceb}', '\u{2cec}'), + ('\u{2ced}', '\u{2cee}'), ('\u{2cf2}', '\u{2cf3}'), ('\u{a640}', '\u{a641}'), + ('\u{a642}', '\u{a643}'), ('\u{a644}', '\u{a645}'), ('\u{a646}', '\u{a647}'), + ('\u{a648}', '\u{a649}'), ('\u{a64a}', '\u{a64b}'), ('\u{a64c}', '\u{a64d}'), + ('\u{a64e}', '\u{a64f}'), ('\u{a650}', '\u{a651}'), ('\u{a652}', '\u{a653}'), + ('\u{a654}', '\u{a655}'), ('\u{a656}', '\u{a657}'), ('\u{a658}', '\u{a659}'), + ('\u{a65a}', '\u{a65b}'), ('\u{a65c}', '\u{a65d}'), ('\u{a65e}', '\u{a65f}'), + ('\u{a660}', '\u{a661}'), ('\u{a662}', '\u{a663}'), ('\u{a664}', '\u{a665}'), + ('\u{a666}', '\u{a667}'), ('\u{a668}', '\u{a669}'), ('\u{a66a}', '\u{a66b}'), + ('\u{a66c}', '\u{a66d}'), ('\u{a680}', '\u{a681}'), ('\u{a682}', '\u{a683}'), + ('\u{a684}', '\u{a685}'), ('\u{a686}', '\u{a687}'), ('\u{a688}', '\u{a689}'), + ('\u{a68a}', '\u{a68b}'), ('\u{a68c}', '\u{a68d}'), ('\u{a68e}', '\u{a68f}'), + ('\u{a690}', '\u{a691}'), ('\u{a692}', '\u{a693}'), ('\u{a694}', '\u{a695}'), + ('\u{a696}', '\u{a697}'), ('\u{a698}', '\u{a699}'), ('\u{a69a}', '\u{a69b}'), + ('\u{a722}', '\u{a723}'), ('\u{a724}', '\u{a725}'), ('\u{a726}', '\u{a727}'), + ('\u{a728}', '\u{a729}'), ('\u{a72a}', '\u{a72b}'), ('\u{a72c}', '\u{a72d}'), + ('\u{a72e}', '\u{a72f}'), ('\u{a732}', '\u{a733}'), ('\u{a734}', '\u{a735}'), + ('\u{a736}', '\u{a737}'), ('\u{a738}', '\u{a739}'), ('\u{a73a}', '\u{a73b}'), + ('\u{a73c}', '\u{a73d}'), ('\u{a73e}', '\u{a73f}'), ('\u{a740}', '\u{a741}'), + ('\u{a742}', '\u{a743}'), ('\u{a744}', '\u{a745}'), ('\u{a746}', '\u{a747}'), + ('\u{a748}', '\u{a749}'), ('\u{a74a}', '\u{a74b}'), ('\u{a74c}', '\u{a74d}'), + ('\u{a74e}', '\u{a74f}'), ('\u{a750}', '\u{a751}'), ('\u{a752}', '\u{a753}'), + ('\u{a754}', '\u{a755}'), ('\u{a756}', '\u{a757}'), ('\u{a758}', '\u{a759}'), + ('\u{a75a}', '\u{a75b}'), ('\u{a75c}', '\u{a75d}'), ('\u{a75e}', '\u{a75f}'), + ('\u{a760}', '\u{a761}'), ('\u{a762}', '\u{a763}'), ('\u{a764}', '\u{a765}'), + ('\u{a766}', '\u{a767}'), ('\u{a768}', '\u{a769}'), ('\u{a76a}', '\u{a76b}'), + ('\u{a76c}', '\u{a76d}'), ('\u{a76e}', '\u{a76f}'), ('\u{a779}', '\u{a77a}'), + ('\u{a77b}', '\u{a77c}'), ('\u{a77d}', '\u{1d79}'), ('\u{a77e}', '\u{a77f}'), + ('\u{a780}', '\u{a781}'), ('\u{a782}', '\u{a783}'), ('\u{a784}', '\u{a785}'), + ('\u{a786}', '\u{a787}'), ('\u{a78b}', '\u{a78c}'), ('\u{a78d}', '\u{265}'), + ('\u{a790}', '\u{a791}'), ('\u{a792}', '\u{a793}'), ('\u{a796}', '\u{a797}'), + ('\u{a798}', '\u{a799}'), ('\u{a79a}', '\u{a79b}'), ('\u{a79c}', '\u{a79d}'), + ('\u{a79e}', '\u{a79f}'), ('\u{a7a0}', '\u{a7a1}'), ('\u{a7a2}', '\u{a7a3}'), + ('\u{a7a4}', '\u{a7a5}'), ('\u{a7a6}', '\u{a7a7}'), ('\u{a7a8}', '\u{a7a9}'), + ('\u{a7aa}', '\u{266}'), ('\u{a7ab}', '\u{25c}'), ('\u{a7ac}', '\u{261}'), + ('\u{a7ad}', '\u{26c}'), ('\u{a7ae}', '\u{26a}'), ('\u{a7b0}', '\u{29e}'), + ('\u{a7b1}', '\u{287}'), ('\u{a7b2}', '\u{29d}'), ('\u{a7b3}', '\u{ab53}'), + ('\u{a7b4}', '\u{a7b5}'), ('\u{a7b6}', '\u{a7b7}'), ('\u{a7b8}', '\u{a7b9}'), + ('\u{a7ba}', '\u{a7bb}'), ('\u{a7bc}', '\u{a7bd}'), ('\u{a7be}', '\u{a7bf}'), + ('\u{a7c0}', '\u{a7c1}'), ('\u{a7c2}', '\u{a7c3}'), ('\u{a7c4}', '\u{a794}'), + ('\u{a7c5}', '\u{282}'), ('\u{a7c6}', '\u{1d8e}'), ('\u{a7c7}', '\u{a7c8}'), + ('\u{a7c9}', '\u{a7ca}'), ('\u{a7d0}', '\u{a7d1}'), ('\u{a7d6}', '\u{a7d7}'), + ('\u{a7d8}', '\u{a7d9}'), ('\u{a7f5}', '\u{a7f6}'), ('\u{ff21}', '\u{ff41}'), + ('\u{ff22}', '\u{ff42}'), ('\u{ff23}', '\u{ff43}'), ('\u{ff24}', '\u{ff44}'), + ('\u{ff25}', '\u{ff45}'), ('\u{ff26}', '\u{ff46}'), ('\u{ff27}', '\u{ff47}'), + ('\u{ff28}', '\u{ff48}'), ('\u{ff29}', '\u{ff49}'), ('\u{ff2a}', '\u{ff4a}'), + ('\u{ff2b}', '\u{ff4b}'), ('\u{ff2c}', '\u{ff4c}'), ('\u{ff2d}', '\u{ff4d}'), + ('\u{ff2e}', '\u{ff4e}'), ('\u{ff2f}', '\u{ff4f}'), ('\u{ff30}', '\u{ff50}'), + ('\u{ff31}', '\u{ff51}'), ('\u{ff32}', '\u{ff52}'), ('\u{ff33}', '\u{ff53}'), + ('\u{ff34}', '\u{ff54}'), ('\u{ff35}', '\u{ff55}'), ('\u{ff36}', '\u{ff56}'), + ('\u{ff37}', '\u{ff57}'), ('\u{ff38}', '\u{ff58}'), ('\u{ff39}', '\u{ff59}'), + ('\u{ff3a}', '\u{ff5a}'), ('\u{10400}', '\u{10428}'), ('\u{10401}', '\u{10429}'), + ('\u{10402}', '\u{1042a}'), ('\u{10403}', '\u{1042b}'), ('\u{10404}', '\u{1042c}'), + ('\u{10405}', '\u{1042d}'), ('\u{10406}', '\u{1042e}'), ('\u{10407}', '\u{1042f}'), + ('\u{10408}', '\u{10430}'), ('\u{10409}', '\u{10431}'), ('\u{1040a}', '\u{10432}'), + ('\u{1040b}', '\u{10433}'), ('\u{1040c}', '\u{10434}'), ('\u{1040d}', '\u{10435}'), + ('\u{1040e}', '\u{10436}'), ('\u{1040f}', '\u{10437}'), ('\u{10410}', '\u{10438}'), + ('\u{10411}', '\u{10439}'), ('\u{10412}', '\u{1043a}'), ('\u{10413}', '\u{1043b}'), + ('\u{10414}', '\u{1043c}'), ('\u{10415}', '\u{1043d}'), ('\u{10416}', '\u{1043e}'), + ('\u{10417}', '\u{1043f}'), ('\u{10418}', '\u{10440}'), ('\u{10419}', '\u{10441}'), + ('\u{1041a}', '\u{10442}'), ('\u{1041b}', '\u{10443}'), ('\u{1041c}', '\u{10444}'), + ('\u{1041d}', '\u{10445}'), ('\u{1041e}', '\u{10446}'), ('\u{1041f}', '\u{10447}'), + ('\u{10420}', '\u{10448}'), ('\u{10421}', '\u{10449}'), ('\u{10422}', '\u{1044a}'), + ('\u{10423}', '\u{1044b}'), ('\u{10424}', '\u{1044c}'), ('\u{10425}', '\u{1044d}'), + ('\u{10426}', '\u{1044e}'), ('\u{10427}', '\u{1044f}'), ('\u{104b0}', '\u{104d8}'), + ('\u{104b1}', '\u{104d9}'), ('\u{104b2}', '\u{104da}'), ('\u{104b3}', '\u{104db}'), + ('\u{104b4}', '\u{104dc}'), ('\u{104b5}', '\u{104dd}'), ('\u{104b6}', '\u{104de}'), + ('\u{104b7}', '\u{104df}'), ('\u{104b8}', '\u{104e0}'), ('\u{104b9}', '\u{104e1}'), + ('\u{104ba}', '\u{104e2}'), ('\u{104bb}', '\u{104e3}'), ('\u{104bc}', '\u{104e4}'), + ('\u{104bd}', '\u{104e5}'), ('\u{104be}', '\u{104e6}'), ('\u{104bf}', '\u{104e7}'), + ('\u{104c0}', '\u{104e8}'), ('\u{104c1}', '\u{104e9}'), ('\u{104c2}', '\u{104ea}'), + ('\u{104c3}', '\u{104eb}'), ('\u{104c4}', '\u{104ec}'), ('\u{104c5}', '\u{104ed}'), + ('\u{104c6}', '\u{104ee}'), ('\u{104c7}', '\u{104ef}'), ('\u{104c8}', '\u{104f0}'), + ('\u{104c9}', '\u{104f1}'), ('\u{104ca}', '\u{104f2}'), ('\u{104cb}', '\u{104f3}'), + ('\u{104cc}', '\u{104f4}'), ('\u{104cd}', '\u{104f5}'), ('\u{104ce}', '\u{104f6}'), + ('\u{104cf}', '\u{104f7}'), ('\u{104d0}', '\u{104f8}'), ('\u{104d1}', '\u{104f9}'), + ('\u{104d2}', '\u{104fa}'), ('\u{104d3}', '\u{104fb}'), ('\u{10570}', '\u{10597}'), + ('\u{10571}', '\u{10598}'), ('\u{10572}', '\u{10599}'), ('\u{10573}', '\u{1059a}'), + ('\u{10574}', '\u{1059b}'), ('\u{10575}', '\u{1059c}'), ('\u{10576}', '\u{1059d}'), + ('\u{10577}', '\u{1059e}'), ('\u{10578}', '\u{1059f}'), ('\u{10579}', '\u{105a0}'), + ('\u{1057a}', '\u{105a1}'), ('\u{1057c}', '\u{105a3}'), ('\u{1057d}', '\u{105a4}'), + ('\u{1057e}', '\u{105a5}'), ('\u{1057f}', '\u{105a6}'), ('\u{10580}', '\u{105a7}'), + ('\u{10581}', '\u{105a8}'), ('\u{10582}', '\u{105a9}'), ('\u{10583}', '\u{105aa}'), + ('\u{10584}', '\u{105ab}'), ('\u{10585}', '\u{105ac}'), ('\u{10586}', '\u{105ad}'), + ('\u{10587}', '\u{105ae}'), ('\u{10588}', '\u{105af}'), ('\u{10589}', '\u{105b0}'), + ('\u{1058a}', '\u{105b1}'), ('\u{1058c}', '\u{105b3}'), ('\u{1058d}', '\u{105b4}'), + ('\u{1058e}', '\u{105b5}'), ('\u{1058f}', '\u{105b6}'), ('\u{10590}', '\u{105b7}'), + ('\u{10591}', '\u{105b8}'), ('\u{10592}', '\u{105b9}'), ('\u{10594}', '\u{105bb}'), + ('\u{10595}', '\u{105bc}'), ('\u{10c80}', '\u{10cc0}'), ('\u{10c81}', '\u{10cc1}'), + ('\u{10c82}', '\u{10cc2}'), ('\u{10c83}', '\u{10cc3}'), ('\u{10c84}', '\u{10cc4}'), + ('\u{10c85}', '\u{10cc5}'), ('\u{10c86}', '\u{10cc6}'), ('\u{10c87}', '\u{10cc7}'), + ('\u{10c88}', '\u{10cc8}'), ('\u{10c89}', '\u{10cc9}'), ('\u{10c8a}', '\u{10cca}'), + ('\u{10c8b}', '\u{10ccb}'), ('\u{10c8c}', '\u{10ccc}'), ('\u{10c8d}', '\u{10ccd}'), + ('\u{10c8e}', '\u{10cce}'), ('\u{10c8f}', '\u{10ccf}'), ('\u{10c90}', '\u{10cd0}'), + ('\u{10c91}', '\u{10cd1}'), ('\u{10c92}', '\u{10cd2}'), ('\u{10c93}', '\u{10cd3}'), + ('\u{10c94}', '\u{10cd4}'), ('\u{10c95}', '\u{10cd5}'), ('\u{10c96}', '\u{10cd6}'), + ('\u{10c97}', '\u{10cd7}'), ('\u{10c98}', '\u{10cd8}'), ('\u{10c99}', '\u{10cd9}'), + ('\u{10c9a}', '\u{10cda}'), ('\u{10c9b}', '\u{10cdb}'), ('\u{10c9c}', '\u{10cdc}'), + ('\u{10c9d}', '\u{10cdd}'), ('\u{10c9e}', '\u{10cde}'), ('\u{10c9f}', '\u{10cdf}'), + ('\u{10ca0}', '\u{10ce0}'), ('\u{10ca1}', '\u{10ce1}'), ('\u{10ca2}', '\u{10ce2}'), + ('\u{10ca3}', '\u{10ce3}'), ('\u{10ca4}', '\u{10ce4}'), ('\u{10ca5}', '\u{10ce5}'), + ('\u{10ca6}', '\u{10ce6}'), ('\u{10ca7}', '\u{10ce7}'), ('\u{10ca8}', '\u{10ce8}'), + ('\u{10ca9}', '\u{10ce9}'), ('\u{10caa}', '\u{10cea}'), ('\u{10cab}', '\u{10ceb}'), + ('\u{10cac}', '\u{10cec}'), ('\u{10cad}', '\u{10ced}'), ('\u{10cae}', '\u{10cee}'), + ('\u{10caf}', '\u{10cef}'), ('\u{10cb0}', '\u{10cf0}'), ('\u{10cb1}', '\u{10cf1}'), + ('\u{10cb2}', '\u{10cf2}'), ('\u{118a0}', '\u{118c0}'), ('\u{118a1}', '\u{118c1}'), + ('\u{118a2}', '\u{118c2}'), ('\u{118a3}', '\u{118c3}'), ('\u{118a4}', '\u{118c4}'), + ('\u{118a5}', '\u{118c5}'), ('\u{118a6}', '\u{118c6}'), ('\u{118a7}', '\u{118c7}'), + ('\u{118a8}', '\u{118c8}'), ('\u{118a9}', '\u{118c9}'), ('\u{118aa}', '\u{118ca}'), + ('\u{118ab}', '\u{118cb}'), ('\u{118ac}', '\u{118cc}'), ('\u{118ad}', '\u{118cd}'), + ('\u{118ae}', '\u{118ce}'), ('\u{118af}', '\u{118cf}'), ('\u{118b0}', '\u{118d0}'), + ('\u{118b1}', '\u{118d1}'), ('\u{118b2}', '\u{118d2}'), ('\u{118b3}', '\u{118d3}'), + ('\u{118b4}', '\u{118d4}'), ('\u{118b5}', '\u{118d5}'), ('\u{118b6}', '\u{118d6}'), + ('\u{118b7}', '\u{118d7}'), ('\u{118b8}', '\u{118d8}'), ('\u{118b9}', '\u{118d9}'), + ('\u{118ba}', '\u{118da}'), ('\u{118bb}', '\u{118db}'), ('\u{118bc}', '\u{118dc}'), + ('\u{118bd}', '\u{118dd}'), ('\u{118be}', '\u{118de}'), ('\u{118bf}', '\u{118df}'), + ('\u{16e40}', '\u{16e60}'), ('\u{16e41}', '\u{16e61}'), ('\u{16e42}', '\u{16e62}'), + ('\u{16e43}', '\u{16e63}'), ('\u{16e44}', '\u{16e64}'), ('\u{16e45}', '\u{16e65}'), + ('\u{16e46}', '\u{16e66}'), ('\u{16e47}', '\u{16e67}'), ('\u{16e48}', '\u{16e68}'), + ('\u{16e49}', '\u{16e69}'), ('\u{16e4a}', '\u{16e6a}'), ('\u{16e4b}', '\u{16e6b}'), + ('\u{16e4c}', '\u{16e6c}'), ('\u{16e4d}', '\u{16e6d}'), ('\u{16e4e}', '\u{16e6e}'), + ('\u{16e4f}', '\u{16e6f}'), ('\u{16e50}', '\u{16e70}'), ('\u{16e51}', '\u{16e71}'), + ('\u{16e52}', '\u{16e72}'), ('\u{16e53}', '\u{16e73}'), ('\u{16e54}', '\u{16e74}'), + ('\u{16e55}', '\u{16e75}'), ('\u{16e56}', '\u{16e76}'), ('\u{16e57}', '\u{16e77}'), + ('\u{16e58}', '\u{16e78}'), ('\u{16e59}', '\u{16e79}'), ('\u{16e5a}', '\u{16e7a}'), + ('\u{16e5b}', '\u{16e7b}'), ('\u{16e5c}', '\u{16e7c}'), ('\u{16e5d}', '\u{16e7d}'), + ('\u{16e5e}', '\u{16e7e}'), ('\u{16e5f}', '\u{16e7f}'), ('\u{1e900}', '\u{1e922}'), + ('\u{1e901}', '\u{1e923}'), ('\u{1e902}', '\u{1e924}'), ('\u{1e903}', '\u{1e925}'), + ('\u{1e904}', '\u{1e926}'), ('\u{1e905}', '\u{1e927}'), ('\u{1e906}', '\u{1e928}'), + ('\u{1e907}', '\u{1e929}'), ('\u{1e908}', '\u{1e92a}'), ('\u{1e909}', '\u{1e92b}'), + ('\u{1e90a}', '\u{1e92c}'), ('\u{1e90b}', '\u{1e92d}'), ('\u{1e90c}', '\u{1e92e}'), + ('\u{1e90d}', '\u{1e92f}'), ('\u{1e90e}', '\u{1e930}'), ('\u{1e90f}', '\u{1e931}'), + ('\u{1e910}', '\u{1e932}'), ('\u{1e911}', '\u{1e933}'), ('\u{1e912}', '\u{1e934}'), + ('\u{1e913}', '\u{1e935}'), ('\u{1e914}', '\u{1e936}'), ('\u{1e915}', '\u{1e937}'), + ('\u{1e916}', '\u{1e938}'), ('\u{1e917}', '\u{1e939}'), ('\u{1e918}', '\u{1e93a}'), + ('\u{1e919}', '\u{1e93b}'), ('\u{1e91a}', '\u{1e93c}'), ('\u{1e91b}', '\u{1e93d}'), + ('\u{1e91c}', '\u{1e93e}'), ('\u{1e91d}', '\u{1e93f}'), ('\u{1e91e}', '\u{1e940}'), + ('\u{1e91f}', '\u{1e941}'), ('\u{1e920}', '\u{1e942}'), ('\u{1e921}', '\u{1e943}'), ]; - static UPPERCASE_TABLE: &[(char, [char; 3])] = &[ - ('\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}']), + static LOWERCASE_TABLE_MULTI: &[(char, [char; 3])] = &[ + ('\u{130}', ['i', '\u{307}', '\u{0}']), + ]; + + static UPPERCASE_TABLE_SINGLE: &[(char, char)] = &[ + ('\u{b5}', '\u{39c}'), ('\u{e0}', '\u{c0}'), ('\u{e1}', '\u{c1}'), ('\u{e2}', '\u{c2}'), + ('\u{e3}', '\u{c3}'), ('\u{e4}', '\u{c4}'), ('\u{e5}', '\u{c5}'), ('\u{e6}', '\u{c6}'), + ('\u{e7}', '\u{c7}'), ('\u{e8}', '\u{c8}'), ('\u{e9}', '\u{c9}'), ('\u{ea}', '\u{ca}'), + ('\u{eb}', '\u{cb}'), ('\u{ec}', '\u{cc}'), ('\u{ed}', '\u{cd}'), ('\u{ee}', '\u{ce}'), + ('\u{ef}', '\u{cf}'), ('\u{f0}', '\u{d0}'), ('\u{f1}', '\u{d1}'), ('\u{f2}', '\u{d2}'), + ('\u{f3}', '\u{d3}'), ('\u{f4}', '\u{d4}'), ('\u{f5}', '\u{d5}'), ('\u{f6}', '\u{d6}'), + ('\u{f8}', '\u{d8}'), ('\u{f9}', '\u{d9}'), ('\u{fa}', '\u{da}'), ('\u{fb}', '\u{db}'), + ('\u{fc}', '\u{dc}'), ('\u{fd}', '\u{dd}'), ('\u{fe}', '\u{de}'), ('\u{ff}', '\u{178}'), + ('\u{101}', '\u{100}'), ('\u{103}', '\u{102}'), ('\u{105}', '\u{104}'), + ('\u{107}', '\u{106}'), ('\u{109}', '\u{108}'), ('\u{10b}', '\u{10a}'), + ('\u{10d}', '\u{10c}'), ('\u{10f}', '\u{10e}'), ('\u{111}', '\u{110}'), + ('\u{113}', '\u{112}'), ('\u{115}', '\u{114}'), ('\u{117}', '\u{116}'), + ('\u{119}', '\u{118}'), ('\u{11b}', '\u{11a}'), ('\u{11d}', '\u{11c}'), + ('\u{11f}', '\u{11e}'), ('\u{121}', '\u{120}'), ('\u{123}', '\u{122}'), + ('\u{125}', '\u{124}'), ('\u{127}', '\u{126}'), ('\u{129}', '\u{128}'), + ('\u{12b}', '\u{12a}'), ('\u{12d}', '\u{12c}'), ('\u{12f}', '\u{12e}'), ('\u{131}', 'I'), + ('\u{133}', '\u{132}'), ('\u{135}', '\u{134}'), ('\u{137}', '\u{136}'), + ('\u{13a}', '\u{139}'), ('\u{13c}', '\u{13b}'), ('\u{13e}', '\u{13d}'), + ('\u{140}', '\u{13f}'), ('\u{142}', '\u{141}'), ('\u{144}', '\u{143}'), + ('\u{146}', '\u{145}'), ('\u{148}', '\u{147}'), ('\u{14b}', '\u{14a}'), + ('\u{14d}', '\u{14c}'), ('\u{14f}', '\u{14e}'), ('\u{151}', '\u{150}'), + ('\u{153}', '\u{152}'), ('\u{155}', '\u{154}'), ('\u{157}', '\u{156}'), + ('\u{159}', '\u{158}'), ('\u{15b}', '\u{15a}'), ('\u{15d}', '\u{15c}'), + ('\u{15f}', '\u{15e}'), ('\u{161}', '\u{160}'), ('\u{163}', '\u{162}'), + ('\u{165}', '\u{164}'), ('\u{167}', '\u{166}'), ('\u{169}', '\u{168}'), + ('\u{16b}', '\u{16a}'), ('\u{16d}', '\u{16c}'), ('\u{16f}', '\u{16e}'), + ('\u{171}', '\u{170}'), ('\u{173}', '\u{172}'), ('\u{175}', '\u{174}'), + ('\u{177}', '\u{176}'), ('\u{17a}', '\u{179}'), ('\u{17c}', '\u{17b}'), + ('\u{17e}', '\u{17d}'), ('\u{17f}', 'S'), ('\u{180}', '\u{243}'), ('\u{183}', '\u{182}'), + ('\u{185}', '\u{184}'), ('\u{188}', '\u{187}'), ('\u{18c}', '\u{18b}'), + ('\u{192}', '\u{191}'), ('\u{195}', '\u{1f6}'), ('\u{199}', '\u{198}'), + ('\u{19a}', '\u{23d}'), ('\u{19e}', '\u{220}'), ('\u{1a1}', '\u{1a0}'), + ('\u{1a3}', '\u{1a2}'), ('\u{1a5}', '\u{1a4}'), ('\u{1a8}', '\u{1a7}'), + ('\u{1ad}', '\u{1ac}'), ('\u{1b0}', '\u{1af}'), ('\u{1b4}', '\u{1b3}'), + ('\u{1b6}', '\u{1b5}'), ('\u{1b9}', '\u{1b8}'), ('\u{1bd}', '\u{1bc}'), + ('\u{1bf}', '\u{1f7}'), ('\u{1c5}', '\u{1c4}'), ('\u{1c6}', '\u{1c4}'), + ('\u{1c8}', '\u{1c7}'), ('\u{1c9}', '\u{1c7}'), ('\u{1cb}', '\u{1ca}'), + ('\u{1cc}', '\u{1ca}'), ('\u{1ce}', '\u{1cd}'), ('\u{1d0}', '\u{1cf}'), + ('\u{1d2}', '\u{1d1}'), ('\u{1d4}', '\u{1d3}'), ('\u{1d6}', '\u{1d5}'), + ('\u{1d8}', '\u{1d7}'), ('\u{1da}', '\u{1d9}'), ('\u{1dc}', '\u{1db}'), + ('\u{1dd}', '\u{18e}'), ('\u{1df}', '\u{1de}'), ('\u{1e1}', '\u{1e0}'), + ('\u{1e3}', '\u{1e2}'), ('\u{1e5}', '\u{1e4}'), ('\u{1e7}', '\u{1e6}'), + ('\u{1e9}', '\u{1e8}'), ('\u{1eb}', '\u{1ea}'), ('\u{1ed}', '\u{1ec}'), + ('\u{1ef}', '\u{1ee}'), ('\u{1f2}', '\u{1f1}'), ('\u{1f3}', '\u{1f1}'), + ('\u{1f5}', '\u{1f4}'), ('\u{1f9}', '\u{1f8}'), ('\u{1fb}', '\u{1fa}'), + ('\u{1fd}', '\u{1fc}'), ('\u{1ff}', '\u{1fe}'), ('\u{201}', '\u{200}'), + ('\u{203}', '\u{202}'), ('\u{205}', '\u{204}'), ('\u{207}', '\u{206}'), + ('\u{209}', '\u{208}'), ('\u{20b}', '\u{20a}'), ('\u{20d}', '\u{20c}'), + ('\u{20f}', '\u{20e}'), ('\u{211}', '\u{210}'), ('\u{213}', '\u{212}'), + ('\u{215}', '\u{214}'), ('\u{217}', '\u{216}'), ('\u{219}', '\u{218}'), + ('\u{21b}', '\u{21a}'), ('\u{21d}', '\u{21c}'), ('\u{21f}', '\u{21e}'), + ('\u{223}', '\u{222}'), ('\u{225}', '\u{224}'), ('\u{227}', '\u{226}'), + ('\u{229}', '\u{228}'), ('\u{22b}', '\u{22a}'), ('\u{22d}', '\u{22c}'), + ('\u{22f}', '\u{22e}'), ('\u{231}', '\u{230}'), ('\u{233}', '\u{232}'), + ('\u{23c}', '\u{23b}'), ('\u{23f}', '\u{2c7e}'), ('\u{240}', '\u{2c7f}'), + ('\u{242}', '\u{241}'), ('\u{247}', '\u{246}'), ('\u{249}', '\u{248}'), + ('\u{24b}', '\u{24a}'), ('\u{24d}', '\u{24c}'), ('\u{24f}', '\u{24e}'), + ('\u{250}', '\u{2c6f}'), ('\u{251}', '\u{2c6d}'), ('\u{252}', '\u{2c70}'), + ('\u{253}', '\u{181}'), ('\u{254}', '\u{186}'), ('\u{256}', '\u{189}'), + ('\u{257}', '\u{18a}'), ('\u{259}', '\u{18f}'), ('\u{25b}', '\u{190}'), + ('\u{25c}', '\u{a7ab}'), ('\u{260}', '\u{193}'), ('\u{261}', '\u{a7ac}'), + ('\u{263}', '\u{194}'), ('\u{265}', '\u{a78d}'), ('\u{266}', '\u{a7aa}'), + ('\u{268}', '\u{197}'), ('\u{269}', '\u{196}'), ('\u{26a}', '\u{a7ae}'), + ('\u{26b}', '\u{2c62}'), ('\u{26c}', '\u{a7ad}'), ('\u{26f}', '\u{19c}'), + ('\u{271}', '\u{2c6e}'), ('\u{272}', '\u{19d}'), ('\u{275}', '\u{19f}'), + ('\u{27d}', '\u{2c64}'), ('\u{280}', '\u{1a6}'), ('\u{282}', '\u{a7c5}'), + ('\u{283}', '\u{1a9}'), ('\u{287}', '\u{a7b1}'), ('\u{288}', '\u{1ae}'), + ('\u{289}', '\u{244}'), ('\u{28a}', '\u{1b1}'), ('\u{28b}', '\u{1b2}'), + ('\u{28c}', '\u{245}'), ('\u{292}', '\u{1b7}'), ('\u{29d}', '\u{a7b2}'), + ('\u{29e}', '\u{a7b0}'), ('\u{345}', '\u{399}'), ('\u{371}', '\u{370}'), + ('\u{373}', '\u{372}'), ('\u{377}', '\u{376}'), ('\u{37b}', '\u{3fd}'), + ('\u{37c}', '\u{3fe}'), ('\u{37d}', '\u{3ff}'), ('\u{3ac}', '\u{386}'), + ('\u{3ad}', '\u{388}'), ('\u{3ae}', '\u{389}'), ('\u{3af}', '\u{38a}'), + ('\u{3b1}', '\u{391}'), ('\u{3b2}', '\u{392}'), ('\u{3b3}', '\u{393}'), + ('\u{3b4}', '\u{394}'), ('\u{3b5}', '\u{395}'), ('\u{3b6}', '\u{396}'), + ('\u{3b7}', '\u{397}'), ('\u{3b8}', '\u{398}'), ('\u{3b9}', '\u{399}'), + ('\u{3ba}', '\u{39a}'), ('\u{3bb}', '\u{39b}'), ('\u{3bc}', '\u{39c}'), + ('\u{3bd}', '\u{39d}'), ('\u{3be}', '\u{39e}'), ('\u{3bf}', '\u{39f}'), + ('\u{3c0}', '\u{3a0}'), ('\u{3c1}', '\u{3a1}'), ('\u{3c2}', '\u{3a3}'), + ('\u{3c3}', '\u{3a3}'), ('\u{3c4}', '\u{3a4}'), ('\u{3c5}', '\u{3a5}'), + ('\u{3c6}', '\u{3a6}'), ('\u{3c7}', '\u{3a7}'), ('\u{3c8}', '\u{3a8}'), + ('\u{3c9}', '\u{3a9}'), ('\u{3ca}', '\u{3aa}'), ('\u{3cb}', '\u{3ab}'), + ('\u{3cc}', '\u{38c}'), ('\u{3cd}', '\u{38e}'), ('\u{3ce}', '\u{38f}'), + ('\u{3d0}', '\u{392}'), ('\u{3d1}', '\u{398}'), ('\u{3d5}', '\u{3a6}'), + ('\u{3d6}', '\u{3a0}'), ('\u{3d7}', '\u{3cf}'), ('\u{3d9}', '\u{3d8}'), + ('\u{3db}', '\u{3da}'), ('\u{3dd}', '\u{3dc}'), ('\u{3df}', '\u{3de}'), + ('\u{3e1}', '\u{3e0}'), ('\u{3e3}', '\u{3e2}'), ('\u{3e5}', '\u{3e4}'), + ('\u{3e7}', '\u{3e6}'), ('\u{3e9}', '\u{3e8}'), ('\u{3eb}', '\u{3ea}'), + ('\u{3ed}', '\u{3ec}'), ('\u{3ef}', '\u{3ee}'), ('\u{3f0}', '\u{39a}'), + ('\u{3f1}', '\u{3a1}'), ('\u{3f2}', '\u{3f9}'), ('\u{3f3}', '\u{37f}'), + ('\u{3f5}', '\u{395}'), ('\u{3f8}', '\u{3f7}'), ('\u{3fb}', '\u{3fa}'), + ('\u{430}', '\u{410}'), ('\u{431}', '\u{411}'), ('\u{432}', '\u{412}'), + ('\u{433}', '\u{413}'), ('\u{434}', '\u{414}'), ('\u{435}', '\u{415}'), + ('\u{436}', '\u{416}'), ('\u{437}', '\u{417}'), ('\u{438}', '\u{418}'), + ('\u{439}', '\u{419}'), ('\u{43a}', '\u{41a}'), ('\u{43b}', '\u{41b}'), + ('\u{43c}', '\u{41c}'), ('\u{43d}', '\u{41d}'), ('\u{43e}', '\u{41e}'), + ('\u{43f}', '\u{41f}'), ('\u{440}', '\u{420}'), ('\u{441}', '\u{421}'), + ('\u{442}', '\u{422}'), ('\u{443}', '\u{423}'), ('\u{444}', '\u{424}'), + ('\u{445}', '\u{425}'), ('\u{446}', '\u{426}'), ('\u{447}', '\u{427}'), + ('\u{448}', '\u{428}'), ('\u{449}', '\u{429}'), ('\u{44a}', '\u{42a}'), + ('\u{44b}', '\u{42b}'), ('\u{44c}', '\u{42c}'), ('\u{44d}', '\u{42d}'), + ('\u{44e}', '\u{42e}'), ('\u{44f}', '\u{42f}'), ('\u{450}', '\u{400}'), + ('\u{451}', '\u{401}'), ('\u{452}', '\u{402}'), ('\u{453}', '\u{403}'), + ('\u{454}', '\u{404}'), ('\u{455}', '\u{405}'), ('\u{456}', '\u{406}'), + ('\u{457}', '\u{407}'), ('\u{458}', '\u{408}'), ('\u{459}', '\u{409}'), + ('\u{45a}', '\u{40a}'), ('\u{45b}', '\u{40b}'), ('\u{45c}', '\u{40c}'), + ('\u{45d}', '\u{40d}'), ('\u{45e}', '\u{40e}'), ('\u{45f}', '\u{40f}'), + ('\u{461}', '\u{460}'), ('\u{463}', '\u{462}'), ('\u{465}', '\u{464}'), + ('\u{467}', '\u{466}'), ('\u{469}', '\u{468}'), ('\u{46b}', '\u{46a}'), + ('\u{46d}', '\u{46c}'), ('\u{46f}', '\u{46e}'), ('\u{471}', '\u{470}'), + ('\u{473}', '\u{472}'), ('\u{475}', '\u{474}'), ('\u{477}', '\u{476}'), + ('\u{479}', '\u{478}'), ('\u{47b}', '\u{47a}'), ('\u{47d}', '\u{47c}'), + ('\u{47f}', '\u{47e}'), ('\u{481}', '\u{480}'), ('\u{48b}', '\u{48a}'), + ('\u{48d}', '\u{48c}'), ('\u{48f}', '\u{48e}'), ('\u{491}', '\u{490}'), + ('\u{493}', '\u{492}'), ('\u{495}', '\u{494}'), ('\u{497}', '\u{496}'), + ('\u{499}', '\u{498}'), ('\u{49b}', '\u{49a}'), ('\u{49d}', '\u{49c}'), + ('\u{49f}', '\u{49e}'), ('\u{4a1}', '\u{4a0}'), ('\u{4a3}', '\u{4a2}'), + ('\u{4a5}', '\u{4a4}'), ('\u{4a7}', '\u{4a6}'), ('\u{4a9}', '\u{4a8}'), + ('\u{4ab}', '\u{4aa}'), ('\u{4ad}', '\u{4ac}'), ('\u{4af}', '\u{4ae}'), + ('\u{4b1}', '\u{4b0}'), ('\u{4b3}', '\u{4b2}'), ('\u{4b5}', '\u{4b4}'), + ('\u{4b7}', '\u{4b6}'), ('\u{4b9}', '\u{4b8}'), ('\u{4bb}', '\u{4ba}'), + ('\u{4bd}', '\u{4bc}'), ('\u{4bf}', '\u{4be}'), ('\u{4c2}', '\u{4c1}'), + ('\u{4c4}', '\u{4c3}'), ('\u{4c6}', '\u{4c5}'), ('\u{4c8}', '\u{4c7}'), + ('\u{4ca}', '\u{4c9}'), ('\u{4cc}', '\u{4cb}'), ('\u{4ce}', '\u{4cd}'), + ('\u{4cf}', '\u{4c0}'), ('\u{4d1}', '\u{4d0}'), ('\u{4d3}', '\u{4d2}'), + ('\u{4d5}', '\u{4d4}'), ('\u{4d7}', '\u{4d6}'), ('\u{4d9}', '\u{4d8}'), + ('\u{4db}', '\u{4da}'), ('\u{4dd}', '\u{4dc}'), ('\u{4df}', '\u{4de}'), + ('\u{4e1}', '\u{4e0}'), ('\u{4e3}', '\u{4e2}'), ('\u{4e5}', '\u{4e4}'), + ('\u{4e7}', '\u{4e6}'), ('\u{4e9}', '\u{4e8}'), ('\u{4eb}', '\u{4ea}'), + ('\u{4ed}', '\u{4ec}'), ('\u{4ef}', '\u{4ee}'), ('\u{4f1}', '\u{4f0}'), + ('\u{4f3}', '\u{4f2}'), ('\u{4f5}', '\u{4f4}'), ('\u{4f7}', '\u{4f6}'), + ('\u{4f9}', '\u{4f8}'), ('\u{4fb}', '\u{4fa}'), ('\u{4fd}', '\u{4fc}'), + ('\u{4ff}', '\u{4fe}'), ('\u{501}', '\u{500}'), ('\u{503}', '\u{502}'), + ('\u{505}', '\u{504}'), ('\u{507}', '\u{506}'), ('\u{509}', '\u{508}'), + ('\u{50b}', '\u{50a}'), ('\u{50d}', '\u{50c}'), ('\u{50f}', '\u{50e}'), + ('\u{511}', '\u{510}'), ('\u{513}', '\u{512}'), ('\u{515}', '\u{514}'), + ('\u{517}', '\u{516}'), ('\u{519}', '\u{518}'), ('\u{51b}', '\u{51a}'), + ('\u{51d}', '\u{51c}'), ('\u{51f}', '\u{51e}'), ('\u{521}', '\u{520}'), + ('\u{523}', '\u{522}'), ('\u{525}', '\u{524}'), ('\u{527}', '\u{526}'), + ('\u{529}', '\u{528}'), ('\u{52b}', '\u{52a}'), ('\u{52d}', '\u{52c}'), + ('\u{52f}', '\u{52e}'), ('\u{561}', '\u{531}'), ('\u{562}', '\u{532}'), + ('\u{563}', '\u{533}'), ('\u{564}', '\u{534}'), ('\u{565}', '\u{535}'), + ('\u{566}', '\u{536}'), ('\u{567}', '\u{537}'), ('\u{568}', '\u{538}'), + ('\u{569}', '\u{539}'), ('\u{56a}', '\u{53a}'), ('\u{56b}', '\u{53b}'), + ('\u{56c}', '\u{53c}'), ('\u{56d}', '\u{53d}'), ('\u{56e}', '\u{53e}'), + ('\u{56f}', '\u{53f}'), ('\u{570}', '\u{540}'), ('\u{571}', '\u{541}'), + ('\u{572}', '\u{542}'), ('\u{573}', '\u{543}'), ('\u{574}', '\u{544}'), + ('\u{575}', '\u{545}'), ('\u{576}', '\u{546}'), ('\u{577}', '\u{547}'), + ('\u{578}', '\u{548}'), ('\u{579}', '\u{549}'), ('\u{57a}', '\u{54a}'), + ('\u{57b}', '\u{54b}'), ('\u{57c}', '\u{54c}'), ('\u{57d}', '\u{54d}'), + ('\u{57e}', '\u{54e}'), ('\u{57f}', '\u{54f}'), ('\u{580}', '\u{550}'), + ('\u{581}', '\u{551}'), ('\u{582}', '\u{552}'), ('\u{583}', '\u{553}'), + ('\u{584}', '\u{554}'), ('\u{585}', '\u{555}'), ('\u{586}', '\u{556}'), + ('\u{10d0}', '\u{1c90}'), ('\u{10d1}', '\u{1c91}'), ('\u{10d2}', '\u{1c92}'), + ('\u{10d3}', '\u{1c93}'), ('\u{10d4}', '\u{1c94}'), ('\u{10d5}', '\u{1c95}'), + ('\u{10d6}', '\u{1c96}'), ('\u{10d7}', '\u{1c97}'), ('\u{10d8}', '\u{1c98}'), + ('\u{10d9}', '\u{1c99}'), ('\u{10da}', '\u{1c9a}'), ('\u{10db}', '\u{1c9b}'), + ('\u{10dc}', '\u{1c9c}'), ('\u{10dd}', '\u{1c9d}'), ('\u{10de}', '\u{1c9e}'), + ('\u{10df}', '\u{1c9f}'), ('\u{10e0}', '\u{1ca0}'), ('\u{10e1}', '\u{1ca1}'), + ('\u{10e2}', '\u{1ca2}'), ('\u{10e3}', '\u{1ca3}'), ('\u{10e4}', '\u{1ca4}'), + ('\u{10e5}', '\u{1ca5}'), ('\u{10e6}', '\u{1ca6}'), ('\u{10e7}', '\u{1ca7}'), + ('\u{10e8}', '\u{1ca8}'), ('\u{10e9}', '\u{1ca9}'), ('\u{10ea}', '\u{1caa}'), + ('\u{10eb}', '\u{1cab}'), ('\u{10ec}', '\u{1cac}'), ('\u{10ed}', '\u{1cad}'), + ('\u{10ee}', '\u{1cae}'), ('\u{10ef}', '\u{1caf}'), ('\u{10f0}', '\u{1cb0}'), + ('\u{10f1}', '\u{1cb1}'), ('\u{10f2}', '\u{1cb2}'), ('\u{10f3}', '\u{1cb3}'), + ('\u{10f4}', '\u{1cb4}'), ('\u{10f5}', '\u{1cb5}'), ('\u{10f6}', '\u{1cb6}'), + ('\u{10f7}', '\u{1cb7}'), ('\u{10f8}', '\u{1cb8}'), ('\u{10f9}', '\u{1cb9}'), + ('\u{10fa}', '\u{1cba}'), ('\u{10fd}', '\u{1cbd}'), ('\u{10fe}', '\u{1cbe}'), + ('\u{10ff}', '\u{1cbf}'), ('\u{13f8}', '\u{13f0}'), ('\u{13f9}', '\u{13f1}'), + ('\u{13fa}', '\u{13f2}'), ('\u{13fb}', '\u{13f3}'), ('\u{13fc}', '\u{13f4}'), + ('\u{13fd}', '\u{13f5}'), ('\u{1c80}', '\u{412}'), ('\u{1c81}', '\u{414}'), + ('\u{1c82}', '\u{41e}'), ('\u{1c83}', '\u{421}'), ('\u{1c84}', '\u{422}'), + ('\u{1c85}', '\u{422}'), ('\u{1c86}', '\u{42a}'), ('\u{1c87}', '\u{462}'), + ('\u{1c88}', '\u{a64a}'), ('\u{1d79}', '\u{a77d}'), ('\u{1d7d}', '\u{2c63}'), + ('\u{1d8e}', '\u{a7c6}'), ('\u{1e01}', '\u{1e00}'), ('\u{1e03}', '\u{1e02}'), + ('\u{1e05}', '\u{1e04}'), ('\u{1e07}', '\u{1e06}'), ('\u{1e09}', '\u{1e08}'), + ('\u{1e0b}', '\u{1e0a}'), ('\u{1e0d}', '\u{1e0c}'), ('\u{1e0f}', '\u{1e0e}'), + ('\u{1e11}', '\u{1e10}'), ('\u{1e13}', '\u{1e12}'), ('\u{1e15}', '\u{1e14}'), + ('\u{1e17}', '\u{1e16}'), ('\u{1e19}', '\u{1e18}'), ('\u{1e1b}', '\u{1e1a}'), + ('\u{1e1d}', '\u{1e1c}'), ('\u{1e1f}', '\u{1e1e}'), ('\u{1e21}', '\u{1e20}'), + ('\u{1e23}', '\u{1e22}'), ('\u{1e25}', '\u{1e24}'), ('\u{1e27}', '\u{1e26}'), + ('\u{1e29}', '\u{1e28}'), ('\u{1e2b}', '\u{1e2a}'), ('\u{1e2d}', '\u{1e2c}'), + ('\u{1e2f}', '\u{1e2e}'), ('\u{1e31}', '\u{1e30}'), ('\u{1e33}', '\u{1e32}'), + ('\u{1e35}', '\u{1e34}'), ('\u{1e37}', '\u{1e36}'), ('\u{1e39}', '\u{1e38}'), + ('\u{1e3b}', '\u{1e3a}'), ('\u{1e3d}', '\u{1e3c}'), ('\u{1e3f}', '\u{1e3e}'), + ('\u{1e41}', '\u{1e40}'), ('\u{1e43}', '\u{1e42}'), ('\u{1e45}', '\u{1e44}'), + ('\u{1e47}', '\u{1e46}'), ('\u{1e49}', '\u{1e48}'), ('\u{1e4b}', '\u{1e4a}'), + ('\u{1e4d}', '\u{1e4c}'), ('\u{1e4f}', '\u{1e4e}'), ('\u{1e51}', '\u{1e50}'), + ('\u{1e53}', '\u{1e52}'), ('\u{1e55}', '\u{1e54}'), ('\u{1e57}', '\u{1e56}'), + ('\u{1e59}', '\u{1e58}'), ('\u{1e5b}', '\u{1e5a}'), ('\u{1e5d}', '\u{1e5c}'), + ('\u{1e5f}', '\u{1e5e}'), ('\u{1e61}', '\u{1e60}'), ('\u{1e63}', '\u{1e62}'), + ('\u{1e65}', '\u{1e64}'), ('\u{1e67}', '\u{1e66}'), ('\u{1e69}', '\u{1e68}'), + ('\u{1e6b}', '\u{1e6a}'), ('\u{1e6d}', '\u{1e6c}'), ('\u{1e6f}', '\u{1e6e}'), + ('\u{1e71}', '\u{1e70}'), ('\u{1e73}', '\u{1e72}'), ('\u{1e75}', '\u{1e74}'), + ('\u{1e77}', '\u{1e76}'), ('\u{1e79}', '\u{1e78}'), ('\u{1e7b}', '\u{1e7a}'), + ('\u{1e7d}', '\u{1e7c}'), ('\u{1e7f}', '\u{1e7e}'), ('\u{1e81}', '\u{1e80}'), + ('\u{1e83}', '\u{1e82}'), ('\u{1e85}', '\u{1e84}'), ('\u{1e87}', '\u{1e86}'), + ('\u{1e89}', '\u{1e88}'), ('\u{1e8b}', '\u{1e8a}'), ('\u{1e8d}', '\u{1e8c}'), + ('\u{1e8f}', '\u{1e8e}'), ('\u{1e91}', '\u{1e90}'), ('\u{1e93}', '\u{1e92}'), + ('\u{1e95}', '\u{1e94}'), ('\u{1e9b}', '\u{1e60}'), ('\u{1ea1}', '\u{1ea0}'), + ('\u{1ea3}', '\u{1ea2}'), ('\u{1ea5}', '\u{1ea4}'), ('\u{1ea7}', '\u{1ea6}'), + ('\u{1ea9}', '\u{1ea8}'), ('\u{1eab}', '\u{1eaa}'), ('\u{1ead}', '\u{1eac}'), + ('\u{1eaf}', '\u{1eae}'), ('\u{1eb1}', '\u{1eb0}'), ('\u{1eb3}', '\u{1eb2}'), + ('\u{1eb5}', '\u{1eb4}'), ('\u{1eb7}', '\u{1eb6}'), ('\u{1eb9}', '\u{1eb8}'), + ('\u{1ebb}', '\u{1eba}'), ('\u{1ebd}', '\u{1ebc}'), ('\u{1ebf}', '\u{1ebe}'), + ('\u{1ec1}', '\u{1ec0}'), ('\u{1ec3}', '\u{1ec2}'), ('\u{1ec5}', '\u{1ec4}'), + ('\u{1ec7}', '\u{1ec6}'), ('\u{1ec9}', '\u{1ec8}'), ('\u{1ecb}', '\u{1eca}'), + ('\u{1ecd}', '\u{1ecc}'), ('\u{1ecf}', '\u{1ece}'), ('\u{1ed1}', '\u{1ed0}'), + ('\u{1ed3}', '\u{1ed2}'), ('\u{1ed5}', '\u{1ed4}'), ('\u{1ed7}', '\u{1ed6}'), + ('\u{1ed9}', '\u{1ed8}'), ('\u{1edb}', '\u{1eda}'), ('\u{1edd}', '\u{1edc}'), + ('\u{1edf}', '\u{1ede}'), ('\u{1ee1}', '\u{1ee0}'), ('\u{1ee3}', '\u{1ee2}'), + ('\u{1ee5}', '\u{1ee4}'), ('\u{1ee7}', '\u{1ee6}'), ('\u{1ee9}', '\u{1ee8}'), + ('\u{1eeb}', '\u{1eea}'), ('\u{1eed}', '\u{1eec}'), ('\u{1eef}', '\u{1eee}'), + ('\u{1ef1}', '\u{1ef0}'), ('\u{1ef3}', '\u{1ef2}'), ('\u{1ef5}', '\u{1ef4}'), + ('\u{1ef7}', '\u{1ef6}'), ('\u{1ef9}', '\u{1ef8}'), ('\u{1efb}', '\u{1efa}'), + ('\u{1efd}', '\u{1efc}'), ('\u{1eff}', '\u{1efe}'), ('\u{1f00}', '\u{1f08}'), + ('\u{1f01}', '\u{1f09}'), ('\u{1f02}', '\u{1f0a}'), ('\u{1f03}', '\u{1f0b}'), + ('\u{1f04}', '\u{1f0c}'), ('\u{1f05}', '\u{1f0d}'), ('\u{1f06}', '\u{1f0e}'), + ('\u{1f07}', '\u{1f0f}'), ('\u{1f10}', '\u{1f18}'), ('\u{1f11}', '\u{1f19}'), + ('\u{1f12}', '\u{1f1a}'), ('\u{1f13}', '\u{1f1b}'), ('\u{1f14}', '\u{1f1c}'), + ('\u{1f15}', '\u{1f1d}'), ('\u{1f20}', '\u{1f28}'), ('\u{1f21}', '\u{1f29}'), + ('\u{1f22}', '\u{1f2a}'), ('\u{1f23}', '\u{1f2b}'), ('\u{1f24}', '\u{1f2c}'), + ('\u{1f25}', '\u{1f2d}'), ('\u{1f26}', '\u{1f2e}'), ('\u{1f27}', '\u{1f2f}'), + ('\u{1f30}', '\u{1f38}'), ('\u{1f31}', '\u{1f39}'), ('\u{1f32}', '\u{1f3a}'), + ('\u{1f33}', '\u{1f3b}'), ('\u{1f34}', '\u{1f3c}'), ('\u{1f35}', '\u{1f3d}'), + ('\u{1f36}', '\u{1f3e}'), ('\u{1f37}', '\u{1f3f}'), ('\u{1f40}', '\u{1f48}'), + ('\u{1f41}', '\u{1f49}'), ('\u{1f42}', '\u{1f4a}'), ('\u{1f43}', '\u{1f4b}'), + ('\u{1f44}', '\u{1f4c}'), ('\u{1f45}', '\u{1f4d}'), ('\u{1f51}', '\u{1f59}'), + ('\u{1f53}', '\u{1f5b}'), ('\u{1f55}', '\u{1f5d}'), ('\u{1f57}', '\u{1f5f}'), + ('\u{1f60}', '\u{1f68}'), ('\u{1f61}', '\u{1f69}'), ('\u{1f62}', '\u{1f6a}'), + ('\u{1f63}', '\u{1f6b}'), ('\u{1f64}', '\u{1f6c}'), ('\u{1f65}', '\u{1f6d}'), + ('\u{1f66}', '\u{1f6e}'), ('\u{1f67}', '\u{1f6f}'), ('\u{1f70}', '\u{1fba}'), + ('\u{1f71}', '\u{1fbb}'), ('\u{1f72}', '\u{1fc8}'), ('\u{1f73}', '\u{1fc9}'), + ('\u{1f74}', '\u{1fca}'), ('\u{1f75}', '\u{1fcb}'), ('\u{1f76}', '\u{1fda}'), + ('\u{1f77}', '\u{1fdb}'), ('\u{1f78}', '\u{1ff8}'), ('\u{1f79}', '\u{1ff9}'), + ('\u{1f7a}', '\u{1fea}'), ('\u{1f7b}', '\u{1feb}'), ('\u{1f7c}', '\u{1ffa}'), + ('\u{1f7d}', '\u{1ffb}'), ('\u{1fb0}', '\u{1fb8}'), ('\u{1fb1}', '\u{1fb9}'), + ('\u{1fbe}', '\u{399}'), ('\u{1fd0}', '\u{1fd8}'), ('\u{1fd1}', '\u{1fd9}'), + ('\u{1fe0}', '\u{1fe8}'), ('\u{1fe1}', '\u{1fe9}'), ('\u{1fe5}', '\u{1fec}'), + ('\u{214e}', '\u{2132}'), ('\u{2170}', '\u{2160}'), ('\u{2171}', '\u{2161}'), + ('\u{2172}', '\u{2162}'), ('\u{2173}', '\u{2163}'), ('\u{2174}', '\u{2164}'), + ('\u{2175}', '\u{2165}'), ('\u{2176}', '\u{2166}'), ('\u{2177}', '\u{2167}'), + ('\u{2178}', '\u{2168}'), ('\u{2179}', '\u{2169}'), ('\u{217a}', '\u{216a}'), + ('\u{217b}', '\u{216b}'), ('\u{217c}', '\u{216c}'), ('\u{217d}', '\u{216d}'), + ('\u{217e}', '\u{216e}'), ('\u{217f}', '\u{216f}'), ('\u{2184}', '\u{2183}'), + ('\u{24d0}', '\u{24b6}'), ('\u{24d1}', '\u{24b7}'), ('\u{24d2}', '\u{24b8}'), + ('\u{24d3}', '\u{24b9}'), ('\u{24d4}', '\u{24ba}'), ('\u{24d5}', '\u{24bb}'), + ('\u{24d6}', '\u{24bc}'), ('\u{24d7}', '\u{24bd}'), ('\u{24d8}', '\u{24be}'), + ('\u{24d9}', '\u{24bf}'), ('\u{24da}', '\u{24c0}'), ('\u{24db}', '\u{24c1}'), + ('\u{24dc}', '\u{24c2}'), ('\u{24dd}', '\u{24c3}'), ('\u{24de}', '\u{24c4}'), + ('\u{24df}', '\u{24c5}'), ('\u{24e0}', '\u{24c6}'), ('\u{24e1}', '\u{24c7}'), + ('\u{24e2}', '\u{24c8}'), ('\u{24e3}', '\u{24c9}'), ('\u{24e4}', '\u{24ca}'), + ('\u{24e5}', '\u{24cb}'), ('\u{24e6}', '\u{24cc}'), ('\u{24e7}', '\u{24cd}'), + ('\u{24e8}', '\u{24ce}'), ('\u{24e9}', '\u{24cf}'), ('\u{2c30}', '\u{2c00}'), + ('\u{2c31}', '\u{2c01}'), ('\u{2c32}', '\u{2c02}'), ('\u{2c33}', '\u{2c03}'), + ('\u{2c34}', '\u{2c04}'), ('\u{2c35}', '\u{2c05}'), ('\u{2c36}', '\u{2c06}'), + ('\u{2c37}', '\u{2c07}'), ('\u{2c38}', '\u{2c08}'), ('\u{2c39}', '\u{2c09}'), + ('\u{2c3a}', '\u{2c0a}'), ('\u{2c3b}', '\u{2c0b}'), ('\u{2c3c}', '\u{2c0c}'), + ('\u{2c3d}', '\u{2c0d}'), ('\u{2c3e}', '\u{2c0e}'), ('\u{2c3f}', '\u{2c0f}'), + ('\u{2c40}', '\u{2c10}'), ('\u{2c41}', '\u{2c11}'), ('\u{2c42}', '\u{2c12}'), + ('\u{2c43}', '\u{2c13}'), ('\u{2c44}', '\u{2c14}'), ('\u{2c45}', '\u{2c15}'), + ('\u{2c46}', '\u{2c16}'), ('\u{2c47}', '\u{2c17}'), ('\u{2c48}', '\u{2c18}'), + ('\u{2c49}', '\u{2c19}'), ('\u{2c4a}', '\u{2c1a}'), ('\u{2c4b}', '\u{2c1b}'), + ('\u{2c4c}', '\u{2c1c}'), ('\u{2c4d}', '\u{2c1d}'), ('\u{2c4e}', '\u{2c1e}'), + ('\u{2c4f}', '\u{2c1f}'), ('\u{2c50}', '\u{2c20}'), ('\u{2c51}', '\u{2c21}'), + ('\u{2c52}', '\u{2c22}'), ('\u{2c53}', '\u{2c23}'), ('\u{2c54}', '\u{2c24}'), + ('\u{2c55}', '\u{2c25}'), ('\u{2c56}', '\u{2c26}'), ('\u{2c57}', '\u{2c27}'), + ('\u{2c58}', '\u{2c28}'), ('\u{2c59}', '\u{2c29}'), ('\u{2c5a}', '\u{2c2a}'), + ('\u{2c5b}', '\u{2c2b}'), ('\u{2c5c}', '\u{2c2c}'), ('\u{2c5d}', '\u{2c2d}'), + ('\u{2c5e}', '\u{2c2e}'), ('\u{2c5f}', '\u{2c2f}'), ('\u{2c61}', '\u{2c60}'), + ('\u{2c65}', '\u{23a}'), ('\u{2c66}', '\u{23e}'), ('\u{2c68}', '\u{2c67}'), + ('\u{2c6a}', '\u{2c69}'), ('\u{2c6c}', '\u{2c6b}'), ('\u{2c73}', '\u{2c72}'), + ('\u{2c76}', '\u{2c75}'), ('\u{2c81}', '\u{2c80}'), ('\u{2c83}', '\u{2c82}'), + ('\u{2c85}', '\u{2c84}'), ('\u{2c87}', '\u{2c86}'), ('\u{2c89}', '\u{2c88}'), + ('\u{2c8b}', '\u{2c8a}'), ('\u{2c8d}', '\u{2c8c}'), ('\u{2c8f}', '\u{2c8e}'), + ('\u{2c91}', '\u{2c90}'), ('\u{2c93}', '\u{2c92}'), ('\u{2c95}', '\u{2c94}'), + ('\u{2c97}', '\u{2c96}'), ('\u{2c99}', '\u{2c98}'), ('\u{2c9b}', '\u{2c9a}'), + ('\u{2c9d}', '\u{2c9c}'), ('\u{2c9f}', '\u{2c9e}'), ('\u{2ca1}', '\u{2ca0}'), + ('\u{2ca3}', '\u{2ca2}'), ('\u{2ca5}', '\u{2ca4}'), ('\u{2ca7}', '\u{2ca6}'), + ('\u{2ca9}', '\u{2ca8}'), ('\u{2cab}', '\u{2caa}'), ('\u{2cad}', '\u{2cac}'), + ('\u{2caf}', '\u{2cae}'), ('\u{2cb1}', '\u{2cb0}'), ('\u{2cb3}', '\u{2cb2}'), + ('\u{2cb5}', '\u{2cb4}'), ('\u{2cb7}', '\u{2cb6}'), ('\u{2cb9}', '\u{2cb8}'), + ('\u{2cbb}', '\u{2cba}'), ('\u{2cbd}', '\u{2cbc}'), ('\u{2cbf}', '\u{2cbe}'), + ('\u{2cc1}', '\u{2cc0}'), ('\u{2cc3}', '\u{2cc2}'), ('\u{2cc5}', '\u{2cc4}'), + ('\u{2cc7}', '\u{2cc6}'), ('\u{2cc9}', '\u{2cc8}'), ('\u{2ccb}', '\u{2cca}'), + ('\u{2ccd}', '\u{2ccc}'), ('\u{2ccf}', '\u{2cce}'), ('\u{2cd1}', '\u{2cd0}'), + ('\u{2cd3}', '\u{2cd2}'), ('\u{2cd5}', '\u{2cd4}'), ('\u{2cd7}', '\u{2cd6}'), + ('\u{2cd9}', '\u{2cd8}'), ('\u{2cdb}', '\u{2cda}'), ('\u{2cdd}', '\u{2cdc}'), + ('\u{2cdf}', '\u{2cde}'), ('\u{2ce1}', '\u{2ce0}'), ('\u{2ce3}', '\u{2ce2}'), + ('\u{2cec}', '\u{2ceb}'), ('\u{2cee}', '\u{2ced}'), ('\u{2cf3}', '\u{2cf2}'), + ('\u{2d00}', '\u{10a0}'), ('\u{2d01}', '\u{10a1}'), ('\u{2d02}', '\u{10a2}'), + ('\u{2d03}', '\u{10a3}'), ('\u{2d04}', '\u{10a4}'), ('\u{2d05}', '\u{10a5}'), + ('\u{2d06}', '\u{10a6}'), ('\u{2d07}', '\u{10a7}'), ('\u{2d08}', '\u{10a8}'), + ('\u{2d09}', '\u{10a9}'), ('\u{2d0a}', '\u{10aa}'), ('\u{2d0b}', '\u{10ab}'), + ('\u{2d0c}', '\u{10ac}'), ('\u{2d0d}', '\u{10ad}'), ('\u{2d0e}', '\u{10ae}'), + ('\u{2d0f}', '\u{10af}'), ('\u{2d10}', '\u{10b0}'), ('\u{2d11}', '\u{10b1}'), + ('\u{2d12}', '\u{10b2}'), ('\u{2d13}', '\u{10b3}'), ('\u{2d14}', '\u{10b4}'), + ('\u{2d15}', '\u{10b5}'), ('\u{2d16}', '\u{10b6}'), ('\u{2d17}', '\u{10b7}'), + ('\u{2d18}', '\u{10b8}'), ('\u{2d19}', '\u{10b9}'), ('\u{2d1a}', '\u{10ba}'), + ('\u{2d1b}', '\u{10bb}'), ('\u{2d1c}', '\u{10bc}'), ('\u{2d1d}', '\u{10bd}'), + ('\u{2d1e}', '\u{10be}'), ('\u{2d1f}', '\u{10bf}'), ('\u{2d20}', '\u{10c0}'), + ('\u{2d21}', '\u{10c1}'), ('\u{2d22}', '\u{10c2}'), ('\u{2d23}', '\u{10c3}'), + ('\u{2d24}', '\u{10c4}'), ('\u{2d25}', '\u{10c5}'), ('\u{2d27}', '\u{10c7}'), + ('\u{2d2d}', '\u{10cd}'), ('\u{a641}', '\u{a640}'), ('\u{a643}', '\u{a642}'), + ('\u{a645}', '\u{a644}'), ('\u{a647}', '\u{a646}'), ('\u{a649}', '\u{a648}'), + ('\u{a64b}', '\u{a64a}'), ('\u{a64d}', '\u{a64c}'), ('\u{a64f}', '\u{a64e}'), + ('\u{a651}', '\u{a650}'), ('\u{a653}', '\u{a652}'), ('\u{a655}', '\u{a654}'), + ('\u{a657}', '\u{a656}'), ('\u{a659}', '\u{a658}'), ('\u{a65b}', '\u{a65a}'), + ('\u{a65d}', '\u{a65c}'), ('\u{a65f}', '\u{a65e}'), ('\u{a661}', '\u{a660}'), + ('\u{a663}', '\u{a662}'), ('\u{a665}', '\u{a664}'), ('\u{a667}', '\u{a666}'), + ('\u{a669}', '\u{a668}'), ('\u{a66b}', '\u{a66a}'), ('\u{a66d}', '\u{a66c}'), + ('\u{a681}', '\u{a680}'), ('\u{a683}', '\u{a682}'), ('\u{a685}', '\u{a684}'), + ('\u{a687}', '\u{a686}'), ('\u{a689}', '\u{a688}'), ('\u{a68b}', '\u{a68a}'), + ('\u{a68d}', '\u{a68c}'), ('\u{a68f}', '\u{a68e}'), ('\u{a691}', '\u{a690}'), + ('\u{a693}', '\u{a692}'), ('\u{a695}', '\u{a694}'), ('\u{a697}', '\u{a696}'), + ('\u{a699}', '\u{a698}'), ('\u{a69b}', '\u{a69a}'), ('\u{a723}', '\u{a722}'), + ('\u{a725}', '\u{a724}'), ('\u{a727}', '\u{a726}'), ('\u{a729}', '\u{a728}'), + ('\u{a72b}', '\u{a72a}'), ('\u{a72d}', '\u{a72c}'), ('\u{a72f}', '\u{a72e}'), + ('\u{a733}', '\u{a732}'), ('\u{a735}', '\u{a734}'), ('\u{a737}', '\u{a736}'), + ('\u{a739}', '\u{a738}'), ('\u{a73b}', '\u{a73a}'), ('\u{a73d}', '\u{a73c}'), + ('\u{a73f}', '\u{a73e}'), ('\u{a741}', '\u{a740}'), ('\u{a743}', '\u{a742}'), + ('\u{a745}', '\u{a744}'), ('\u{a747}', '\u{a746}'), ('\u{a749}', '\u{a748}'), + ('\u{a74b}', '\u{a74a}'), ('\u{a74d}', '\u{a74c}'), ('\u{a74f}', '\u{a74e}'), + ('\u{a751}', '\u{a750}'), ('\u{a753}', '\u{a752}'), ('\u{a755}', '\u{a754}'), + ('\u{a757}', '\u{a756}'), ('\u{a759}', '\u{a758}'), ('\u{a75b}', '\u{a75a}'), + ('\u{a75d}', '\u{a75c}'), ('\u{a75f}', '\u{a75e}'), ('\u{a761}', '\u{a760}'), + ('\u{a763}', '\u{a762}'), ('\u{a765}', '\u{a764}'), ('\u{a767}', '\u{a766}'), + ('\u{a769}', '\u{a768}'), ('\u{a76b}', '\u{a76a}'), ('\u{a76d}', '\u{a76c}'), + ('\u{a76f}', '\u{a76e}'), ('\u{a77a}', '\u{a779}'), ('\u{a77c}', '\u{a77b}'), + ('\u{a77f}', '\u{a77e}'), ('\u{a781}', '\u{a780}'), ('\u{a783}', '\u{a782}'), + ('\u{a785}', '\u{a784}'), ('\u{a787}', '\u{a786}'), ('\u{a78c}', '\u{a78b}'), + ('\u{a791}', '\u{a790}'), ('\u{a793}', '\u{a792}'), ('\u{a794}', '\u{a7c4}'), + ('\u{a797}', '\u{a796}'), ('\u{a799}', '\u{a798}'), ('\u{a79b}', '\u{a79a}'), + ('\u{a79d}', '\u{a79c}'), ('\u{a79f}', '\u{a79e}'), ('\u{a7a1}', '\u{a7a0}'), + ('\u{a7a3}', '\u{a7a2}'), ('\u{a7a5}', '\u{a7a4}'), ('\u{a7a7}', '\u{a7a6}'), + ('\u{a7a9}', '\u{a7a8}'), ('\u{a7b5}', '\u{a7b4}'), ('\u{a7b7}', '\u{a7b6}'), + ('\u{a7b9}', '\u{a7b8}'), ('\u{a7bb}', '\u{a7ba}'), ('\u{a7bd}', '\u{a7bc}'), + ('\u{a7bf}', '\u{a7be}'), ('\u{a7c1}', '\u{a7c0}'), ('\u{a7c3}', '\u{a7c2}'), + ('\u{a7c8}', '\u{a7c7}'), ('\u{a7ca}', '\u{a7c9}'), ('\u{a7d1}', '\u{a7d0}'), + ('\u{a7d7}', '\u{a7d6}'), ('\u{a7d9}', '\u{a7d8}'), ('\u{a7f6}', '\u{a7f5}'), + ('\u{ab53}', '\u{a7b3}'), ('\u{ab70}', '\u{13a0}'), ('\u{ab71}', '\u{13a1}'), + ('\u{ab72}', '\u{13a2}'), ('\u{ab73}', '\u{13a3}'), ('\u{ab74}', '\u{13a4}'), + ('\u{ab75}', '\u{13a5}'), ('\u{ab76}', '\u{13a6}'), ('\u{ab77}', '\u{13a7}'), + ('\u{ab78}', '\u{13a8}'), ('\u{ab79}', '\u{13a9}'), ('\u{ab7a}', '\u{13aa}'), + ('\u{ab7b}', '\u{13ab}'), ('\u{ab7c}', '\u{13ac}'), ('\u{ab7d}', '\u{13ad}'), + ('\u{ab7e}', '\u{13ae}'), ('\u{ab7f}', '\u{13af}'), ('\u{ab80}', '\u{13b0}'), + ('\u{ab81}', '\u{13b1}'), ('\u{ab82}', '\u{13b2}'), ('\u{ab83}', '\u{13b3}'), + ('\u{ab84}', '\u{13b4}'), ('\u{ab85}', '\u{13b5}'), ('\u{ab86}', '\u{13b6}'), + ('\u{ab87}', '\u{13b7}'), ('\u{ab88}', '\u{13b8}'), ('\u{ab89}', '\u{13b9}'), + ('\u{ab8a}', '\u{13ba}'), ('\u{ab8b}', '\u{13bb}'), ('\u{ab8c}', '\u{13bc}'), + ('\u{ab8d}', '\u{13bd}'), ('\u{ab8e}', '\u{13be}'), ('\u{ab8f}', '\u{13bf}'), + ('\u{ab90}', '\u{13c0}'), ('\u{ab91}', '\u{13c1}'), ('\u{ab92}', '\u{13c2}'), + ('\u{ab93}', '\u{13c3}'), ('\u{ab94}', '\u{13c4}'), ('\u{ab95}', '\u{13c5}'), + ('\u{ab96}', '\u{13c6}'), ('\u{ab97}', '\u{13c7}'), ('\u{ab98}', '\u{13c8}'), + ('\u{ab99}', '\u{13c9}'), ('\u{ab9a}', '\u{13ca}'), ('\u{ab9b}', '\u{13cb}'), + ('\u{ab9c}', '\u{13cc}'), ('\u{ab9d}', '\u{13cd}'), ('\u{ab9e}', '\u{13ce}'), + ('\u{ab9f}', '\u{13cf}'), ('\u{aba0}', '\u{13d0}'), ('\u{aba1}', '\u{13d1}'), + ('\u{aba2}', '\u{13d2}'), ('\u{aba3}', '\u{13d3}'), ('\u{aba4}', '\u{13d4}'), + ('\u{aba5}', '\u{13d5}'), ('\u{aba6}', '\u{13d6}'), ('\u{aba7}', '\u{13d7}'), + ('\u{aba8}', '\u{13d8}'), ('\u{aba9}', '\u{13d9}'), ('\u{abaa}', '\u{13da}'), + ('\u{abab}', '\u{13db}'), ('\u{abac}', '\u{13dc}'), ('\u{abad}', '\u{13dd}'), + ('\u{abae}', '\u{13de}'), ('\u{abaf}', '\u{13df}'), ('\u{abb0}', '\u{13e0}'), + ('\u{abb1}', '\u{13e1}'), ('\u{abb2}', '\u{13e2}'), ('\u{abb3}', '\u{13e3}'), + ('\u{abb4}', '\u{13e4}'), ('\u{abb5}', '\u{13e5}'), ('\u{abb6}', '\u{13e6}'), + ('\u{abb7}', '\u{13e7}'), ('\u{abb8}', '\u{13e8}'), ('\u{abb9}', '\u{13e9}'), + ('\u{abba}', '\u{13ea}'), ('\u{abbb}', '\u{13eb}'), ('\u{abbc}', '\u{13ec}'), + ('\u{abbd}', '\u{13ed}'), ('\u{abbe}', '\u{13ee}'), ('\u{abbf}', '\u{13ef}'), + ('\u{ff41}', '\u{ff21}'), ('\u{ff42}', '\u{ff22}'), ('\u{ff43}', '\u{ff23}'), + ('\u{ff44}', '\u{ff24}'), ('\u{ff45}', '\u{ff25}'), ('\u{ff46}', '\u{ff26}'), + ('\u{ff47}', '\u{ff27}'), ('\u{ff48}', '\u{ff28}'), ('\u{ff49}', '\u{ff29}'), + ('\u{ff4a}', '\u{ff2a}'), ('\u{ff4b}', '\u{ff2b}'), ('\u{ff4c}', '\u{ff2c}'), + ('\u{ff4d}', '\u{ff2d}'), ('\u{ff4e}', '\u{ff2e}'), ('\u{ff4f}', '\u{ff2f}'), + ('\u{ff50}', '\u{ff30}'), ('\u{ff51}', '\u{ff31}'), ('\u{ff52}', '\u{ff32}'), + ('\u{ff53}', '\u{ff33}'), ('\u{ff54}', '\u{ff34}'), ('\u{ff55}', '\u{ff35}'), + ('\u{ff56}', '\u{ff36}'), ('\u{ff57}', '\u{ff37}'), ('\u{ff58}', '\u{ff38}'), + ('\u{ff59}', '\u{ff39}'), ('\u{ff5a}', '\u{ff3a}'), ('\u{10428}', '\u{10400}'), + ('\u{10429}', '\u{10401}'), ('\u{1042a}', '\u{10402}'), ('\u{1042b}', '\u{10403}'), + ('\u{1042c}', '\u{10404}'), ('\u{1042d}', '\u{10405}'), ('\u{1042e}', '\u{10406}'), + ('\u{1042f}', '\u{10407}'), ('\u{10430}', '\u{10408}'), ('\u{10431}', '\u{10409}'), + ('\u{10432}', '\u{1040a}'), ('\u{10433}', '\u{1040b}'), ('\u{10434}', '\u{1040c}'), + ('\u{10435}', '\u{1040d}'), ('\u{10436}', '\u{1040e}'), ('\u{10437}', '\u{1040f}'), + ('\u{10438}', '\u{10410}'), ('\u{10439}', '\u{10411}'), ('\u{1043a}', '\u{10412}'), + ('\u{1043b}', '\u{10413}'), ('\u{1043c}', '\u{10414}'), ('\u{1043d}', '\u{10415}'), + ('\u{1043e}', '\u{10416}'), ('\u{1043f}', '\u{10417}'), ('\u{10440}', '\u{10418}'), + ('\u{10441}', '\u{10419}'), ('\u{10442}', '\u{1041a}'), ('\u{10443}', '\u{1041b}'), + ('\u{10444}', '\u{1041c}'), ('\u{10445}', '\u{1041d}'), ('\u{10446}', '\u{1041e}'), + ('\u{10447}', '\u{1041f}'), ('\u{10448}', '\u{10420}'), ('\u{10449}', '\u{10421}'), + ('\u{1044a}', '\u{10422}'), ('\u{1044b}', '\u{10423}'), ('\u{1044c}', '\u{10424}'), + ('\u{1044d}', '\u{10425}'), ('\u{1044e}', '\u{10426}'), ('\u{1044f}', '\u{10427}'), + ('\u{104d8}', '\u{104b0}'), ('\u{104d9}', '\u{104b1}'), ('\u{104da}', '\u{104b2}'), + ('\u{104db}', '\u{104b3}'), ('\u{104dc}', '\u{104b4}'), ('\u{104dd}', '\u{104b5}'), + ('\u{104de}', '\u{104b6}'), ('\u{104df}', '\u{104b7}'), ('\u{104e0}', '\u{104b8}'), + ('\u{104e1}', '\u{104b9}'), ('\u{104e2}', '\u{104ba}'), ('\u{104e3}', '\u{104bb}'), + ('\u{104e4}', '\u{104bc}'), ('\u{104e5}', '\u{104bd}'), ('\u{104e6}', '\u{104be}'), + ('\u{104e7}', '\u{104bf}'), ('\u{104e8}', '\u{104c0}'), ('\u{104e9}', '\u{104c1}'), + ('\u{104ea}', '\u{104c2}'), ('\u{104eb}', '\u{104c3}'), ('\u{104ec}', '\u{104c4}'), + ('\u{104ed}', '\u{104c5}'), ('\u{104ee}', '\u{104c6}'), ('\u{104ef}', '\u{104c7}'), + ('\u{104f0}', '\u{104c8}'), ('\u{104f1}', '\u{104c9}'), ('\u{104f2}', '\u{104ca}'), + ('\u{104f3}', '\u{104cb}'), ('\u{104f4}', '\u{104cc}'), ('\u{104f5}', '\u{104cd}'), + ('\u{104f6}', '\u{104ce}'), ('\u{104f7}', '\u{104cf}'), ('\u{104f8}', '\u{104d0}'), + ('\u{104f9}', '\u{104d1}'), ('\u{104fa}', '\u{104d2}'), ('\u{104fb}', '\u{104d3}'), + ('\u{10597}', '\u{10570}'), ('\u{10598}', '\u{10571}'), ('\u{10599}', '\u{10572}'), + ('\u{1059a}', '\u{10573}'), ('\u{1059b}', '\u{10574}'), ('\u{1059c}', '\u{10575}'), + ('\u{1059d}', '\u{10576}'), ('\u{1059e}', '\u{10577}'), ('\u{1059f}', '\u{10578}'), + ('\u{105a0}', '\u{10579}'), ('\u{105a1}', '\u{1057a}'), ('\u{105a3}', '\u{1057c}'), + ('\u{105a4}', '\u{1057d}'), ('\u{105a5}', '\u{1057e}'), ('\u{105a6}', '\u{1057f}'), + ('\u{105a7}', '\u{10580}'), ('\u{105a8}', '\u{10581}'), ('\u{105a9}', '\u{10582}'), + ('\u{105aa}', '\u{10583}'), ('\u{105ab}', '\u{10584}'), ('\u{105ac}', '\u{10585}'), + ('\u{105ad}', '\u{10586}'), ('\u{105ae}', '\u{10587}'), ('\u{105af}', '\u{10588}'), + ('\u{105b0}', '\u{10589}'), ('\u{105b1}', '\u{1058a}'), ('\u{105b3}', '\u{1058c}'), + ('\u{105b4}', '\u{1058d}'), ('\u{105b5}', '\u{1058e}'), ('\u{105b6}', '\u{1058f}'), + ('\u{105b7}', '\u{10590}'), ('\u{105b8}', '\u{10591}'), ('\u{105b9}', '\u{10592}'), + ('\u{105bb}', '\u{10594}'), ('\u{105bc}', '\u{10595}'), ('\u{10cc0}', '\u{10c80}'), + ('\u{10cc1}', '\u{10c81}'), ('\u{10cc2}', '\u{10c82}'), ('\u{10cc3}', '\u{10c83}'), + ('\u{10cc4}', '\u{10c84}'), ('\u{10cc5}', '\u{10c85}'), ('\u{10cc6}', '\u{10c86}'), + ('\u{10cc7}', '\u{10c87}'), ('\u{10cc8}', '\u{10c88}'), ('\u{10cc9}', '\u{10c89}'), + ('\u{10cca}', '\u{10c8a}'), ('\u{10ccb}', '\u{10c8b}'), ('\u{10ccc}', '\u{10c8c}'), + ('\u{10ccd}', '\u{10c8d}'), ('\u{10cce}', '\u{10c8e}'), ('\u{10ccf}', '\u{10c8f}'), + ('\u{10cd0}', '\u{10c90}'), ('\u{10cd1}', '\u{10c91}'), ('\u{10cd2}', '\u{10c92}'), + ('\u{10cd3}', '\u{10c93}'), ('\u{10cd4}', '\u{10c94}'), ('\u{10cd5}', '\u{10c95}'), + ('\u{10cd6}', '\u{10c96}'), ('\u{10cd7}', '\u{10c97}'), ('\u{10cd8}', '\u{10c98}'), + ('\u{10cd9}', '\u{10c99}'), ('\u{10cda}', '\u{10c9a}'), ('\u{10cdb}', '\u{10c9b}'), + ('\u{10cdc}', '\u{10c9c}'), ('\u{10cdd}', '\u{10c9d}'), ('\u{10cde}', '\u{10c9e}'), + ('\u{10cdf}', '\u{10c9f}'), ('\u{10ce0}', '\u{10ca0}'), ('\u{10ce1}', '\u{10ca1}'), + ('\u{10ce2}', '\u{10ca2}'), ('\u{10ce3}', '\u{10ca3}'), ('\u{10ce4}', '\u{10ca4}'), + ('\u{10ce5}', '\u{10ca5}'), ('\u{10ce6}', '\u{10ca6}'), ('\u{10ce7}', '\u{10ca7}'), + ('\u{10ce8}', '\u{10ca8}'), ('\u{10ce9}', '\u{10ca9}'), ('\u{10cea}', '\u{10caa}'), + ('\u{10ceb}', '\u{10cab}'), ('\u{10cec}', '\u{10cac}'), ('\u{10ced}', '\u{10cad}'), + ('\u{10cee}', '\u{10cae}'), ('\u{10cef}', '\u{10caf}'), ('\u{10cf0}', '\u{10cb0}'), + ('\u{10cf1}', '\u{10cb1}'), ('\u{10cf2}', '\u{10cb2}'), ('\u{118c0}', '\u{118a0}'), + ('\u{118c1}', '\u{118a1}'), ('\u{118c2}', '\u{118a2}'), ('\u{118c3}', '\u{118a3}'), + ('\u{118c4}', '\u{118a4}'), ('\u{118c5}', '\u{118a5}'), ('\u{118c6}', '\u{118a6}'), + ('\u{118c7}', '\u{118a7}'), ('\u{118c8}', '\u{118a8}'), ('\u{118c9}', '\u{118a9}'), + ('\u{118ca}', '\u{118aa}'), ('\u{118cb}', '\u{118ab}'), ('\u{118cc}', '\u{118ac}'), + ('\u{118cd}', '\u{118ad}'), ('\u{118ce}', '\u{118ae}'), ('\u{118cf}', '\u{118af}'), + ('\u{118d0}', '\u{118b0}'), ('\u{118d1}', '\u{118b1}'), ('\u{118d2}', '\u{118b2}'), + ('\u{118d3}', '\u{118b3}'), ('\u{118d4}', '\u{118b4}'), ('\u{118d5}', '\u{118b5}'), + ('\u{118d6}', '\u{118b6}'), ('\u{118d7}', '\u{118b7}'), ('\u{118d8}', '\u{118b8}'), + ('\u{118d9}', '\u{118b9}'), ('\u{118da}', '\u{118ba}'), ('\u{118db}', '\u{118bb}'), + ('\u{118dc}', '\u{118bc}'), ('\u{118dd}', '\u{118bd}'), ('\u{118de}', '\u{118be}'), + ('\u{118df}', '\u{118bf}'), ('\u{16e60}', '\u{16e40}'), ('\u{16e61}', '\u{16e41}'), + ('\u{16e62}', '\u{16e42}'), ('\u{16e63}', '\u{16e43}'), ('\u{16e64}', '\u{16e44}'), + ('\u{16e65}', '\u{16e45}'), ('\u{16e66}', '\u{16e46}'), ('\u{16e67}', '\u{16e47}'), + ('\u{16e68}', '\u{16e48}'), ('\u{16e69}', '\u{16e49}'), ('\u{16e6a}', '\u{16e4a}'), + ('\u{16e6b}', '\u{16e4b}'), ('\u{16e6c}', '\u{16e4c}'), ('\u{16e6d}', '\u{16e4d}'), + ('\u{16e6e}', '\u{16e4e}'), ('\u{16e6f}', '\u{16e4f}'), ('\u{16e70}', '\u{16e50}'), + ('\u{16e71}', '\u{16e51}'), ('\u{16e72}', '\u{16e52}'), ('\u{16e73}', '\u{16e53}'), + ('\u{16e74}', '\u{16e54}'), ('\u{16e75}', '\u{16e55}'), ('\u{16e76}', '\u{16e56}'), + ('\u{16e77}', '\u{16e57}'), ('\u{16e78}', '\u{16e58}'), ('\u{16e79}', '\u{16e59}'), + ('\u{16e7a}', '\u{16e5a}'), ('\u{16e7b}', '\u{16e5b}'), ('\u{16e7c}', '\u{16e5c}'), + ('\u{16e7d}', '\u{16e5d}'), ('\u{16e7e}', '\u{16e5e}'), ('\u{16e7f}', '\u{16e5f}'), + ('\u{1e922}', '\u{1e900}'), ('\u{1e923}', '\u{1e901}'), ('\u{1e924}', '\u{1e902}'), + ('\u{1e925}', '\u{1e903}'), ('\u{1e926}', '\u{1e904}'), ('\u{1e927}', '\u{1e905}'), + ('\u{1e928}', '\u{1e906}'), ('\u{1e929}', '\u{1e907}'), ('\u{1e92a}', '\u{1e908}'), + ('\u{1e92b}', '\u{1e909}'), ('\u{1e92c}', '\u{1e90a}'), ('\u{1e92d}', '\u{1e90b}'), + ('\u{1e92e}', '\u{1e90c}'), ('\u{1e92f}', '\u{1e90d}'), ('\u{1e930}', '\u{1e90e}'), + ('\u{1e931}', '\u{1e90f}'), ('\u{1e932}', '\u{1e910}'), ('\u{1e933}', '\u{1e911}'), + ('\u{1e934}', '\u{1e912}'), ('\u{1e935}', '\u{1e913}'), ('\u{1e936}', '\u{1e914}'), + ('\u{1e937}', '\u{1e915}'), ('\u{1e938}', '\u{1e916}'), ('\u{1e939}', '\u{1e917}'), + ('\u{1e93a}', '\u{1e918}'), ('\u{1e93b}', '\u{1e919}'), ('\u{1e93c}', '\u{1e91a}'), + ('\u{1e93d}', '\u{1e91b}'), ('\u{1e93e}', '\u{1e91c}'), ('\u{1e93f}', '\u{1e91d}'), + ('\u{1e940}', '\u{1e91e}'), ('\u{1e941}', '\u{1e91f}'), ('\u{1e942}', '\u{1e920}'), + ('\u{1e943}', '\u{1e921}'), + ]; + + static UPPERCASE_TABLE_MULTI: &[(char, [char; 3])] = &[ + ('\u{df}', ['S', 'S', '\u{0}']), ('\u{149}', ['\u{2bc}', 'N', '\u{0}']), + ('\u{1f0}', ['J', '\u{30c}', '\u{0}']), ('\u{390}', ['\u{399}', '\u{308}', '\u{301}']), + ('\u{3b0}', ['\u{3a5}', '\u{308}', '\u{301}']), + ('\u{587}', ['\u{535}', '\u{552}', '\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{1f50}', ['\u{3a5}', '\u{313}', '\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}']), @@ -1861,28 +1610,25 @@ pub mod conversions { ('\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{1fbc}', ['\u{391}', '\u{399}', '\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{1fcc}', ['\u{397}', '\u{399}', '\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{1fe4}', ['\u{3a1}', '\u{313}', '\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}']), @@ -1890,199 +1636,7 @@ pub mod conversions { ('\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{2c5f}', ['\u{2c2f}', '\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{a7c1}', ['\u{a7c0}', '\u{0}', '\u{0}']), ('\u{a7c3}', ['\u{a7c2}', '\u{0}', '\u{0}']), - ('\u{a7c8}', ['\u{a7c7}', '\u{0}', '\u{0}']), ('\u{a7ca}', ['\u{a7c9}', '\u{0}', '\u{0}']), - ('\u{a7d1}', ['\u{a7d0}', '\u{0}', '\u{0}']), ('\u{a7d7}', ['\u{a7d6}', '\u{0}', '\u{0}']), - ('\u{a7d9}', ['\u{a7d8}', '\u{0}', '\u{0}']), ('\u{a7f6}', ['\u{a7f5}', '\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{1ffc}', ['\u{3a9}', '\u{399}', '\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}']), @@ -2090,279 +1644,6 @@ pub mod conversions { ('\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{10597}', ['\u{10570}', '\u{0}', '\u{0}']), - ('\u{10598}', ['\u{10571}', '\u{0}', '\u{0}']), - ('\u{10599}', ['\u{10572}', '\u{0}', '\u{0}']), - ('\u{1059a}', ['\u{10573}', '\u{0}', '\u{0}']), - ('\u{1059b}', ['\u{10574}', '\u{0}', '\u{0}']), - ('\u{1059c}', ['\u{10575}', '\u{0}', '\u{0}']), - ('\u{1059d}', ['\u{10576}', '\u{0}', '\u{0}']), - ('\u{1059e}', ['\u{10577}', '\u{0}', '\u{0}']), - ('\u{1059f}', ['\u{10578}', '\u{0}', '\u{0}']), - ('\u{105a0}', ['\u{10579}', '\u{0}', '\u{0}']), - ('\u{105a1}', ['\u{1057a}', '\u{0}', '\u{0}']), - ('\u{105a3}', ['\u{1057c}', '\u{0}', '\u{0}']), - ('\u{105a4}', ['\u{1057d}', '\u{0}', '\u{0}']), - ('\u{105a5}', ['\u{1057e}', '\u{0}', '\u{0}']), - ('\u{105a6}', ['\u{1057f}', '\u{0}', '\u{0}']), - ('\u{105a7}', ['\u{10580}', '\u{0}', '\u{0}']), - ('\u{105a8}', ['\u{10581}', '\u{0}', '\u{0}']), - ('\u{105a9}', ['\u{10582}', '\u{0}', '\u{0}']), - ('\u{105aa}', ['\u{10583}', '\u{0}', '\u{0}']), - ('\u{105ab}', ['\u{10584}', '\u{0}', '\u{0}']), - ('\u{105ac}', ['\u{10585}', '\u{0}', '\u{0}']), - ('\u{105ad}', ['\u{10586}', '\u{0}', '\u{0}']), - ('\u{105ae}', ['\u{10587}', '\u{0}', '\u{0}']), - ('\u{105af}', ['\u{10588}', '\u{0}', '\u{0}']), - ('\u{105b0}', ['\u{10589}', '\u{0}', '\u{0}']), - ('\u{105b1}', ['\u{1058a}', '\u{0}', '\u{0}']), - ('\u{105b3}', ['\u{1058c}', '\u{0}', '\u{0}']), - ('\u{105b4}', ['\u{1058d}', '\u{0}', '\u{0}']), - ('\u{105b5}', ['\u{1058e}', '\u{0}', '\u{0}']), - ('\u{105b6}', ['\u{1058f}', '\u{0}', '\u{0}']), - ('\u{105b7}', ['\u{10590}', '\u{0}', '\u{0}']), - ('\u{105b8}', ['\u{10591}', '\u{0}', '\u{0}']), - ('\u{105b9}', ['\u{10592}', '\u{0}', '\u{0}']), - ('\u{105bb}', ['\u{10594}', '\u{0}', '\u{0}']), - ('\u{105bc}', ['\u{10595}', '\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}']), + ('\u{fb17}', ['\u{544}', '\u{53d}', '\u{0}']), ]; } diff --git a/src/tools/unicode-table-generator/src/case_mapping.rs b/src/tools/unicode-table-generator/src/case_mapping.rs index b8153a71118..23ad93925ba 100644 --- a/src/tools/unicode-table-generator/src/case_mapping.rs +++ b/src/tools/unicode-table-generator/src/case_mapping.rs @@ -1,22 +1,47 @@ use crate::{fmt_list, UnicodeData}; -use std::{collections::BTreeMap, fmt}; +use std::{ + collections::BTreeMap, + fmt::{self, Write}, +}; pub(crate) fn generate_case_mapping(data: &UnicodeData) -> String { let mut file = String::new(); file.push_str(HEADER.trim_start()); - file.push_str(&generate_table("LOWER", &data.to_lower)); + file.push_str(&generate_tables("LOWER", &data.to_lower)); file.push_str("\n\n"); - file.push_str(&generate_table("UPPER", &data.to_upper)); + file.push_str(&generate_tables("UPPER", &data.to_upper)); file } -fn generate_table(case: &str, data: &BTreeMap) -> String { - format!( - "static {}CASE_TABLE: &[(char, [char; 3])] = &[{}];", +fn generate_tables(case: &str, data: &BTreeMap) -> String { + let (single, multi): (Vec<_>, Vec<_>) = data + .iter() + .map(to_mapping) + .filter(|(k, _)| !k.0.is_ascii()) + .partition(|(_, [_, s, t])| s.0 == '\0' && t.0 == '\0'); + + let mut tables = String::new(); + + write!( + tables, + "static {}CASE_TABLE_SINGLE: &[(char, char)] = &[{}];", case, - fmt_list(data.iter().map(to_mapping).filter(|(k, _)| !k.0.is_ascii())) + fmt_list(single.into_iter().map(|(k, [v, _, _])| (k, v))) ) + .unwrap(); + + tables.push_str("\n\n"); + + write!( + tables, + "static {}CASE_TABLE_MULTI: &[(char, [char; 3])] = &[{}];", + case, + fmt_list(multi) + ) + .unwrap(); + + tables } fn to_mapping((key, (a, b, c)): (&u32, &(u32, u32, u32))) -> (CharEscape, [CharEscape; 3]) { @@ -43,9 +68,9 @@ pub fn to_lower(c: char) -> [char; 3] { if c.is_ascii() { [(c as u8).to_ascii_lowercase() as char, '\0', '\0'] } else { - match bsearch_case_table(c, LOWERCASE_TABLE) { + match bsearch_case_tables(c, LOWERCASE_TABLE_SINGLE, LOWERCASE_TABLE_MULTI) { + Some(replacement) => replacement, None => [c, '\0', '\0'], - Some(index) => LOWERCASE_TABLE[index].1, } } } @@ -54,14 +79,21 @@ pub fn to_upper(c: char) -> [char; 3] { if c.is_ascii() { [(c as u8).to_ascii_uppercase() as char, '\0', '\0'] } else { - match bsearch_case_table(c, UPPERCASE_TABLE) { + match bsearch_case_tables(c, UPPERCASE_TABLE_SINGLE, UPPERCASE_TABLE_MULTI) { + Some(replacement) => replacement, 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() +fn bsearch_case_tables( + c: char, + single: &[(char, char)], + multi: &[(char, [char; 3])], +) -> Option<[char; 3]> { + match single.binary_search_by(|&(key, _)| key.cmp(&c)) { + Ok(i) => Some([single[i].1, '\0', '\0']), + Err(_) => multi.binary_search_by(|&(key, _)| key.cmp(&c)).map(|i| multi[i].1).ok(), + } } "; From 30331828cb9e694b59c9325dce7c1f25dac3e80e Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 16 Mar 2023 14:56:02 +0100 Subject: [PATCH 052/346] Use poison instead of undef In cases where it is legal, we should prefer poison values over undef values. This replaces undef with poison for aggregate construction and for uninhabited types. There are more places where we can likely use poison, but I wanted to stay conservative to start with. In particular the aggregate case is important for newer LLVM versions, which are not able to handle an undef base value during early optimization due to poison-propagation concerns. --- compiler/rustc_codegen_gcc/src/common.rs | 5 +++++ compiler/rustc_codegen_llvm/src/builder.rs | 2 +- compiler/rustc_codegen_llvm/src/common.rs | 4 ++++ compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 1 + compiler/rustc_codegen_ssa/src/mir/operand.rs | 4 ++-- compiler/rustc_codegen_ssa/src/mir/place.rs | 2 +- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 2 +- compiler/rustc_codegen_ssa/src/traits/consts.rs | 1 + tests/codegen/adjustments.rs | 2 +- 9 files changed, 17 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/common.rs b/compiler/rustc_codegen_gcc/src/common.rs index 76fc7bd222e..ac04b61a306 100644 --- a/compiler/rustc_codegen_gcc/src/common.rs +++ b/compiler/rustc_codegen_gcc/src/common.rs @@ -73,6 +73,11 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> { } } + fn const_poison(&self, typ: Type<'gcc>) -> RValue<'gcc> { + // No distinction between undef and poison. + self.const_undef(typ) + } + fn const_int(&self, typ: Type<'gcc>, int: i64) -> RValue<'gcc> { self.gcc_int(typ, int) } diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 0f33b985489..580451ba265 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -990,7 +990,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { fn resume(&mut self, exn0: &'ll Value, exn1: &'ll Value) { let ty = self.type_struct(&[self.type_i8p(), self.type_i32()], false); - let mut exn = self.const_undef(ty); + let mut exn = self.const_poison(ty); exn = self.insert_value(exn, exn0, 0); exn = self.insert_value(exn, exn1, 1); unsafe { diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index b0a9a30ab46..efa0c13226e 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -130,6 +130,10 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { unsafe { llvm::LLVMGetUndef(t) } } + fn const_poison(&self, t: &'ll Type) -> &'ll Value { + unsafe { llvm::LLVMGetPoison(t) } + } + fn const_int(&self, t: &'ll Type, i: i64) -> &'ll Value { unsafe { llvm::LLVMConstInt(t, i as u64, True) } } diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 509cb0fef56..9e5265188b5 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -1069,6 +1069,7 @@ extern "C" { // Operations on constants of any type pub fn LLVMConstNull(Ty: &Type) -> &Value; pub fn LLVMGetUndef(Ty: &Type) -> &Value; + pub fn LLVMGetPoison(Ty: &Type) -> &Value; // Operations on metadata pub fn LLVMMDStringInContext(C: &Context, Str: *const c_char, SLen: c_uint) -> &Value; diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 34a5b638d7e..25721f75583 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -60,7 +60,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { ) -> OperandRef<'tcx, V> { assert!(layout.is_zst()); OperandRef { - val: OperandValue::Immediate(bx.const_undef(bx.immediate_backend_type(layout))), + val: OperandValue::Immediate(bx.const_poison(bx.immediate_backend_type(layout))), layout, } } @@ -145,7 +145,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> { let llty = bx.cx().backend_type(self.layout); debug!("Operand::immediate_or_packed_pair: packing {:?} into {:?}", self, llty); // Reconstruct the immediate aggregate. - let mut llpair = bx.cx().const_undef(llty); + let mut llpair = bx.cx().const_poison(llty); let imm_a = bx.from_immediate(a); let imm_b = bx.from_immediate(b); llpair = bx.insert_value(llpair, imm_a, 0); diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index cf02f59f67b..f6523a448e3 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -214,7 +214,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { let cast_to_size = cast_to_layout.layout.size(); let cast_to = bx.cx().immediate_backend_type(cast_to_layout); if self.layout.abi.is_uninhabited() { - return bx.cx().const_undef(cast_to); + return bx.cx().const_poison(cast_to); } let (tag_scalar, tag_encoding, tag_field) = match self.layout.variants { Variants::Single { index } => { diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 13c4fa132d8..74b9ff7eace 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -295,7 +295,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { assert!(bx.cx().is_backend_immediate(cast)); let ll_t_out = bx.cx().immediate_backend_type(cast); if operand.layout.abi.is_uninhabited() { - let val = OperandValue::Immediate(bx.cx().const_undef(ll_t_out)); + let val = OperandValue::Immediate(bx.cx().const_poison(ll_t_out)); return OperandRef { val, layout: cast }; } let r_t_in = diff --git a/compiler/rustc_codegen_ssa/src/traits/consts.rs b/compiler/rustc_codegen_ssa/src/traits/consts.rs index fdc7a30e841..61906302779 100644 --- a/compiler/rustc_codegen_ssa/src/traits/consts.rs +++ b/compiler/rustc_codegen_ssa/src/traits/consts.rs @@ -8,6 +8,7 @@ pub trait ConstMethods<'tcx>: BackendTypes { // Constant constructors fn const_null(&self, t: Self::Type) -> Self::Value; fn const_undef(&self, t: Self::Type) -> Self::Value; + fn const_poison(&self, t: Self::Type) -> Self::Value; fn const_int(&self, t: Self::Type, i: i64) -> Self::Value; fn const_uint(&self, t: Self::Type, i: u64) -> Self::Value; fn const_uint_big(&self, t: Self::Type, u: u128) -> Self::Value; diff --git a/tests/codegen/adjustments.rs b/tests/codegen/adjustments.rs index 6d224751752..b53a68a5588 100644 --- a/tests/codegen/adjustments.rs +++ b/tests/codegen/adjustments.rs @@ -13,7 +13,7 @@ pub fn helper(_: usize) { pub fn no_op_slice_adjustment(x: &[u8]) -> &[u8] { // We used to generate an extra alloca and memcpy for the block's trailing expression value, so // check that we copy directly to the return value slot -// CHECK: %0 = insertvalue { {{\[0 x i8\]\*|ptr}}, [[USIZE]] } undef, {{\[0 x i8\]\*|ptr}} %x.0, 0 +// CHECK: %0 = insertvalue { {{\[0 x i8\]\*|ptr}}, [[USIZE]] } poison, {{\[0 x i8\]\*|ptr}} %x.0, 0 // CHECK: %1 = insertvalue { {{\[0 x i8\]\*|ptr}}, [[USIZE]] } %0, [[USIZE]] %x.1, 1 // CHECK: ret { {{\[0 x i8\]\*|ptr}}, [[USIZE]] } %1 { x } From 6fe982283d70a9c6ab621093716ef616ce26e0b3 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 16 Mar 2023 14:53:57 +0000 Subject: [PATCH 053/346] Remove `DefId` from `CrateItem` in favor of a lookup table --- compiler/rustc_smir/src/rustc_internal/mod.rs | 19 ++++++++++++++++++- compiler/rustc_smir/src/rustc_smir/mod.rs | 9 +++++---- compiler/rustc_smir/src/stable_mir/mod.rs | 4 +--- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index 3eaff9c051f..5998c8b6500 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -3,11 +3,28 @@ //! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs //! until stable MIR is complete. +use std::sync::RwLock; + use crate::stable_mir; pub use rustc_span::def_id::{CrateNum, DefId}; +static DEF_ID_MAP: RwLock> = RwLock::new(Vec::new()); + pub fn item_def_id(item: &stable_mir::CrateItem) -> DefId { - item.0 + DEF_ID_MAP.read().unwrap()[item.0] +} + +pub fn crate_item(did: DefId) -> stable_mir::CrateItem { + // FIXME: this becomes inefficient when we have too many ids + let mut map = DEF_ID_MAP.write().unwrap(); + for (i, &d) in map.iter().enumerate() { + if d == did { + return stable_mir::CrateItem(i); + } + } + let id = map.len(); + map.push(did); + stable_mir::CrateItem(id) } pub fn crate_num(item: &stable_mir::Crate) -> CrateNum { diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index d956f0ac802..c17dab6dce0 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -7,7 +7,10 @@ //! //! For now, we are developing everything inside `rustc`, thus, we keep this module private. -use crate::stable_mir::{self}; +use crate::{ + rustc_internal::crate_item, + stable_mir::{self}, +}; use rustc_middle::ty::{tls::with, TyCtxt}; use rustc_span::def_id::{CrateNum, LOCAL_CRATE}; use tracing::debug; @@ -34,9 +37,7 @@ pub fn find_crate(name: &str) -> Option { /// Retrieve all items of the local crate that have a MIR associated with them. pub fn all_local_items() -> stable_mir::CrateItems { - with(|tcx| { - tcx.mir_keys(()).iter().map(|item| stable_mir::CrateItem(item.to_def_id())).collect() - }) + with(|tcx| tcx.mir_keys(()).iter().map(|item| crate_item(item.to_def_id())).collect()) } /// Build a stable mir crate from a given crate number. diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/rustc_smir/src/stable_mir/mod.rs index cbf52e691fb..6b3ab620e2d 100644 --- a/compiler/rustc_smir/src/stable_mir/mod.rs +++ b/compiler/rustc_smir/src/stable_mir/mod.rs @@ -11,8 +11,6 @@ //! There shouldn't be any direct references to internal compiler constructs in this module. //! If you need an internal construct, consider using `rustc_internal` or `rustc_smir`. -use crate::rustc_internal; - /// Use String for now but we should replace it. pub type Symbol = String; @@ -37,7 +35,7 @@ pub struct Crate { /// For now, it only stores the item DefId. Use functions inside `rustc_internal` module to /// use this item. #[derive(Clone, PartialEq, Eq, Debug)] -pub struct CrateItem(pub(crate) rustc_internal::DefId); +pub struct CrateItem(pub(crate) DefId); /// Access to the local crate. pub fn local_crate() -> Crate { From 942cac1b8d9b9fa6a5ba372aaff815f565f302d0 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 16 Mar 2023 16:06:12 +0000 Subject: [PATCH 054/346] Implement a minimal subset of MIR statements and terminators for smir --- compiler/rustc_smir/src/rustc_smir/mod.rs | 111 +++++++++++++++++- compiler/rustc_smir/src/stable_mir/mir.rs | 3 + .../rustc_smir/src/stable_mir/mir/body.rs | 62 ++++++++++ compiler/rustc_smir/src/stable_mir/mod.rs | 8 ++ tests/ui-fulldeps/stable-mir/crate-info.rs | 30 ++++- 5 files changed, 209 insertions(+), 5 deletions(-) create mode 100644 compiler/rustc_smir/src/stable_mir/mir.rs create mode 100644 compiler/rustc_smir/src/stable_mir/mir/body.rs diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index c17dab6dce0..86e30dd0f6a 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -8,7 +8,7 @@ //! For now, we are developing everything inside `rustc`, thus, we keep this module private. use crate::{ - rustc_internal::crate_item, + rustc_internal::{crate_item, item_def_id}, stable_mir::{self}, }; use rustc_middle::ty::{tls::with, TyCtxt}; @@ -47,3 +47,112 @@ fn smir_crate(tcx: TyCtxt<'_>, crate_num: CrateNum) -> stable_mir::Crate { debug!(?crate_name, ?crate_num, "smir_crate"); stable_mir::Crate { id: crate_num.into(), name: crate_name, is_local } } + +pub fn mir_body(item: &stable_mir::CrateItem) -> stable_mir::mir::Body { + with(|tcx| { + let def_id = item_def_id(item); + let mir = tcx.optimized_mir(def_id); + stable_mir::mir::Body { + blocks: mir + .basic_blocks + .iter() + .map(|block| stable_mir::mir::BasicBlock { + terminator: rustc_terminator_to_terminator(block.terminator()), + statements: block.statements.iter().map(rustc_statement_to_statement).collect(), + }) + .collect(), + } + }) +} + +fn rustc_statement_to_statement( + s: &rustc_middle::mir::Statement<'_>, +) -> stable_mir::mir::Statement { + use rustc_middle::mir::StatementKind::*; + match &s.kind { + Assign(assign) => stable_mir::mir::Statement::Assign( + rustc_place_to_place(&assign.0), + rustc_rvalue_to_rvalue(&assign.1), + ), + FakeRead(_) => todo!(), + SetDiscriminant { .. } => todo!(), + Deinit(_) => todo!(), + StorageLive(_) => todo!(), + StorageDead(_) => todo!(), + Retag(_, _) => todo!(), + PlaceMention(_) => todo!(), + AscribeUserType(_, _) => todo!(), + Coverage(_) => todo!(), + Intrinsic(_) => todo!(), + ConstEvalCounter => todo!(), + Nop => stable_mir::mir::Statement::Nop, + } +} + +fn rustc_rvalue_to_rvalue(rvalue: &rustc_middle::mir::Rvalue<'_>) -> stable_mir::mir::Operand { + use rustc_middle::mir::Rvalue::*; + match rvalue { + Use(op) => rustc_op_to_op(op), + Repeat(_, _) => todo!(), + Ref(_, _, _) => todo!(), + ThreadLocalRef(_) => todo!(), + AddressOf(_, _) => todo!(), + Len(_) => todo!(), + Cast(_, _, _) => todo!(), + BinaryOp(_, _) => todo!(), + CheckedBinaryOp(_, _) => todo!(), + NullaryOp(_, _) => todo!(), + UnaryOp(_, _) => todo!(), + Discriminant(_) => todo!(), + Aggregate(_, _) => todo!(), + ShallowInitBox(_, _) => todo!(), + CopyForDeref(_) => todo!(), + } +} + +fn rustc_op_to_op(op: &rustc_middle::mir::Operand<'_>) -> stable_mir::mir::Operand { + use rustc_middle::mir::Operand::*; + match op { + Copy(place) => stable_mir::mir::Operand::Copy(rustc_place_to_place(place)), + Move(place) => stable_mir::mir::Operand::Move(rustc_place_to_place(place)), + Constant(c) => stable_mir::mir::Operand::Constant(c.to_string()), + } +} + +fn rustc_place_to_place(place: &rustc_middle::mir::Place<'_>) -> stable_mir::mir::Place { + assert_eq!(&place.projection[..], &[]); + stable_mir::mir::Place { local: place.local.as_usize() } +} + +fn rustc_terminator_to_terminator( + terminator: &rustc_middle::mir::Terminator<'_>, +) -> stable_mir::mir::Terminator { + use rustc_middle::mir::TerminatorKind::*; + use stable_mir::mir::Terminator; + match &terminator.kind { + Goto { target } => Terminator::Goto { target: target.as_usize() }, + SwitchInt { discr, targets } => Terminator::SwitchInt { + discr: rustc_op_to_op(discr), + targets: targets + .iter() + .map(|(value, target)| stable_mir::mir::SwitchTarget { + value, + target: target.as_usize(), + }) + .collect(), + otherwise: targets.otherwise().as_usize(), + }, + Resume => Terminator::Resume, + Abort => Terminator::Abort, + Return => Terminator::Return, + Unreachable => Terminator::Unreachable, + Drop { .. } => todo!(), + Call { .. } => todo!(), + Assert { .. } => todo!(), + Yield { .. } => todo!(), + GeneratorDrop => todo!(), + FalseEdge { .. } => todo!(), + FalseUnwind { .. } => todo!(), + InlineAsm { .. } => todo!(), + } +} diff --git a/compiler/rustc_smir/src/stable_mir/mir.rs b/compiler/rustc_smir/src/stable_mir/mir.rs new file mode 100644 index 00000000000..a9dbc3463f8 --- /dev/null +++ b/compiler/rustc_smir/src/stable_mir/mir.rs @@ -0,0 +1,3 @@ +mod body; + +pub use body::*; diff --git a/compiler/rustc_smir/src/stable_mir/mir/body.rs b/compiler/rustc_smir/src/stable_mir/mir/body.rs new file mode 100644 index 00000000000..613141952a7 --- /dev/null +++ b/compiler/rustc_smir/src/stable_mir/mir/body.rs @@ -0,0 +1,62 @@ +pub struct Body { + pub blocks: Vec, +} + +pub struct BasicBlock { + pub statements: Vec, + pub terminator: Terminator, +} + +pub enum Terminator { + Goto { + target: usize, + }, + SwitchInt { + discr: Operand, + targets: Vec, + otherwise: usize, + }, + Resume, + Abort, + Return, + Unreachable, + Drop { + place: Place, + target: usize, + unwind: Option, + }, + Call { + func: Operand, + args: Vec, + destination: Place, + target: Option, + cleanup: Option, + }, + Assert { + cond: Operand, + expected: bool, + msg: String, + target: usize, + cleanup: Option, + }, +} + +pub enum Statement { + Assign(Place, Operand), + Nop, +} + +pub enum Operand { + Copy(Place), + Move(Place), + Constant(String), +} + +pub struct Place { + pub local: usize, +} + +pub struct SwitchTarget { + pub value: u128, + pub target: usize, +} diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/rustc_smir/src/stable_mir/mod.rs index 6b3ab620e2d..ba23186224a 100644 --- a/compiler/rustc_smir/src/stable_mir/mod.rs +++ b/compiler/rustc_smir/src/stable_mir/mod.rs @@ -11,6 +11,8 @@ //! There shouldn't be any direct references to internal compiler constructs in this module. //! If you need an internal construct, consider using `rustc_internal` or `rustc_smir`. +pub mod mir; + /// Use String for now but we should replace it. pub type Symbol = String; @@ -37,6 +39,12 @@ pub struct Crate { #[derive(Clone, PartialEq, Eq, Debug)] pub struct CrateItem(pub(crate) DefId); +impl CrateItem { + pub fn body(&self) -> mir::Body { + crate::rustc_smir::mir_body(self) + } +} + /// Access to the local crate. pub fn local_crate() -> Crate { crate::rustc_smir::local_crate() diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs index 4458ab0162e..95797ddf073 100644 --- a/tests/ui-fulldeps/stable-mir/crate-info.rs +++ b/tests/ui-fulldeps/stable-mir/crate-info.rs @@ -30,16 +30,34 @@ fn test_stable_mir(tcx: TyCtxt<'_>) { // Find items in the local crate. let items = stable_mir::all_local_items(); - assert!(has_item(tcx, &items, (DefKind::Fn, "foo_bar"))); - assert!(has_item(tcx, &items, (DefKind::Fn, "foo::bar"))); + assert!(get_item(tcx, &items, (DefKind::Fn, "foo_bar")).is_some()); + assert!(get_item(tcx, &items, (DefKind::Fn, "foo::bar")).is_some()); // Find the `std` crate. assert!(stable_mir::find_crate("std").is_some()); + + let bar = get_item(tcx, &items, (DefKind::Fn, "bar")).unwrap(); + let body = bar.body(); + assert_eq!(body.blocks.len(), 1); + let block = &body.blocks[0]; + assert_eq!(block.statements.len(), 1); + match &block.statements[0] { + stable_mir::mir::Statement::Assign(..) => {} + _ => panic!(), + } + match &block.terminator { + stable_mir::mir::Terminator::Return => {} + _ => panic!(), + } } // Use internal API to find a function in a crate. -fn has_item(tcx: TyCtxt, items: &stable_mir::CrateItems, item: (DefKind, &str)) -> bool { - items.iter().any(|crate_item| { +fn get_item<'a>( + tcx: TyCtxt, + items: &'a stable_mir::CrateItems, + item: (DefKind, &str), +) -> Option<&'a stable_mir::CrateItem> { + items.iter().find(|crate_item| { let def_id = rustc_internal::item_def_id(crate_item); tcx.def_kind(def_id) == item.0 && tcx.def_path_str(def_id) == item.1 }) @@ -94,6 +112,10 @@ fn generate_input(path: &str) -> std::io::Result<()> { }} }} + pub fn bar(x: i32) -> i32 {{ + x + }} + pub fn foo_bar(x: i32, y: i32) -> i64 {{ let x_64 = foo::bar(x); let y_64 = foo::bar(y); From 480e042097573ad518e43cf2ee8f17ecb755693a Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 16 Mar 2023 16:17:25 +0000 Subject: [PATCH 055/346] Add Debug and Clone derives for stable mir datastructures --- compiler/rustc_smir/src/stable_mir/mir/body.rs | 7 +++++++ tests/ui-fulldeps/stable-mir/crate-info.rs | 5 +++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_smir/src/stable_mir/mir/body.rs b/compiler/rustc_smir/src/stable_mir/mir/body.rs index 613141952a7..c504065c993 100644 --- a/compiler/rustc_smir/src/stable_mir/mir/body.rs +++ b/compiler/rustc_smir/src/stable_mir/mir/body.rs @@ -1,12 +1,15 @@ +#[derive(Clone, Debug)] pub struct Body { pub blocks: Vec, } +#[derive(Clone, Debug)] pub struct BasicBlock { pub statements: Vec, pub terminator: Terminator, } +#[derive(Clone, Debug)] pub enum Terminator { Goto { target: usize, @@ -41,21 +44,25 @@ pub enum Terminator { }, } +#[derive(Clone, Debug)] pub enum Statement { Assign(Place, Operand), Nop, } +#[derive(Clone, Debug)] pub enum Operand { Copy(Place), Move(Place), Constant(String), } +#[derive(Clone, Debug)] pub struct Place { pub local: usize, } +#[derive(Clone, Debug)] pub struct SwitchTarget { pub value: u128, pub target: usize, diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs index 95797ddf073..99b653f20b6 100644 --- a/tests/ui-fulldeps/stable-mir/crate-info.rs +++ b/tests/ui-fulldeps/stable-mir/crate-info.rs @@ -4,6 +4,7 @@ // ignore-stage-1 // ignore-cross-compile // ignore-remote +// edition: 2021 #![feature(rustc_private)] @@ -43,11 +44,11 @@ fn test_stable_mir(tcx: TyCtxt<'_>) { assert_eq!(block.statements.len(), 1); match &block.statements[0] { stable_mir::mir::Statement::Assign(..) => {} - _ => panic!(), + other => panic!("{other:?}"), } match &block.terminator { stable_mir::mir::Terminator::Return => {} - _ => panic!(), + other => panic!("{other:?}"), } } From afe27ba1a2fbf902ecb5bd02590871be5f46f34d Mon Sep 17 00:00:00 2001 From: Samuel Tardieu Date: Sun, 5 Mar 2023 12:38:23 +0100 Subject: [PATCH 056/346] Issue function modifiers in the right order in manual_async_fn lint --- clippy_lints/src/manual_async_fn.rs | 14 +++++++-- tests/ui/manual_async_fn.fixed | 6 ++++ tests/ui/manual_async_fn.rs | 12 ++++++++ tests/ui/manual_async_fn.stderr | 47 ++++++++++++++++++++++++++++- 4 files changed, 75 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/manual_async_fn.rs b/clippy_lints/src/manual_async_fn.rs index 3778eb4c732..af52090d8a4 100644 --- a/clippy_lints/src/manual_async_fn.rs +++ b/clippy_lints/src/manual_async_fn.rs @@ -6,7 +6,7 @@ use rustc_errors::Applicability; use rustc_hir::intravisit::FnKind; use rustc_hir::{ AsyncGeneratorKind, Block, Body, Closure, Expr, ExprKind, FnDecl, FnRetTy, GeneratorKind, GenericArg, GenericBound, - ItemKind, LifetimeName, Term, TraitRef, Ty, TyKind, TypeBindingKind, + ImplItem, Item, ItemKind, LifetimeName, Node, Term, TraitRef, Ty, TyKind, TypeBindingKind, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -46,7 +46,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn { decl: &'tcx FnDecl<'_>, body: &'tcx Body<'_>, span: Span, - _: LocalDefId, + def_id: LocalDefId, ) { if_chain! { if let Some(header) = kind.header(); @@ -60,6 +60,8 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn { if let ExprKind::Block(block, _) = body.value.kind; if block.stmts.is_empty(); if let Some(closure_body) = desugared_async_block(cx, block); + if let Node::Item(Item {vis_span, ..}) | Node::ImplItem(ImplItem {vis_span, ..}) = + cx.tcx.hir().get_by_def_id(def_id); then { let header_span = span.with_hi(ret_ty.span.hi()); @@ -70,15 +72,21 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn { "this function can be simplified using the `async fn` syntax", |diag| { if_chain! { + if let Some(vis_snip) = snippet_opt(cx, *vis_span); if let Some(header_snip) = snippet_opt(cx, header_span); if let Some(ret_pos) = position_before_rarrow(&header_snip); if let Some((ret_sugg, ret_snip)) = suggested_ret(cx, output); then { + let header_snip = if !vis_snip.is_empty() { + format!("{} async {}", vis_snip, &header_snip[vis_snip.len() + 1..ret_pos]) + } else { + format!("async {}", &header_snip[..ret_pos]) + }; let help = format!("make the function `async` and {ret_sugg}"); diag.span_suggestion( header_span, help, - format!("async {}{ret_snip}", &header_snip[..ret_pos]), + format!("{header_snip}{ret_snip}"), Applicability::MachineApplicable ); diff --git a/tests/ui/manual_async_fn.fixed b/tests/ui/manual_async_fn.fixed index b7e46a4a8cc..5cc4a43af7e 100644 --- a/tests/ui/manual_async_fn.fixed +++ b/tests/ui/manual_async_fn.fixed @@ -107,4 +107,10 @@ mod issue_5765 { } } +pub async fn issue_10450() -> i32 { 42 } + +pub(crate) async fn issue_10450_2() -> i32 { 42 } + +pub(self) async fn issue_10450_3() -> i32 { 42 } + fn main() {} diff --git a/tests/ui/manual_async_fn.rs b/tests/ui/manual_async_fn.rs index b05429da662..ba504b8a823 100644 --- a/tests/ui/manual_async_fn.rs +++ b/tests/ui/manual_async_fn.rs @@ -127,4 +127,16 @@ mod issue_5765 { } } +pub fn issue_10450() -> impl Future { + async { 42 } +} + +pub(crate) fn issue_10450_2() -> impl Future { + async { 42 } +} + +pub(self) fn issue_10450_3() -> impl Future { + async { 42 } +} + fn main() {} diff --git a/tests/ui/manual_async_fn.stderr b/tests/ui/manual_async_fn.stderr index 0a903ed6fd4..f5ee3eb7ccc 100644 --- a/tests/ui/manual_async_fn.stderr +++ b/tests/ui/manual_async_fn.stderr @@ -161,5 +161,50 @@ help: move the body of the async block to the enclosing function LL | fn explicit<'a, 'b>(_: &'a i32, _: &'b i32) -> impl Future + 'a + 'b { 42 } | ~~~~~~ -error: aborting due to 10 previous errors +error: this function can be simplified using the `async fn` syntax + --> $DIR/manual_async_fn.rs:130:1 + | +LL | pub fn issue_10450() -> impl Future { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: make the function `async` and return the output of the future directly + | +LL | pub async fn issue_10450() -> i32 { + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +help: move the body of the async block to the enclosing function + | +LL | pub fn issue_10450() -> impl Future { 42 } + | ~~~~~~ + +error: this function can be simplified using the `async fn` syntax + --> $DIR/manual_async_fn.rs:134:1 + | +LL | pub(crate) fn issue_10450_2() -> impl Future { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: make the function `async` and return the output of the future directly + | +LL | pub(crate) async fn issue_10450_2() -> i32 { + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +help: move the body of the async block to the enclosing function + | +LL | pub(crate) fn issue_10450_2() -> impl Future { 42 } + | ~~~~~~ + +error: this function can be simplified using the `async fn` syntax + --> $DIR/manual_async_fn.rs:138:1 + | +LL | pub(self) fn issue_10450_3() -> impl Future { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: make the function `async` and return the output of the future directly + | +LL | pub(self) async fn issue_10450_3() -> i32 { + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +help: move the body of the async block to the enclosing function + | +LL | pub(self) fn issue_10450_3() -> impl Future { 42 } + | ~~~~~~ + +error: aborting due to 13 previous errors From 9546517a842f31be2258a70ae940dd9071e2913a Mon Sep 17 00:00:00 2001 From: blyxyas Date: Thu, 16 Mar 2023 19:48:23 +0100 Subject: [PATCH 057/346] Add external macro test + Now it works --- clippy_lints/src/swap.rs | 5 ++--- tests/ui/auxiliary/macro_rules.rs | 10 +++++++++ tests/ui/swap.fixed | 10 +++------ tests/ui/swap.rs | 10 +++------ tests/ui/swap.stderr | 34 +++++++++++++++---------------- 5 files changed, 35 insertions(+), 34 deletions(-) diff --git a/clippy_lints/src/swap.rs b/clippy_lints/src/swap.rs index 938ca3a6cee..50298898d03 100644 --- a/clippy_lints/src/swap.rs +++ b/clippy_lints/src/swap.rs @@ -76,9 +76,7 @@ declare_lint_pass!(Swap => [MANUAL_SWAP, ALMOST_SWAPPED]); impl<'tcx> LateLintPass<'tcx> for Swap { fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'_>) { check_manual_swap(cx, block); - if !in_external_macro(cx.sess(), block.span) { - check_suspicious_swap(cx, block); - } + check_suspicious_swap(cx, block); check_xor_swap(cx, block); } } @@ -191,6 +189,7 @@ fn check_suspicious_swap(cx: &LateContext<'_>, block: &Block<'_>) { if let Some((lhs0, rhs0)) = parse(first) && let Some((lhs1, rhs1)) = parse(second) && first.span.eq_ctxt(second.span) + && !in_external_macro(&cx.sess(), first.span) && is_same(cx, lhs0, rhs1) && is_same(cx, lhs1, rhs0) && !is_same(cx, lhs1, rhs1) // Ignore a = b; a = a (#10421) diff --git a/tests/ui/auxiliary/macro_rules.rs b/tests/ui/auxiliary/macro_rules.rs index 1dc92c1b92b..a9bb61451dc 100644 --- a/tests/ui/auxiliary/macro_rules.rs +++ b/tests/ui/auxiliary/macro_rules.rs @@ -27,3 +27,13 @@ macro_rules! mut_mut { let mut_mut_ty: &mut &mut u32 = &mut &mut 1u32; }; } + +#[macro_export] +macro_rules! issue_10421 { + () => { + let mut a = 1; + let mut b = 2; + a = b; + b = a; + }; +} diff --git a/tests/ui/swap.fixed b/tests/ui/swap.fixed index 78d8eedc38a..9703674d1a4 100644 --- a/tests/ui/swap.fixed +++ b/tests/ui/swap.fixed @@ -1,4 +1,5 @@ // run-rustfix +// aux-build: macro_rules.rs #![warn(clippy::all)] #![allow( @@ -188,13 +189,8 @@ const fn issue_9864(mut u: u32) -> u32 { u + v } -macro_rules! issue_10421 { - () => { - let a = 1; - let b = a; - let b = b; - }; -} +#[macro_use] +extern crate macro_rules; const fn issue_10421(x: u32) -> u32 { issue_10421!(); diff --git a/tests/ui/swap.rs b/tests/ui/swap.rs index c995af8ecf9..a0228065e46 100644 --- a/tests/ui/swap.rs +++ b/tests/ui/swap.rs @@ -1,4 +1,5 @@ // run-rustfix +// aux-build: macro_rules.rs #![warn(clippy::all)] #![allow( @@ -217,13 +218,8 @@ const fn issue_9864(mut u: u32) -> u32 { u + v } -macro_rules! issue_10421 { - () => { - let a = 1; - let b = a; - let b = b; - }; -} +#[macro_use] +extern crate macro_rules; const fn issue_10421(x: u32) -> u32 { issue_10421!(); diff --git a/tests/ui/swap.stderr b/tests/ui/swap.stderr index e9dacb3119e..0c246268499 100644 --- a/tests/ui/swap.stderr +++ b/tests/ui/swap.stderr @@ -1,5 +1,5 @@ error: this looks like you are swapping `bar.a` and `bar.b` manually - --> $DIR/swap.rs:26:5 + --> $DIR/swap.rs:27:5 | LL | / let temp = bar.a; LL | | bar.a = bar.b; @@ -10,7 +10,7 @@ LL | | bar.b = temp; = note: `-D clippy::manual-swap` implied by `-D warnings` error: this looks like you are swapping elements of `foo` manually - --> $DIR/swap.rs:38:5 + --> $DIR/swap.rs:39:5 | LL | / let temp = foo[0]; LL | | foo[0] = foo[1]; @@ -18,7 +18,7 @@ LL | | foo[1] = temp; | |__________________^ help: try: `foo.swap(0, 1);` error: this looks like you are swapping elements of `foo` manually - --> $DIR/swap.rs:47:5 + --> $DIR/swap.rs:48:5 | LL | / let temp = foo[0]; LL | | foo[0] = foo[1]; @@ -26,7 +26,7 @@ LL | | foo[1] = temp; | |__________________^ help: try: `foo.swap(0, 1);` error: this looks like you are swapping elements of `foo` manually - --> $DIR/swap.rs:66:5 + --> $DIR/swap.rs:67:5 | LL | / let temp = foo[0]; LL | | foo[0] = foo[1]; @@ -34,7 +34,7 @@ LL | | foo[1] = temp; | |__________________^ help: try: `foo.swap(0, 1);` error: this looks like you are swapping `a` and `b` manually - --> $DIR/swap.rs:77:5 + --> $DIR/swap.rs:78:5 | LL | / a ^= b; LL | | b ^= a; @@ -42,7 +42,7 @@ LL | | a ^= b; | |___________^ help: try: `std::mem::swap(&mut a, &mut b);` error: this looks like you are swapping `bar.a` and `bar.b` manually - --> $DIR/swap.rs:85:5 + --> $DIR/swap.rs:86:5 | LL | / bar.a ^= bar.b; LL | | bar.b ^= bar.a; @@ -50,7 +50,7 @@ LL | | bar.a ^= bar.b; | |___________________^ help: try: `std::mem::swap(&mut bar.a, &mut bar.b);` error: this looks like you are swapping elements of `foo` manually - --> $DIR/swap.rs:93:5 + --> $DIR/swap.rs:94:5 | LL | / foo[0] ^= foo[1]; LL | | foo[1] ^= foo[0]; @@ -58,7 +58,7 @@ LL | | foo[0] ^= foo[1]; | |_____________________^ help: try: `foo.swap(0, 1);` error: this looks like you are swapping `foo[0][1]` and `bar[1][0]` manually - --> $DIR/swap.rs:122:5 + --> $DIR/swap.rs:123:5 | LL | / let temp = foo[0][1]; LL | | foo[0][1] = bar[1][0]; @@ -68,7 +68,7 @@ LL | | bar[1][0] = temp; = note: or maybe you should use `std::mem::replace`? error: this looks like you are swapping `a` and `b` manually - --> $DIR/swap.rs:136:7 + --> $DIR/swap.rs:137:7 | LL | ; let t = a; | _______^ @@ -79,7 +79,7 @@ LL | | b = t; = note: or maybe you should use `std::mem::replace`? error: this looks like you are swapping `c.0` and `a` manually - --> $DIR/swap.rs:145:7 + --> $DIR/swap.rs:146:7 | LL | ; let t = c.0; | _______^ @@ -90,7 +90,7 @@ LL | | a = t; = note: or maybe you should use `std::mem::replace`? error: this looks like you are swapping `b` and `a` manually - --> $DIR/swap.rs:171:5 + --> $DIR/swap.rs:172:5 | LL | / let t = b; LL | | b = a; @@ -100,7 +100,7 @@ LL | | a = t; = note: or maybe you should use `std::mem::replace`? error: this looks like you are trying to swap `a` and `b` - --> $DIR/swap.rs:133:5 + --> $DIR/swap.rs:134:5 | LL | / a = b; LL | | b = a; @@ -110,7 +110,7 @@ LL | | b = a; = note: `-D clippy::almost-swapped` implied by `-D warnings` error: this looks like you are trying to swap `c.0` and `a` - --> $DIR/swap.rs:142:5 + --> $DIR/swap.rs:143:5 | LL | / c.0 = a; LL | | a = c.0; @@ -119,7 +119,7 @@ LL | | a = c.0; = note: or maybe you should use `std::mem::replace`? error: this looks like you are trying to swap `a` and `b` - --> $DIR/swap.rs:149:5 + --> $DIR/swap.rs:150:5 | LL | / let a = b; LL | | let b = a; @@ -128,7 +128,7 @@ LL | | let b = a; = note: or maybe you should use `std::mem::replace`? error: this looks like you are trying to swap `d` and `c` - --> $DIR/swap.rs:154:5 + --> $DIR/swap.rs:155:5 | LL | / d = c; LL | | c = d; @@ -137,7 +137,7 @@ LL | | c = d; = note: or maybe you should use `std::mem::replace`? error: this looks like you are trying to swap `a` and `b` - --> $DIR/swap.rs:158:5 + --> $DIR/swap.rs:159:5 | LL | / let a = b; LL | | b = a; @@ -146,7 +146,7 @@ LL | | b = a; = note: or maybe you should use `std::mem::replace`? error: this looks like you are swapping `s.0.x` and `s.0.y` manually - --> $DIR/swap.rs:206:5 + --> $DIR/swap.rs:207:5 | LL | / let t = s.0.x; LL | | s.0.x = s.0.y; From ffabdab8cf1499e1857d9ebcac2c410220137025 Mon Sep 17 00:00:00 2001 From: "Samuel \"Sam\" Tardieu" Date: Sat, 11 Mar 2023 10:20:44 +0100 Subject: [PATCH 058/346] New lint to detect `&std::path::MAIN_SEPARATOR.to_string()` --- CHANGELOG.md | 1 + clippy_lints/src/declared_lints.rs | 1 + clippy_lints/src/lib.rs | 2 + clippy_lints/src/manual_main_separator_str.rs | 72 +++++++++++++++++++ clippy_utils/src/msrvs.rs | 1 + clippy_utils/src/paths.rs | 1 + tests/ui/manual_main_separator_str.fixed | 39 ++++++++++ tests/ui/manual_main_separator_str.rs | 39 ++++++++++ tests/ui/manual_main_separator_str.stderr | 28 ++++++++ 9 files changed, 184 insertions(+) create mode 100644 clippy_lints/src/manual_main_separator_str.rs create mode 100644 tests/ui/manual_main_separator_str.fixed create mode 100644 tests/ui/manual_main_separator_str.rs create mode 100644 tests/ui/manual_main_separator_str.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index c090a844858..47a503510c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4662,6 +4662,7 @@ Released 2018-09-13 [`manual_instant_elapsed`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_instant_elapsed [`manual_is_ascii_check`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_ascii_check [`manual_let_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else +[`manual_main_separator_str`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_main_separator_str [`manual_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_map [`manual_memcpy`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_memcpy [`manual_non_exhaustive`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_non_exhaustive diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 25f15973490..2331e857b1f 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -263,6 +263,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::manual_clamp::MANUAL_CLAMP_INFO, crate::manual_is_ascii_check::MANUAL_IS_ASCII_CHECK_INFO, crate::manual_let_else::MANUAL_LET_ELSE_INFO, + crate::manual_main_separator_str::MANUAL_MAIN_SEPARATOR_STR_INFO, crate::manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE_INFO, crate::manual_rem_euclid::MANUAL_REM_EUCLID_INFO, crate::manual_retain::MANUAL_RETAIN_INFO, diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 4bb0e2ec96c..100cba45679 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -180,6 +180,7 @@ mod manual_bits; mod manual_clamp; mod manual_is_ascii_check; mod manual_let_else; +mod manual_main_separator_str; mod manual_non_exhaustive; mod manual_rem_euclid; mod manual_retain; @@ -936,6 +937,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_early_pass(|| Box::new(redundant_async_block::RedundantAsyncBlock)); store.register_late_pass(|_| Box::new(let_with_type_underscore::UnderscoreTyped)); store.register_late_pass(|_| Box::new(allow_attributes::AllowAttribute)); + store.register_late_pass(move |_| Box::new(manual_main_separator_str::ManualMainSeparatorStr::new(msrv()))); // add lints here, do not remove this comment, it's used in `new_lint` } diff --git a/clippy_lints/src/manual_main_separator_str.rs b/clippy_lints/src/manual_main_separator_str.rs new file mode 100644 index 00000000000..a6d318f952c --- /dev/null +++ b/clippy_lints/src/manual_main_separator_str.rs @@ -0,0 +1,72 @@ +use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::msrvs::{self, Msrv}; +use clippy_utils::{is_trait_method, match_def_path, paths, peel_hir_expr_refs}; +use rustc_errors::Applicability; +use rustc_hir::def::{DefKind, Res}; +use rustc_hir::*; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::ty; +use rustc_session::{declare_tool_lint, impl_lint_pass}; +use rustc_span::sym; + +declare_clippy_lint! { + /// ### What it does + /// Checks for references on `std::path::MAIN_SEPARATOR.to_string()` used + /// to build a `&str`. + /// + /// ### Why is this bad? + /// There exists a `std::path::MAIN_SEPARATOR_STR` which does not require + /// an extra memory allocation. + /// + /// ### Example + /// ```rust + /// let s: &str = &std::path::MAIN_SEPARATOR.to_string(); + /// ``` + /// Use instead: + /// ```rust + /// let s: &str = std::path::MAIN_SEPARATOR_STR; + /// ``` + #[clippy::version = "1.70.0"] + pub MANUAL_MAIN_SEPARATOR_STR, + complexity, + "`&std::path::MAIN_SEPARATOR.to_string()` can be replaced by `std::path::MAIN_SEPARATOR_STR`" +} + +pub struct ManualMainSeparatorStr { + msrv: Msrv, +} + +impl ManualMainSeparatorStr { + #[must_use] + pub fn new(msrv: Msrv) -> Self { + Self { msrv } + } +} + +impl_lint_pass!(ManualMainSeparatorStr => [MANUAL_MAIN_SEPARATOR_STR]); + +impl LateLintPass<'_> for ManualMainSeparatorStr { + fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { + if self.msrv.meets(msrvs::PATH_MAIN_SEPARATOR_STR) && + let (target, _) = peel_hir_expr_refs(expr) && + is_trait_method(cx, target, sym::ToString) && + let ExprKind::MethodCall(path, receiver, &[], _) = target.kind && + path.ident.name == sym::to_string && + let ExprKind::Path(QPath::Resolved(None, path)) = receiver.kind && + let Res::Def(DefKind::Const, receiver_def_id) = path.res && + match_def_path(cx, receiver_def_id, &paths::PATH_MAIN_SEPARATOR) && + let ty::Ref(_, ty, Mutability::Not) = cx.typeck_results().expr_ty_adjusted(expr).kind() && + ty.is_str() + { + span_lint_and_sugg( + cx, + MANUAL_MAIN_SEPARATOR_STR, + expr.span, + "taking a reference on `std::path::MAIN_SEPARATOR` conversion to `String`", + "replace with", + "std::path::MAIN_SEPARATOR_STR".to_owned(), + Applicability::MachineApplicable, + ); + } + } +} diff --git a/clippy_utils/src/msrvs.rs b/clippy_utils/src/msrvs.rs index dbf9f3b621d..e05de2dc99c 100644 --- a/clippy_utils/src/msrvs.rs +++ b/clippy_utils/src/msrvs.rs @@ -19,6 +19,7 @@ macro_rules! msrv_aliases { // names may refer to stabilized feature flags or library items msrv_aliases! { + 1,68,0 { PATH_MAIN_SEPARATOR_STR } 1,65,0 { LET_ELSE } 1,62,0 { BOOL_THEN_SOME, DEFAULT_ENUM_ATTRIBUTE } 1,58,0 { FORMAT_ARGS_CAPTURE, PATTERN_TRAIT_CHAR_ARRAY } diff --git a/clippy_utils/src/paths.rs b/clippy_utils/src/paths.rs index 4aae0f7284e..c919575bfe9 100644 --- a/clippy_utils/src/paths.rs +++ b/clippy_utils/src/paths.rs @@ -67,6 +67,7 @@ pub const PARKING_LOT_MUTEX_GUARD: [&str; 3] = ["lock_api", "mutex", "MutexGuard pub const PARKING_LOT_RWLOCK_READ_GUARD: [&str; 3] = ["lock_api", "rwlock", "RwLockReadGuard"]; pub const PARKING_LOT_RWLOCK_WRITE_GUARD: [&str; 3] = ["lock_api", "rwlock", "RwLockWriteGuard"]; pub const PATH_BUF_AS_PATH: [&str; 4] = ["std", "path", "PathBuf", "as_path"]; +pub const PATH_MAIN_SEPARATOR: [&str; 3] = ["std", "path", "MAIN_SEPARATOR"]; pub const PATH_TO_PATH_BUF: [&str; 4] = ["std", "path", "Path", "to_path_buf"]; pub const PEEKABLE: [&str; 5] = ["core", "iter", "adapters", "peekable", "Peekable"]; pub const PERMISSIONS: [&str; 3] = ["std", "fs", "Permissions"]; diff --git a/tests/ui/manual_main_separator_str.fixed b/tests/ui/manual_main_separator_str.fixed new file mode 100644 index 00000000000..50f46d6b355 --- /dev/null +++ b/tests/ui/manual_main_separator_str.fixed @@ -0,0 +1,39 @@ +// run-rustfix + +#![allow(unused)] +#![warn(clippy::manual_main_separator_str)] + +use std::path::MAIN_SEPARATOR; + +fn len(s: &str) -> usize { + s.len() +} + +struct U<'a> { + f: &'a str, + g: &'a String, +} + +struct V { + f: T, +} + +fn main() { + // Should lint + let _: &str = std::path::MAIN_SEPARATOR_STR; + let _ = len(std::path::MAIN_SEPARATOR_STR); + let _: Vec = std::path::MAIN_SEPARATOR_STR.encode_utf16().collect(); + + // Should lint for field `f` only + let _ = U { + f: std::path::MAIN_SEPARATOR_STR, + g: &MAIN_SEPARATOR.to_string(), + }; + + // Should not lint + let _: &String = &MAIN_SEPARATOR.to_string(); + let _ = &MAIN_SEPARATOR.to_string(); + let _ = V { + f: &MAIN_SEPARATOR.to_string(), + }; +} diff --git a/tests/ui/manual_main_separator_str.rs b/tests/ui/manual_main_separator_str.rs new file mode 100644 index 00000000000..2dbb9e66151 --- /dev/null +++ b/tests/ui/manual_main_separator_str.rs @@ -0,0 +1,39 @@ +// run-rustfix + +#![allow(unused)] +#![warn(clippy::manual_main_separator_str)] + +use std::path::MAIN_SEPARATOR; + +fn len(s: &str) -> usize { + s.len() +} + +struct U<'a> { + f: &'a str, + g: &'a String, +} + +struct V { + f: T, +} + +fn main() { + // Should lint + let _: &str = &MAIN_SEPARATOR.to_string(); + let _ = len(&MAIN_SEPARATOR.to_string()); + let _: Vec = MAIN_SEPARATOR.to_string().encode_utf16().collect(); + + // Should lint for field `f` only + let _ = U { + f: &MAIN_SEPARATOR.to_string(), + g: &MAIN_SEPARATOR.to_string(), + }; + + // Should not lint + let _: &String = &MAIN_SEPARATOR.to_string(); + let _ = &MAIN_SEPARATOR.to_string(); + let _ = V { + f: &MAIN_SEPARATOR.to_string(), + }; +} diff --git a/tests/ui/manual_main_separator_str.stderr b/tests/ui/manual_main_separator_str.stderr new file mode 100644 index 00000000000..e6cefde66a7 --- /dev/null +++ b/tests/ui/manual_main_separator_str.stderr @@ -0,0 +1,28 @@ +error: taking a reference on `std::path::MAIN_SEPARATOR` conversion to `String` + --> $DIR/manual_main_separator_str.rs:23:19 + | +LL | let _: &str = &MAIN_SEPARATOR.to_string(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::path::MAIN_SEPARATOR_STR` + | + = note: `-D clippy::manual-main-separator-str` implied by `-D warnings` + +error: taking a reference on `std::path::MAIN_SEPARATOR` conversion to `String` + --> $DIR/manual_main_separator_str.rs:24:17 + | +LL | let _ = len(&MAIN_SEPARATOR.to_string()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::path::MAIN_SEPARATOR_STR` + +error: taking a reference on `std::path::MAIN_SEPARATOR` conversion to `String` + --> $DIR/manual_main_separator_str.rs:25:23 + | +LL | let _: Vec = MAIN_SEPARATOR.to_string().encode_utf16().collect(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::path::MAIN_SEPARATOR_STR` + +error: taking a reference on `std::path::MAIN_SEPARATOR` conversion to `String` + --> $DIR/manual_main_separator_str.rs:29:12 + | +LL | f: &MAIN_SEPARATOR.to_string(), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `std::path::MAIN_SEPARATOR_STR` + +error: aborting due to 4 previous errors + From 355e1dda1df8a8106a1692eb7f019fb00df8c3ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gammels=C3=A6ter?= Date: Thu, 16 Mar 2023 20:20:37 +0100 Subject: [PATCH 059/346] Improve case mapping encoding scheme The indices are encoded as `u32`s in the range of invalid `char`s, so that we know that if any mapping fails to parse as a `char` we should use the value for lookup in the multi-table. This avoids the second binary search in cases where a multi-`char` mapping is needed. Idea from @nikic --- library/core/src/unicode/unicode_data.rs | 1824 +++++++---------- .../src/case_mapping.rs | 103 +- 2 files changed, 833 insertions(+), 1094 deletions(-) diff --git a/library/core/src/unicode/unicode_data.rs b/library/core/src/unicode/unicode_data.rs index 20b3587ab65..091259e4d38 100644 --- a/library/core/src/unicode/unicode_data.rs +++ b/library/core/src/unicode/unicode_data.rs @@ -580,14 +580,22 @@ pub mod white_space { #[rustfmt::skip] pub mod conversions { + const INDEX_MASK: u32 = 4194304; + pub fn to_lower(c: char) -> [char; 3] { if c.is_ascii() { [(c as u8).to_ascii_lowercase() as char, '\0', '\0'] } else { - match bsearch_case_tables(c, LOWERCASE_TABLE_SINGLE, LOWERCASE_TABLE_MULTI) { - Some(replacement) => replacement, - None => [c, '\0', '\0'], - } + LOWERCASE_TABLE + .binary_search_by(|&(key, _)| key.cmp(&c)) + .map(|i| { + let u = LOWERCASE_TABLE[i].1; + char::from_u32(u).map(|c| [c, '\0', '\0']).unwrap_or_else(|| { + // SAFETY: Index comes from statically generated table + unsafe { *LOWERCASE_TABLE_MULTI.get_unchecked((u & (INDEX_MASK - 1)) as usize) } + }) + }) + .unwrap_or([c, '\0', '\0']) } } @@ -595,1055 +603,781 @@ pub mod conversions { if c.is_ascii() { [(c as u8).to_ascii_uppercase() as char, '\0', '\0'] } else { - match bsearch_case_tables(c, UPPERCASE_TABLE_SINGLE, UPPERCASE_TABLE_MULTI) { - Some(replacement) => replacement, - None => [c, '\0', '\0'], - } + UPPERCASE_TABLE + .binary_search_by(|&(key, _)| key.cmp(&c)) + .map(|i| { + let u = UPPERCASE_TABLE[i].1; + char::from_u32(u).map(|c| [c, '\0', '\0']).unwrap_or_else(|| { + // SAFETY: Index comes from statically generated table + unsafe { *UPPERCASE_TABLE_MULTI.get_unchecked((u & (INDEX_MASK - 1)) as usize) } + }) + }) + .unwrap_or([c, '\0', '\0']) } } - fn bsearch_case_tables( - c: char, - single: &[(char, char)], - multi: &[(char, [char; 3])], - ) -> Option<[char; 3]> { - match single.binary_search_by(|&(key, _)| key.cmp(&c)) { - Ok(i) => Some([single[i].1, '\0', '\0']), - Err(_) => multi.binary_search_by(|&(key, _)| key.cmp(&c)).map(|i| multi[i].1).ok(), - } - } - static LOWERCASE_TABLE_SINGLE: &[(char, char)] = &[ - ('\u{c0}', '\u{e0}'), ('\u{c1}', '\u{e1}'), ('\u{c2}', '\u{e2}'), ('\u{c3}', '\u{e3}'), - ('\u{c4}', '\u{e4}'), ('\u{c5}', '\u{e5}'), ('\u{c6}', '\u{e6}'), ('\u{c7}', '\u{e7}'), - ('\u{c8}', '\u{e8}'), ('\u{c9}', '\u{e9}'), ('\u{ca}', '\u{ea}'), ('\u{cb}', '\u{eb}'), - ('\u{cc}', '\u{ec}'), ('\u{cd}', '\u{ed}'), ('\u{ce}', '\u{ee}'), ('\u{cf}', '\u{ef}'), - ('\u{d0}', '\u{f0}'), ('\u{d1}', '\u{f1}'), ('\u{d2}', '\u{f2}'), ('\u{d3}', '\u{f3}'), - ('\u{d4}', '\u{f4}'), ('\u{d5}', '\u{f5}'), ('\u{d6}', '\u{f6}'), ('\u{d8}', '\u{f8}'), - ('\u{d9}', '\u{f9}'), ('\u{da}', '\u{fa}'), ('\u{db}', '\u{fb}'), ('\u{dc}', '\u{fc}'), - ('\u{dd}', '\u{fd}'), ('\u{de}', '\u{fe}'), ('\u{100}', '\u{101}'), ('\u{102}', '\u{103}'), - ('\u{104}', '\u{105}'), ('\u{106}', '\u{107}'), ('\u{108}', '\u{109}'), - ('\u{10a}', '\u{10b}'), ('\u{10c}', '\u{10d}'), ('\u{10e}', '\u{10f}'), - ('\u{110}', '\u{111}'), ('\u{112}', '\u{113}'), ('\u{114}', '\u{115}'), - ('\u{116}', '\u{117}'), ('\u{118}', '\u{119}'), ('\u{11a}', '\u{11b}'), - ('\u{11c}', '\u{11d}'), ('\u{11e}', '\u{11f}'), ('\u{120}', '\u{121}'), - ('\u{122}', '\u{123}'), ('\u{124}', '\u{125}'), ('\u{126}', '\u{127}'), - ('\u{128}', '\u{129}'), ('\u{12a}', '\u{12b}'), ('\u{12c}', '\u{12d}'), - ('\u{12e}', '\u{12f}'), ('\u{132}', '\u{133}'), ('\u{134}', '\u{135}'), - ('\u{136}', '\u{137}'), ('\u{139}', '\u{13a}'), ('\u{13b}', '\u{13c}'), - ('\u{13d}', '\u{13e}'), ('\u{13f}', '\u{140}'), ('\u{141}', '\u{142}'), - ('\u{143}', '\u{144}'), ('\u{145}', '\u{146}'), ('\u{147}', '\u{148}'), - ('\u{14a}', '\u{14b}'), ('\u{14c}', '\u{14d}'), ('\u{14e}', '\u{14f}'), - ('\u{150}', '\u{151}'), ('\u{152}', '\u{153}'), ('\u{154}', '\u{155}'), - ('\u{156}', '\u{157}'), ('\u{158}', '\u{159}'), ('\u{15a}', '\u{15b}'), - ('\u{15c}', '\u{15d}'), ('\u{15e}', '\u{15f}'), ('\u{160}', '\u{161}'), - ('\u{162}', '\u{163}'), ('\u{164}', '\u{165}'), ('\u{166}', '\u{167}'), - ('\u{168}', '\u{169}'), ('\u{16a}', '\u{16b}'), ('\u{16c}', '\u{16d}'), - ('\u{16e}', '\u{16f}'), ('\u{170}', '\u{171}'), ('\u{172}', '\u{173}'), - ('\u{174}', '\u{175}'), ('\u{176}', '\u{177}'), ('\u{178}', '\u{ff}'), - ('\u{179}', '\u{17a}'), ('\u{17b}', '\u{17c}'), ('\u{17d}', '\u{17e}'), - ('\u{181}', '\u{253}'), ('\u{182}', '\u{183}'), ('\u{184}', '\u{185}'), - ('\u{186}', '\u{254}'), ('\u{187}', '\u{188}'), ('\u{189}', '\u{256}'), - ('\u{18a}', '\u{257}'), ('\u{18b}', '\u{18c}'), ('\u{18e}', '\u{1dd}'), - ('\u{18f}', '\u{259}'), ('\u{190}', '\u{25b}'), ('\u{191}', '\u{192}'), - ('\u{193}', '\u{260}'), ('\u{194}', '\u{263}'), ('\u{196}', '\u{269}'), - ('\u{197}', '\u{268}'), ('\u{198}', '\u{199}'), ('\u{19c}', '\u{26f}'), - ('\u{19d}', '\u{272}'), ('\u{19f}', '\u{275}'), ('\u{1a0}', '\u{1a1}'), - ('\u{1a2}', '\u{1a3}'), ('\u{1a4}', '\u{1a5}'), ('\u{1a6}', '\u{280}'), - ('\u{1a7}', '\u{1a8}'), ('\u{1a9}', '\u{283}'), ('\u{1ac}', '\u{1ad}'), - ('\u{1ae}', '\u{288}'), ('\u{1af}', '\u{1b0}'), ('\u{1b1}', '\u{28a}'), - ('\u{1b2}', '\u{28b}'), ('\u{1b3}', '\u{1b4}'), ('\u{1b5}', '\u{1b6}'), - ('\u{1b7}', '\u{292}'), ('\u{1b8}', '\u{1b9}'), ('\u{1bc}', '\u{1bd}'), - ('\u{1c4}', '\u{1c6}'), ('\u{1c5}', '\u{1c6}'), ('\u{1c7}', '\u{1c9}'), - ('\u{1c8}', '\u{1c9}'), ('\u{1ca}', '\u{1cc}'), ('\u{1cb}', '\u{1cc}'), - ('\u{1cd}', '\u{1ce}'), ('\u{1cf}', '\u{1d0}'), ('\u{1d1}', '\u{1d2}'), - ('\u{1d3}', '\u{1d4}'), ('\u{1d5}', '\u{1d6}'), ('\u{1d7}', '\u{1d8}'), - ('\u{1d9}', '\u{1da}'), ('\u{1db}', '\u{1dc}'), ('\u{1de}', '\u{1df}'), - ('\u{1e0}', '\u{1e1}'), ('\u{1e2}', '\u{1e3}'), ('\u{1e4}', '\u{1e5}'), - ('\u{1e6}', '\u{1e7}'), ('\u{1e8}', '\u{1e9}'), ('\u{1ea}', '\u{1eb}'), - ('\u{1ec}', '\u{1ed}'), ('\u{1ee}', '\u{1ef}'), ('\u{1f1}', '\u{1f3}'), - ('\u{1f2}', '\u{1f3}'), ('\u{1f4}', '\u{1f5}'), ('\u{1f6}', '\u{195}'), - ('\u{1f7}', '\u{1bf}'), ('\u{1f8}', '\u{1f9}'), ('\u{1fa}', '\u{1fb}'), - ('\u{1fc}', '\u{1fd}'), ('\u{1fe}', '\u{1ff}'), ('\u{200}', '\u{201}'), - ('\u{202}', '\u{203}'), ('\u{204}', '\u{205}'), ('\u{206}', '\u{207}'), - ('\u{208}', '\u{209}'), ('\u{20a}', '\u{20b}'), ('\u{20c}', '\u{20d}'), - ('\u{20e}', '\u{20f}'), ('\u{210}', '\u{211}'), ('\u{212}', '\u{213}'), - ('\u{214}', '\u{215}'), ('\u{216}', '\u{217}'), ('\u{218}', '\u{219}'), - ('\u{21a}', '\u{21b}'), ('\u{21c}', '\u{21d}'), ('\u{21e}', '\u{21f}'), - ('\u{220}', '\u{19e}'), ('\u{222}', '\u{223}'), ('\u{224}', '\u{225}'), - ('\u{226}', '\u{227}'), ('\u{228}', '\u{229}'), ('\u{22a}', '\u{22b}'), - ('\u{22c}', '\u{22d}'), ('\u{22e}', '\u{22f}'), ('\u{230}', '\u{231}'), - ('\u{232}', '\u{233}'), ('\u{23a}', '\u{2c65}'), ('\u{23b}', '\u{23c}'), - ('\u{23d}', '\u{19a}'), ('\u{23e}', '\u{2c66}'), ('\u{241}', '\u{242}'), - ('\u{243}', '\u{180}'), ('\u{244}', '\u{289}'), ('\u{245}', '\u{28c}'), - ('\u{246}', '\u{247}'), ('\u{248}', '\u{249}'), ('\u{24a}', '\u{24b}'), - ('\u{24c}', '\u{24d}'), ('\u{24e}', '\u{24f}'), ('\u{370}', '\u{371}'), - ('\u{372}', '\u{373}'), ('\u{376}', '\u{377}'), ('\u{37f}', '\u{3f3}'), - ('\u{386}', '\u{3ac}'), ('\u{388}', '\u{3ad}'), ('\u{389}', '\u{3ae}'), - ('\u{38a}', '\u{3af}'), ('\u{38c}', '\u{3cc}'), ('\u{38e}', '\u{3cd}'), - ('\u{38f}', '\u{3ce}'), ('\u{391}', '\u{3b1}'), ('\u{392}', '\u{3b2}'), - ('\u{393}', '\u{3b3}'), ('\u{394}', '\u{3b4}'), ('\u{395}', '\u{3b5}'), - ('\u{396}', '\u{3b6}'), ('\u{397}', '\u{3b7}'), ('\u{398}', '\u{3b8}'), - ('\u{399}', '\u{3b9}'), ('\u{39a}', '\u{3ba}'), ('\u{39b}', '\u{3bb}'), - ('\u{39c}', '\u{3bc}'), ('\u{39d}', '\u{3bd}'), ('\u{39e}', '\u{3be}'), - ('\u{39f}', '\u{3bf}'), ('\u{3a0}', '\u{3c0}'), ('\u{3a1}', '\u{3c1}'), - ('\u{3a3}', '\u{3c3}'), ('\u{3a4}', '\u{3c4}'), ('\u{3a5}', '\u{3c5}'), - ('\u{3a6}', '\u{3c6}'), ('\u{3a7}', '\u{3c7}'), ('\u{3a8}', '\u{3c8}'), - ('\u{3a9}', '\u{3c9}'), ('\u{3aa}', '\u{3ca}'), ('\u{3ab}', '\u{3cb}'), - ('\u{3cf}', '\u{3d7}'), ('\u{3d8}', '\u{3d9}'), ('\u{3da}', '\u{3db}'), - ('\u{3dc}', '\u{3dd}'), ('\u{3de}', '\u{3df}'), ('\u{3e0}', '\u{3e1}'), - ('\u{3e2}', '\u{3e3}'), ('\u{3e4}', '\u{3e5}'), ('\u{3e6}', '\u{3e7}'), - ('\u{3e8}', '\u{3e9}'), ('\u{3ea}', '\u{3eb}'), ('\u{3ec}', '\u{3ed}'), - ('\u{3ee}', '\u{3ef}'), ('\u{3f4}', '\u{3b8}'), ('\u{3f7}', '\u{3f8}'), - ('\u{3f9}', '\u{3f2}'), ('\u{3fa}', '\u{3fb}'), ('\u{3fd}', '\u{37b}'), - ('\u{3fe}', '\u{37c}'), ('\u{3ff}', '\u{37d}'), ('\u{400}', '\u{450}'), - ('\u{401}', '\u{451}'), ('\u{402}', '\u{452}'), ('\u{403}', '\u{453}'), - ('\u{404}', '\u{454}'), ('\u{405}', '\u{455}'), ('\u{406}', '\u{456}'), - ('\u{407}', '\u{457}'), ('\u{408}', '\u{458}'), ('\u{409}', '\u{459}'), - ('\u{40a}', '\u{45a}'), ('\u{40b}', '\u{45b}'), ('\u{40c}', '\u{45c}'), - ('\u{40d}', '\u{45d}'), ('\u{40e}', '\u{45e}'), ('\u{40f}', '\u{45f}'), - ('\u{410}', '\u{430}'), ('\u{411}', '\u{431}'), ('\u{412}', '\u{432}'), - ('\u{413}', '\u{433}'), ('\u{414}', '\u{434}'), ('\u{415}', '\u{435}'), - ('\u{416}', '\u{436}'), ('\u{417}', '\u{437}'), ('\u{418}', '\u{438}'), - ('\u{419}', '\u{439}'), ('\u{41a}', '\u{43a}'), ('\u{41b}', '\u{43b}'), - ('\u{41c}', '\u{43c}'), ('\u{41d}', '\u{43d}'), ('\u{41e}', '\u{43e}'), - ('\u{41f}', '\u{43f}'), ('\u{420}', '\u{440}'), ('\u{421}', '\u{441}'), - ('\u{422}', '\u{442}'), ('\u{423}', '\u{443}'), ('\u{424}', '\u{444}'), - ('\u{425}', '\u{445}'), ('\u{426}', '\u{446}'), ('\u{427}', '\u{447}'), - ('\u{428}', '\u{448}'), ('\u{429}', '\u{449}'), ('\u{42a}', '\u{44a}'), - ('\u{42b}', '\u{44b}'), ('\u{42c}', '\u{44c}'), ('\u{42d}', '\u{44d}'), - ('\u{42e}', '\u{44e}'), ('\u{42f}', '\u{44f}'), ('\u{460}', '\u{461}'), - ('\u{462}', '\u{463}'), ('\u{464}', '\u{465}'), ('\u{466}', '\u{467}'), - ('\u{468}', '\u{469}'), ('\u{46a}', '\u{46b}'), ('\u{46c}', '\u{46d}'), - ('\u{46e}', '\u{46f}'), ('\u{470}', '\u{471}'), ('\u{472}', '\u{473}'), - ('\u{474}', '\u{475}'), ('\u{476}', '\u{477}'), ('\u{478}', '\u{479}'), - ('\u{47a}', '\u{47b}'), ('\u{47c}', '\u{47d}'), ('\u{47e}', '\u{47f}'), - ('\u{480}', '\u{481}'), ('\u{48a}', '\u{48b}'), ('\u{48c}', '\u{48d}'), - ('\u{48e}', '\u{48f}'), ('\u{490}', '\u{491}'), ('\u{492}', '\u{493}'), - ('\u{494}', '\u{495}'), ('\u{496}', '\u{497}'), ('\u{498}', '\u{499}'), - ('\u{49a}', '\u{49b}'), ('\u{49c}', '\u{49d}'), ('\u{49e}', '\u{49f}'), - ('\u{4a0}', '\u{4a1}'), ('\u{4a2}', '\u{4a3}'), ('\u{4a4}', '\u{4a5}'), - ('\u{4a6}', '\u{4a7}'), ('\u{4a8}', '\u{4a9}'), ('\u{4aa}', '\u{4ab}'), - ('\u{4ac}', '\u{4ad}'), ('\u{4ae}', '\u{4af}'), ('\u{4b0}', '\u{4b1}'), - ('\u{4b2}', '\u{4b3}'), ('\u{4b4}', '\u{4b5}'), ('\u{4b6}', '\u{4b7}'), - ('\u{4b8}', '\u{4b9}'), ('\u{4ba}', '\u{4bb}'), ('\u{4bc}', '\u{4bd}'), - ('\u{4be}', '\u{4bf}'), ('\u{4c0}', '\u{4cf}'), ('\u{4c1}', '\u{4c2}'), - ('\u{4c3}', '\u{4c4}'), ('\u{4c5}', '\u{4c6}'), ('\u{4c7}', '\u{4c8}'), - ('\u{4c9}', '\u{4ca}'), ('\u{4cb}', '\u{4cc}'), ('\u{4cd}', '\u{4ce}'), - ('\u{4d0}', '\u{4d1}'), ('\u{4d2}', '\u{4d3}'), ('\u{4d4}', '\u{4d5}'), - ('\u{4d6}', '\u{4d7}'), ('\u{4d8}', '\u{4d9}'), ('\u{4da}', '\u{4db}'), - ('\u{4dc}', '\u{4dd}'), ('\u{4de}', '\u{4df}'), ('\u{4e0}', '\u{4e1}'), - ('\u{4e2}', '\u{4e3}'), ('\u{4e4}', '\u{4e5}'), ('\u{4e6}', '\u{4e7}'), - ('\u{4e8}', '\u{4e9}'), ('\u{4ea}', '\u{4eb}'), ('\u{4ec}', '\u{4ed}'), - ('\u{4ee}', '\u{4ef}'), ('\u{4f0}', '\u{4f1}'), ('\u{4f2}', '\u{4f3}'), - ('\u{4f4}', '\u{4f5}'), ('\u{4f6}', '\u{4f7}'), ('\u{4f8}', '\u{4f9}'), - ('\u{4fa}', '\u{4fb}'), ('\u{4fc}', '\u{4fd}'), ('\u{4fe}', '\u{4ff}'), - ('\u{500}', '\u{501}'), ('\u{502}', '\u{503}'), ('\u{504}', '\u{505}'), - ('\u{506}', '\u{507}'), ('\u{508}', '\u{509}'), ('\u{50a}', '\u{50b}'), - ('\u{50c}', '\u{50d}'), ('\u{50e}', '\u{50f}'), ('\u{510}', '\u{511}'), - ('\u{512}', '\u{513}'), ('\u{514}', '\u{515}'), ('\u{516}', '\u{517}'), - ('\u{518}', '\u{519}'), ('\u{51a}', '\u{51b}'), ('\u{51c}', '\u{51d}'), - ('\u{51e}', '\u{51f}'), ('\u{520}', '\u{521}'), ('\u{522}', '\u{523}'), - ('\u{524}', '\u{525}'), ('\u{526}', '\u{527}'), ('\u{528}', '\u{529}'), - ('\u{52a}', '\u{52b}'), ('\u{52c}', '\u{52d}'), ('\u{52e}', '\u{52f}'), - ('\u{531}', '\u{561}'), ('\u{532}', '\u{562}'), ('\u{533}', '\u{563}'), - ('\u{534}', '\u{564}'), ('\u{535}', '\u{565}'), ('\u{536}', '\u{566}'), - ('\u{537}', '\u{567}'), ('\u{538}', '\u{568}'), ('\u{539}', '\u{569}'), - ('\u{53a}', '\u{56a}'), ('\u{53b}', '\u{56b}'), ('\u{53c}', '\u{56c}'), - ('\u{53d}', '\u{56d}'), ('\u{53e}', '\u{56e}'), ('\u{53f}', '\u{56f}'), - ('\u{540}', '\u{570}'), ('\u{541}', '\u{571}'), ('\u{542}', '\u{572}'), - ('\u{543}', '\u{573}'), ('\u{544}', '\u{574}'), ('\u{545}', '\u{575}'), - ('\u{546}', '\u{576}'), ('\u{547}', '\u{577}'), ('\u{548}', '\u{578}'), - ('\u{549}', '\u{579}'), ('\u{54a}', '\u{57a}'), ('\u{54b}', '\u{57b}'), - ('\u{54c}', '\u{57c}'), ('\u{54d}', '\u{57d}'), ('\u{54e}', '\u{57e}'), - ('\u{54f}', '\u{57f}'), ('\u{550}', '\u{580}'), ('\u{551}', '\u{581}'), - ('\u{552}', '\u{582}'), ('\u{553}', '\u{583}'), ('\u{554}', '\u{584}'), - ('\u{555}', '\u{585}'), ('\u{556}', '\u{586}'), ('\u{10a0}', '\u{2d00}'), - ('\u{10a1}', '\u{2d01}'), ('\u{10a2}', '\u{2d02}'), ('\u{10a3}', '\u{2d03}'), - ('\u{10a4}', '\u{2d04}'), ('\u{10a5}', '\u{2d05}'), ('\u{10a6}', '\u{2d06}'), - ('\u{10a7}', '\u{2d07}'), ('\u{10a8}', '\u{2d08}'), ('\u{10a9}', '\u{2d09}'), - ('\u{10aa}', '\u{2d0a}'), ('\u{10ab}', '\u{2d0b}'), ('\u{10ac}', '\u{2d0c}'), - ('\u{10ad}', '\u{2d0d}'), ('\u{10ae}', '\u{2d0e}'), ('\u{10af}', '\u{2d0f}'), - ('\u{10b0}', '\u{2d10}'), ('\u{10b1}', '\u{2d11}'), ('\u{10b2}', '\u{2d12}'), - ('\u{10b3}', '\u{2d13}'), ('\u{10b4}', '\u{2d14}'), ('\u{10b5}', '\u{2d15}'), - ('\u{10b6}', '\u{2d16}'), ('\u{10b7}', '\u{2d17}'), ('\u{10b8}', '\u{2d18}'), - ('\u{10b9}', '\u{2d19}'), ('\u{10ba}', '\u{2d1a}'), ('\u{10bb}', '\u{2d1b}'), - ('\u{10bc}', '\u{2d1c}'), ('\u{10bd}', '\u{2d1d}'), ('\u{10be}', '\u{2d1e}'), - ('\u{10bf}', '\u{2d1f}'), ('\u{10c0}', '\u{2d20}'), ('\u{10c1}', '\u{2d21}'), - ('\u{10c2}', '\u{2d22}'), ('\u{10c3}', '\u{2d23}'), ('\u{10c4}', '\u{2d24}'), - ('\u{10c5}', '\u{2d25}'), ('\u{10c7}', '\u{2d27}'), ('\u{10cd}', '\u{2d2d}'), - ('\u{13a0}', '\u{ab70}'), ('\u{13a1}', '\u{ab71}'), ('\u{13a2}', '\u{ab72}'), - ('\u{13a3}', '\u{ab73}'), ('\u{13a4}', '\u{ab74}'), ('\u{13a5}', '\u{ab75}'), - ('\u{13a6}', '\u{ab76}'), ('\u{13a7}', '\u{ab77}'), ('\u{13a8}', '\u{ab78}'), - ('\u{13a9}', '\u{ab79}'), ('\u{13aa}', '\u{ab7a}'), ('\u{13ab}', '\u{ab7b}'), - ('\u{13ac}', '\u{ab7c}'), ('\u{13ad}', '\u{ab7d}'), ('\u{13ae}', '\u{ab7e}'), - ('\u{13af}', '\u{ab7f}'), ('\u{13b0}', '\u{ab80}'), ('\u{13b1}', '\u{ab81}'), - ('\u{13b2}', '\u{ab82}'), ('\u{13b3}', '\u{ab83}'), ('\u{13b4}', '\u{ab84}'), - ('\u{13b5}', '\u{ab85}'), ('\u{13b6}', '\u{ab86}'), ('\u{13b7}', '\u{ab87}'), - ('\u{13b8}', '\u{ab88}'), ('\u{13b9}', '\u{ab89}'), ('\u{13ba}', '\u{ab8a}'), - ('\u{13bb}', '\u{ab8b}'), ('\u{13bc}', '\u{ab8c}'), ('\u{13bd}', '\u{ab8d}'), - ('\u{13be}', '\u{ab8e}'), ('\u{13bf}', '\u{ab8f}'), ('\u{13c0}', '\u{ab90}'), - ('\u{13c1}', '\u{ab91}'), ('\u{13c2}', '\u{ab92}'), ('\u{13c3}', '\u{ab93}'), - ('\u{13c4}', '\u{ab94}'), ('\u{13c5}', '\u{ab95}'), ('\u{13c6}', '\u{ab96}'), - ('\u{13c7}', '\u{ab97}'), ('\u{13c8}', '\u{ab98}'), ('\u{13c9}', '\u{ab99}'), - ('\u{13ca}', '\u{ab9a}'), ('\u{13cb}', '\u{ab9b}'), ('\u{13cc}', '\u{ab9c}'), - ('\u{13cd}', '\u{ab9d}'), ('\u{13ce}', '\u{ab9e}'), ('\u{13cf}', '\u{ab9f}'), - ('\u{13d0}', '\u{aba0}'), ('\u{13d1}', '\u{aba1}'), ('\u{13d2}', '\u{aba2}'), - ('\u{13d3}', '\u{aba3}'), ('\u{13d4}', '\u{aba4}'), ('\u{13d5}', '\u{aba5}'), - ('\u{13d6}', '\u{aba6}'), ('\u{13d7}', '\u{aba7}'), ('\u{13d8}', '\u{aba8}'), - ('\u{13d9}', '\u{aba9}'), ('\u{13da}', '\u{abaa}'), ('\u{13db}', '\u{abab}'), - ('\u{13dc}', '\u{abac}'), ('\u{13dd}', '\u{abad}'), ('\u{13de}', '\u{abae}'), - ('\u{13df}', '\u{abaf}'), ('\u{13e0}', '\u{abb0}'), ('\u{13e1}', '\u{abb1}'), - ('\u{13e2}', '\u{abb2}'), ('\u{13e3}', '\u{abb3}'), ('\u{13e4}', '\u{abb4}'), - ('\u{13e5}', '\u{abb5}'), ('\u{13e6}', '\u{abb6}'), ('\u{13e7}', '\u{abb7}'), - ('\u{13e8}', '\u{abb8}'), ('\u{13e9}', '\u{abb9}'), ('\u{13ea}', '\u{abba}'), - ('\u{13eb}', '\u{abbb}'), ('\u{13ec}', '\u{abbc}'), ('\u{13ed}', '\u{abbd}'), - ('\u{13ee}', '\u{abbe}'), ('\u{13ef}', '\u{abbf}'), ('\u{13f0}', '\u{13f8}'), - ('\u{13f1}', '\u{13f9}'), ('\u{13f2}', '\u{13fa}'), ('\u{13f3}', '\u{13fb}'), - ('\u{13f4}', '\u{13fc}'), ('\u{13f5}', '\u{13fd}'), ('\u{1c90}', '\u{10d0}'), - ('\u{1c91}', '\u{10d1}'), ('\u{1c92}', '\u{10d2}'), ('\u{1c93}', '\u{10d3}'), - ('\u{1c94}', '\u{10d4}'), ('\u{1c95}', '\u{10d5}'), ('\u{1c96}', '\u{10d6}'), - ('\u{1c97}', '\u{10d7}'), ('\u{1c98}', '\u{10d8}'), ('\u{1c99}', '\u{10d9}'), - ('\u{1c9a}', '\u{10da}'), ('\u{1c9b}', '\u{10db}'), ('\u{1c9c}', '\u{10dc}'), - ('\u{1c9d}', '\u{10dd}'), ('\u{1c9e}', '\u{10de}'), ('\u{1c9f}', '\u{10df}'), - ('\u{1ca0}', '\u{10e0}'), ('\u{1ca1}', '\u{10e1}'), ('\u{1ca2}', '\u{10e2}'), - ('\u{1ca3}', '\u{10e3}'), ('\u{1ca4}', '\u{10e4}'), ('\u{1ca5}', '\u{10e5}'), - ('\u{1ca6}', '\u{10e6}'), ('\u{1ca7}', '\u{10e7}'), ('\u{1ca8}', '\u{10e8}'), - ('\u{1ca9}', '\u{10e9}'), ('\u{1caa}', '\u{10ea}'), ('\u{1cab}', '\u{10eb}'), - ('\u{1cac}', '\u{10ec}'), ('\u{1cad}', '\u{10ed}'), ('\u{1cae}', '\u{10ee}'), - ('\u{1caf}', '\u{10ef}'), ('\u{1cb0}', '\u{10f0}'), ('\u{1cb1}', '\u{10f1}'), - ('\u{1cb2}', '\u{10f2}'), ('\u{1cb3}', '\u{10f3}'), ('\u{1cb4}', '\u{10f4}'), - ('\u{1cb5}', '\u{10f5}'), ('\u{1cb6}', '\u{10f6}'), ('\u{1cb7}', '\u{10f7}'), - ('\u{1cb8}', '\u{10f8}'), ('\u{1cb9}', '\u{10f9}'), ('\u{1cba}', '\u{10fa}'), - ('\u{1cbd}', '\u{10fd}'), ('\u{1cbe}', '\u{10fe}'), ('\u{1cbf}', '\u{10ff}'), - ('\u{1e00}', '\u{1e01}'), ('\u{1e02}', '\u{1e03}'), ('\u{1e04}', '\u{1e05}'), - ('\u{1e06}', '\u{1e07}'), ('\u{1e08}', '\u{1e09}'), ('\u{1e0a}', '\u{1e0b}'), - ('\u{1e0c}', '\u{1e0d}'), ('\u{1e0e}', '\u{1e0f}'), ('\u{1e10}', '\u{1e11}'), - ('\u{1e12}', '\u{1e13}'), ('\u{1e14}', '\u{1e15}'), ('\u{1e16}', '\u{1e17}'), - ('\u{1e18}', '\u{1e19}'), ('\u{1e1a}', '\u{1e1b}'), ('\u{1e1c}', '\u{1e1d}'), - ('\u{1e1e}', '\u{1e1f}'), ('\u{1e20}', '\u{1e21}'), ('\u{1e22}', '\u{1e23}'), - ('\u{1e24}', '\u{1e25}'), ('\u{1e26}', '\u{1e27}'), ('\u{1e28}', '\u{1e29}'), - ('\u{1e2a}', '\u{1e2b}'), ('\u{1e2c}', '\u{1e2d}'), ('\u{1e2e}', '\u{1e2f}'), - ('\u{1e30}', '\u{1e31}'), ('\u{1e32}', '\u{1e33}'), ('\u{1e34}', '\u{1e35}'), - ('\u{1e36}', '\u{1e37}'), ('\u{1e38}', '\u{1e39}'), ('\u{1e3a}', '\u{1e3b}'), - ('\u{1e3c}', '\u{1e3d}'), ('\u{1e3e}', '\u{1e3f}'), ('\u{1e40}', '\u{1e41}'), - ('\u{1e42}', '\u{1e43}'), ('\u{1e44}', '\u{1e45}'), ('\u{1e46}', '\u{1e47}'), - ('\u{1e48}', '\u{1e49}'), ('\u{1e4a}', '\u{1e4b}'), ('\u{1e4c}', '\u{1e4d}'), - ('\u{1e4e}', '\u{1e4f}'), ('\u{1e50}', '\u{1e51}'), ('\u{1e52}', '\u{1e53}'), - ('\u{1e54}', '\u{1e55}'), ('\u{1e56}', '\u{1e57}'), ('\u{1e58}', '\u{1e59}'), - ('\u{1e5a}', '\u{1e5b}'), ('\u{1e5c}', '\u{1e5d}'), ('\u{1e5e}', '\u{1e5f}'), - ('\u{1e60}', '\u{1e61}'), ('\u{1e62}', '\u{1e63}'), ('\u{1e64}', '\u{1e65}'), - ('\u{1e66}', '\u{1e67}'), ('\u{1e68}', '\u{1e69}'), ('\u{1e6a}', '\u{1e6b}'), - ('\u{1e6c}', '\u{1e6d}'), ('\u{1e6e}', '\u{1e6f}'), ('\u{1e70}', '\u{1e71}'), - ('\u{1e72}', '\u{1e73}'), ('\u{1e74}', '\u{1e75}'), ('\u{1e76}', '\u{1e77}'), - ('\u{1e78}', '\u{1e79}'), ('\u{1e7a}', '\u{1e7b}'), ('\u{1e7c}', '\u{1e7d}'), - ('\u{1e7e}', '\u{1e7f}'), ('\u{1e80}', '\u{1e81}'), ('\u{1e82}', '\u{1e83}'), - ('\u{1e84}', '\u{1e85}'), ('\u{1e86}', '\u{1e87}'), ('\u{1e88}', '\u{1e89}'), - ('\u{1e8a}', '\u{1e8b}'), ('\u{1e8c}', '\u{1e8d}'), ('\u{1e8e}', '\u{1e8f}'), - ('\u{1e90}', '\u{1e91}'), ('\u{1e92}', '\u{1e93}'), ('\u{1e94}', '\u{1e95}'), - ('\u{1e9e}', '\u{df}'), ('\u{1ea0}', '\u{1ea1}'), ('\u{1ea2}', '\u{1ea3}'), - ('\u{1ea4}', '\u{1ea5}'), ('\u{1ea6}', '\u{1ea7}'), ('\u{1ea8}', '\u{1ea9}'), - ('\u{1eaa}', '\u{1eab}'), ('\u{1eac}', '\u{1ead}'), ('\u{1eae}', '\u{1eaf}'), - ('\u{1eb0}', '\u{1eb1}'), ('\u{1eb2}', '\u{1eb3}'), ('\u{1eb4}', '\u{1eb5}'), - ('\u{1eb6}', '\u{1eb7}'), ('\u{1eb8}', '\u{1eb9}'), ('\u{1eba}', '\u{1ebb}'), - ('\u{1ebc}', '\u{1ebd}'), ('\u{1ebe}', '\u{1ebf}'), ('\u{1ec0}', '\u{1ec1}'), - ('\u{1ec2}', '\u{1ec3}'), ('\u{1ec4}', '\u{1ec5}'), ('\u{1ec6}', '\u{1ec7}'), - ('\u{1ec8}', '\u{1ec9}'), ('\u{1eca}', '\u{1ecb}'), ('\u{1ecc}', '\u{1ecd}'), - ('\u{1ece}', '\u{1ecf}'), ('\u{1ed0}', '\u{1ed1}'), ('\u{1ed2}', '\u{1ed3}'), - ('\u{1ed4}', '\u{1ed5}'), ('\u{1ed6}', '\u{1ed7}'), ('\u{1ed8}', '\u{1ed9}'), - ('\u{1eda}', '\u{1edb}'), ('\u{1edc}', '\u{1edd}'), ('\u{1ede}', '\u{1edf}'), - ('\u{1ee0}', '\u{1ee1}'), ('\u{1ee2}', '\u{1ee3}'), ('\u{1ee4}', '\u{1ee5}'), - ('\u{1ee6}', '\u{1ee7}'), ('\u{1ee8}', '\u{1ee9}'), ('\u{1eea}', '\u{1eeb}'), - ('\u{1eec}', '\u{1eed}'), ('\u{1eee}', '\u{1eef}'), ('\u{1ef0}', '\u{1ef1}'), - ('\u{1ef2}', '\u{1ef3}'), ('\u{1ef4}', '\u{1ef5}'), ('\u{1ef6}', '\u{1ef7}'), - ('\u{1ef8}', '\u{1ef9}'), ('\u{1efa}', '\u{1efb}'), ('\u{1efc}', '\u{1efd}'), - ('\u{1efe}', '\u{1eff}'), ('\u{1f08}', '\u{1f00}'), ('\u{1f09}', '\u{1f01}'), - ('\u{1f0a}', '\u{1f02}'), ('\u{1f0b}', '\u{1f03}'), ('\u{1f0c}', '\u{1f04}'), - ('\u{1f0d}', '\u{1f05}'), ('\u{1f0e}', '\u{1f06}'), ('\u{1f0f}', '\u{1f07}'), - ('\u{1f18}', '\u{1f10}'), ('\u{1f19}', '\u{1f11}'), ('\u{1f1a}', '\u{1f12}'), - ('\u{1f1b}', '\u{1f13}'), ('\u{1f1c}', '\u{1f14}'), ('\u{1f1d}', '\u{1f15}'), - ('\u{1f28}', '\u{1f20}'), ('\u{1f29}', '\u{1f21}'), ('\u{1f2a}', '\u{1f22}'), - ('\u{1f2b}', '\u{1f23}'), ('\u{1f2c}', '\u{1f24}'), ('\u{1f2d}', '\u{1f25}'), - ('\u{1f2e}', '\u{1f26}'), ('\u{1f2f}', '\u{1f27}'), ('\u{1f38}', '\u{1f30}'), - ('\u{1f39}', '\u{1f31}'), ('\u{1f3a}', '\u{1f32}'), ('\u{1f3b}', '\u{1f33}'), - ('\u{1f3c}', '\u{1f34}'), ('\u{1f3d}', '\u{1f35}'), ('\u{1f3e}', '\u{1f36}'), - ('\u{1f3f}', '\u{1f37}'), ('\u{1f48}', '\u{1f40}'), ('\u{1f49}', '\u{1f41}'), - ('\u{1f4a}', '\u{1f42}'), ('\u{1f4b}', '\u{1f43}'), ('\u{1f4c}', '\u{1f44}'), - ('\u{1f4d}', '\u{1f45}'), ('\u{1f59}', '\u{1f51}'), ('\u{1f5b}', '\u{1f53}'), - ('\u{1f5d}', '\u{1f55}'), ('\u{1f5f}', '\u{1f57}'), ('\u{1f68}', '\u{1f60}'), - ('\u{1f69}', '\u{1f61}'), ('\u{1f6a}', '\u{1f62}'), ('\u{1f6b}', '\u{1f63}'), - ('\u{1f6c}', '\u{1f64}'), ('\u{1f6d}', '\u{1f65}'), ('\u{1f6e}', '\u{1f66}'), - ('\u{1f6f}', '\u{1f67}'), ('\u{1f88}', '\u{1f80}'), ('\u{1f89}', '\u{1f81}'), - ('\u{1f8a}', '\u{1f82}'), ('\u{1f8b}', '\u{1f83}'), ('\u{1f8c}', '\u{1f84}'), - ('\u{1f8d}', '\u{1f85}'), ('\u{1f8e}', '\u{1f86}'), ('\u{1f8f}', '\u{1f87}'), - ('\u{1f98}', '\u{1f90}'), ('\u{1f99}', '\u{1f91}'), ('\u{1f9a}', '\u{1f92}'), - ('\u{1f9b}', '\u{1f93}'), ('\u{1f9c}', '\u{1f94}'), ('\u{1f9d}', '\u{1f95}'), - ('\u{1f9e}', '\u{1f96}'), ('\u{1f9f}', '\u{1f97}'), ('\u{1fa8}', '\u{1fa0}'), - ('\u{1fa9}', '\u{1fa1}'), ('\u{1faa}', '\u{1fa2}'), ('\u{1fab}', '\u{1fa3}'), - ('\u{1fac}', '\u{1fa4}'), ('\u{1fad}', '\u{1fa5}'), ('\u{1fae}', '\u{1fa6}'), - ('\u{1faf}', '\u{1fa7}'), ('\u{1fb8}', '\u{1fb0}'), ('\u{1fb9}', '\u{1fb1}'), - ('\u{1fba}', '\u{1f70}'), ('\u{1fbb}', '\u{1f71}'), ('\u{1fbc}', '\u{1fb3}'), - ('\u{1fc8}', '\u{1f72}'), ('\u{1fc9}', '\u{1f73}'), ('\u{1fca}', '\u{1f74}'), - ('\u{1fcb}', '\u{1f75}'), ('\u{1fcc}', '\u{1fc3}'), ('\u{1fd8}', '\u{1fd0}'), - ('\u{1fd9}', '\u{1fd1}'), ('\u{1fda}', '\u{1f76}'), ('\u{1fdb}', '\u{1f77}'), - ('\u{1fe8}', '\u{1fe0}'), ('\u{1fe9}', '\u{1fe1}'), ('\u{1fea}', '\u{1f7a}'), - ('\u{1feb}', '\u{1f7b}'), ('\u{1fec}', '\u{1fe5}'), ('\u{1ff8}', '\u{1f78}'), - ('\u{1ff9}', '\u{1f79}'), ('\u{1ffa}', '\u{1f7c}'), ('\u{1ffb}', '\u{1f7d}'), - ('\u{1ffc}', '\u{1ff3}'), ('\u{2126}', '\u{3c9}'), ('\u{212a}', 'k'), - ('\u{212b}', '\u{e5}'), ('\u{2132}', '\u{214e}'), ('\u{2160}', '\u{2170}'), - ('\u{2161}', '\u{2171}'), ('\u{2162}', '\u{2172}'), ('\u{2163}', '\u{2173}'), - ('\u{2164}', '\u{2174}'), ('\u{2165}', '\u{2175}'), ('\u{2166}', '\u{2176}'), - ('\u{2167}', '\u{2177}'), ('\u{2168}', '\u{2178}'), ('\u{2169}', '\u{2179}'), - ('\u{216a}', '\u{217a}'), ('\u{216b}', '\u{217b}'), ('\u{216c}', '\u{217c}'), - ('\u{216d}', '\u{217d}'), ('\u{216e}', '\u{217e}'), ('\u{216f}', '\u{217f}'), - ('\u{2183}', '\u{2184}'), ('\u{24b6}', '\u{24d0}'), ('\u{24b7}', '\u{24d1}'), - ('\u{24b8}', '\u{24d2}'), ('\u{24b9}', '\u{24d3}'), ('\u{24ba}', '\u{24d4}'), - ('\u{24bb}', '\u{24d5}'), ('\u{24bc}', '\u{24d6}'), ('\u{24bd}', '\u{24d7}'), - ('\u{24be}', '\u{24d8}'), ('\u{24bf}', '\u{24d9}'), ('\u{24c0}', '\u{24da}'), - ('\u{24c1}', '\u{24db}'), ('\u{24c2}', '\u{24dc}'), ('\u{24c3}', '\u{24dd}'), - ('\u{24c4}', '\u{24de}'), ('\u{24c5}', '\u{24df}'), ('\u{24c6}', '\u{24e0}'), - ('\u{24c7}', '\u{24e1}'), ('\u{24c8}', '\u{24e2}'), ('\u{24c9}', '\u{24e3}'), - ('\u{24ca}', '\u{24e4}'), ('\u{24cb}', '\u{24e5}'), ('\u{24cc}', '\u{24e6}'), - ('\u{24cd}', '\u{24e7}'), ('\u{24ce}', '\u{24e8}'), ('\u{24cf}', '\u{24e9}'), - ('\u{2c00}', '\u{2c30}'), ('\u{2c01}', '\u{2c31}'), ('\u{2c02}', '\u{2c32}'), - ('\u{2c03}', '\u{2c33}'), ('\u{2c04}', '\u{2c34}'), ('\u{2c05}', '\u{2c35}'), - ('\u{2c06}', '\u{2c36}'), ('\u{2c07}', '\u{2c37}'), ('\u{2c08}', '\u{2c38}'), - ('\u{2c09}', '\u{2c39}'), ('\u{2c0a}', '\u{2c3a}'), ('\u{2c0b}', '\u{2c3b}'), - ('\u{2c0c}', '\u{2c3c}'), ('\u{2c0d}', '\u{2c3d}'), ('\u{2c0e}', '\u{2c3e}'), - ('\u{2c0f}', '\u{2c3f}'), ('\u{2c10}', '\u{2c40}'), ('\u{2c11}', '\u{2c41}'), - ('\u{2c12}', '\u{2c42}'), ('\u{2c13}', '\u{2c43}'), ('\u{2c14}', '\u{2c44}'), - ('\u{2c15}', '\u{2c45}'), ('\u{2c16}', '\u{2c46}'), ('\u{2c17}', '\u{2c47}'), - ('\u{2c18}', '\u{2c48}'), ('\u{2c19}', '\u{2c49}'), ('\u{2c1a}', '\u{2c4a}'), - ('\u{2c1b}', '\u{2c4b}'), ('\u{2c1c}', '\u{2c4c}'), ('\u{2c1d}', '\u{2c4d}'), - ('\u{2c1e}', '\u{2c4e}'), ('\u{2c1f}', '\u{2c4f}'), ('\u{2c20}', '\u{2c50}'), - ('\u{2c21}', '\u{2c51}'), ('\u{2c22}', '\u{2c52}'), ('\u{2c23}', '\u{2c53}'), - ('\u{2c24}', '\u{2c54}'), ('\u{2c25}', '\u{2c55}'), ('\u{2c26}', '\u{2c56}'), - ('\u{2c27}', '\u{2c57}'), ('\u{2c28}', '\u{2c58}'), ('\u{2c29}', '\u{2c59}'), - ('\u{2c2a}', '\u{2c5a}'), ('\u{2c2b}', '\u{2c5b}'), ('\u{2c2c}', '\u{2c5c}'), - ('\u{2c2d}', '\u{2c5d}'), ('\u{2c2e}', '\u{2c5e}'), ('\u{2c2f}', '\u{2c5f}'), - ('\u{2c60}', '\u{2c61}'), ('\u{2c62}', '\u{26b}'), ('\u{2c63}', '\u{1d7d}'), - ('\u{2c64}', '\u{27d}'), ('\u{2c67}', '\u{2c68}'), ('\u{2c69}', '\u{2c6a}'), - ('\u{2c6b}', '\u{2c6c}'), ('\u{2c6d}', '\u{251}'), ('\u{2c6e}', '\u{271}'), - ('\u{2c6f}', '\u{250}'), ('\u{2c70}', '\u{252}'), ('\u{2c72}', '\u{2c73}'), - ('\u{2c75}', '\u{2c76}'), ('\u{2c7e}', '\u{23f}'), ('\u{2c7f}', '\u{240}'), - ('\u{2c80}', '\u{2c81}'), ('\u{2c82}', '\u{2c83}'), ('\u{2c84}', '\u{2c85}'), - ('\u{2c86}', '\u{2c87}'), ('\u{2c88}', '\u{2c89}'), ('\u{2c8a}', '\u{2c8b}'), - ('\u{2c8c}', '\u{2c8d}'), ('\u{2c8e}', '\u{2c8f}'), ('\u{2c90}', '\u{2c91}'), - ('\u{2c92}', '\u{2c93}'), ('\u{2c94}', '\u{2c95}'), ('\u{2c96}', '\u{2c97}'), - ('\u{2c98}', '\u{2c99}'), ('\u{2c9a}', '\u{2c9b}'), ('\u{2c9c}', '\u{2c9d}'), - ('\u{2c9e}', '\u{2c9f}'), ('\u{2ca0}', '\u{2ca1}'), ('\u{2ca2}', '\u{2ca3}'), - ('\u{2ca4}', '\u{2ca5}'), ('\u{2ca6}', '\u{2ca7}'), ('\u{2ca8}', '\u{2ca9}'), - ('\u{2caa}', '\u{2cab}'), ('\u{2cac}', '\u{2cad}'), ('\u{2cae}', '\u{2caf}'), - ('\u{2cb0}', '\u{2cb1}'), ('\u{2cb2}', '\u{2cb3}'), ('\u{2cb4}', '\u{2cb5}'), - ('\u{2cb6}', '\u{2cb7}'), ('\u{2cb8}', '\u{2cb9}'), ('\u{2cba}', '\u{2cbb}'), - ('\u{2cbc}', '\u{2cbd}'), ('\u{2cbe}', '\u{2cbf}'), ('\u{2cc0}', '\u{2cc1}'), - ('\u{2cc2}', '\u{2cc3}'), ('\u{2cc4}', '\u{2cc5}'), ('\u{2cc6}', '\u{2cc7}'), - ('\u{2cc8}', '\u{2cc9}'), ('\u{2cca}', '\u{2ccb}'), ('\u{2ccc}', '\u{2ccd}'), - ('\u{2cce}', '\u{2ccf}'), ('\u{2cd0}', '\u{2cd1}'), ('\u{2cd2}', '\u{2cd3}'), - ('\u{2cd4}', '\u{2cd5}'), ('\u{2cd6}', '\u{2cd7}'), ('\u{2cd8}', '\u{2cd9}'), - ('\u{2cda}', '\u{2cdb}'), ('\u{2cdc}', '\u{2cdd}'), ('\u{2cde}', '\u{2cdf}'), - ('\u{2ce0}', '\u{2ce1}'), ('\u{2ce2}', '\u{2ce3}'), ('\u{2ceb}', '\u{2cec}'), - ('\u{2ced}', '\u{2cee}'), ('\u{2cf2}', '\u{2cf3}'), ('\u{a640}', '\u{a641}'), - ('\u{a642}', '\u{a643}'), ('\u{a644}', '\u{a645}'), ('\u{a646}', '\u{a647}'), - ('\u{a648}', '\u{a649}'), ('\u{a64a}', '\u{a64b}'), ('\u{a64c}', '\u{a64d}'), - ('\u{a64e}', '\u{a64f}'), ('\u{a650}', '\u{a651}'), ('\u{a652}', '\u{a653}'), - ('\u{a654}', '\u{a655}'), ('\u{a656}', '\u{a657}'), ('\u{a658}', '\u{a659}'), - ('\u{a65a}', '\u{a65b}'), ('\u{a65c}', '\u{a65d}'), ('\u{a65e}', '\u{a65f}'), - ('\u{a660}', '\u{a661}'), ('\u{a662}', '\u{a663}'), ('\u{a664}', '\u{a665}'), - ('\u{a666}', '\u{a667}'), ('\u{a668}', '\u{a669}'), ('\u{a66a}', '\u{a66b}'), - ('\u{a66c}', '\u{a66d}'), ('\u{a680}', '\u{a681}'), ('\u{a682}', '\u{a683}'), - ('\u{a684}', '\u{a685}'), ('\u{a686}', '\u{a687}'), ('\u{a688}', '\u{a689}'), - ('\u{a68a}', '\u{a68b}'), ('\u{a68c}', '\u{a68d}'), ('\u{a68e}', '\u{a68f}'), - ('\u{a690}', '\u{a691}'), ('\u{a692}', '\u{a693}'), ('\u{a694}', '\u{a695}'), - ('\u{a696}', '\u{a697}'), ('\u{a698}', '\u{a699}'), ('\u{a69a}', '\u{a69b}'), - ('\u{a722}', '\u{a723}'), ('\u{a724}', '\u{a725}'), ('\u{a726}', '\u{a727}'), - ('\u{a728}', '\u{a729}'), ('\u{a72a}', '\u{a72b}'), ('\u{a72c}', '\u{a72d}'), - ('\u{a72e}', '\u{a72f}'), ('\u{a732}', '\u{a733}'), ('\u{a734}', '\u{a735}'), - ('\u{a736}', '\u{a737}'), ('\u{a738}', '\u{a739}'), ('\u{a73a}', '\u{a73b}'), - ('\u{a73c}', '\u{a73d}'), ('\u{a73e}', '\u{a73f}'), ('\u{a740}', '\u{a741}'), - ('\u{a742}', '\u{a743}'), ('\u{a744}', '\u{a745}'), ('\u{a746}', '\u{a747}'), - ('\u{a748}', '\u{a749}'), ('\u{a74a}', '\u{a74b}'), ('\u{a74c}', '\u{a74d}'), - ('\u{a74e}', '\u{a74f}'), ('\u{a750}', '\u{a751}'), ('\u{a752}', '\u{a753}'), - ('\u{a754}', '\u{a755}'), ('\u{a756}', '\u{a757}'), ('\u{a758}', '\u{a759}'), - ('\u{a75a}', '\u{a75b}'), ('\u{a75c}', '\u{a75d}'), ('\u{a75e}', '\u{a75f}'), - ('\u{a760}', '\u{a761}'), ('\u{a762}', '\u{a763}'), ('\u{a764}', '\u{a765}'), - ('\u{a766}', '\u{a767}'), ('\u{a768}', '\u{a769}'), ('\u{a76a}', '\u{a76b}'), - ('\u{a76c}', '\u{a76d}'), ('\u{a76e}', '\u{a76f}'), ('\u{a779}', '\u{a77a}'), - ('\u{a77b}', '\u{a77c}'), ('\u{a77d}', '\u{1d79}'), ('\u{a77e}', '\u{a77f}'), - ('\u{a780}', '\u{a781}'), ('\u{a782}', '\u{a783}'), ('\u{a784}', '\u{a785}'), - ('\u{a786}', '\u{a787}'), ('\u{a78b}', '\u{a78c}'), ('\u{a78d}', '\u{265}'), - ('\u{a790}', '\u{a791}'), ('\u{a792}', '\u{a793}'), ('\u{a796}', '\u{a797}'), - ('\u{a798}', '\u{a799}'), ('\u{a79a}', '\u{a79b}'), ('\u{a79c}', '\u{a79d}'), - ('\u{a79e}', '\u{a79f}'), ('\u{a7a0}', '\u{a7a1}'), ('\u{a7a2}', '\u{a7a3}'), - ('\u{a7a4}', '\u{a7a5}'), ('\u{a7a6}', '\u{a7a7}'), ('\u{a7a8}', '\u{a7a9}'), - ('\u{a7aa}', '\u{266}'), ('\u{a7ab}', '\u{25c}'), ('\u{a7ac}', '\u{261}'), - ('\u{a7ad}', '\u{26c}'), ('\u{a7ae}', '\u{26a}'), ('\u{a7b0}', '\u{29e}'), - ('\u{a7b1}', '\u{287}'), ('\u{a7b2}', '\u{29d}'), ('\u{a7b3}', '\u{ab53}'), - ('\u{a7b4}', '\u{a7b5}'), ('\u{a7b6}', '\u{a7b7}'), ('\u{a7b8}', '\u{a7b9}'), - ('\u{a7ba}', '\u{a7bb}'), ('\u{a7bc}', '\u{a7bd}'), ('\u{a7be}', '\u{a7bf}'), - ('\u{a7c0}', '\u{a7c1}'), ('\u{a7c2}', '\u{a7c3}'), ('\u{a7c4}', '\u{a794}'), - ('\u{a7c5}', '\u{282}'), ('\u{a7c6}', '\u{1d8e}'), ('\u{a7c7}', '\u{a7c8}'), - ('\u{a7c9}', '\u{a7ca}'), ('\u{a7d0}', '\u{a7d1}'), ('\u{a7d6}', '\u{a7d7}'), - ('\u{a7d8}', '\u{a7d9}'), ('\u{a7f5}', '\u{a7f6}'), ('\u{ff21}', '\u{ff41}'), - ('\u{ff22}', '\u{ff42}'), ('\u{ff23}', '\u{ff43}'), ('\u{ff24}', '\u{ff44}'), - ('\u{ff25}', '\u{ff45}'), ('\u{ff26}', '\u{ff46}'), ('\u{ff27}', '\u{ff47}'), - ('\u{ff28}', '\u{ff48}'), ('\u{ff29}', '\u{ff49}'), ('\u{ff2a}', '\u{ff4a}'), - ('\u{ff2b}', '\u{ff4b}'), ('\u{ff2c}', '\u{ff4c}'), ('\u{ff2d}', '\u{ff4d}'), - ('\u{ff2e}', '\u{ff4e}'), ('\u{ff2f}', '\u{ff4f}'), ('\u{ff30}', '\u{ff50}'), - ('\u{ff31}', '\u{ff51}'), ('\u{ff32}', '\u{ff52}'), ('\u{ff33}', '\u{ff53}'), - ('\u{ff34}', '\u{ff54}'), ('\u{ff35}', '\u{ff55}'), ('\u{ff36}', '\u{ff56}'), - ('\u{ff37}', '\u{ff57}'), ('\u{ff38}', '\u{ff58}'), ('\u{ff39}', '\u{ff59}'), - ('\u{ff3a}', '\u{ff5a}'), ('\u{10400}', '\u{10428}'), ('\u{10401}', '\u{10429}'), - ('\u{10402}', '\u{1042a}'), ('\u{10403}', '\u{1042b}'), ('\u{10404}', '\u{1042c}'), - ('\u{10405}', '\u{1042d}'), ('\u{10406}', '\u{1042e}'), ('\u{10407}', '\u{1042f}'), - ('\u{10408}', '\u{10430}'), ('\u{10409}', '\u{10431}'), ('\u{1040a}', '\u{10432}'), - ('\u{1040b}', '\u{10433}'), ('\u{1040c}', '\u{10434}'), ('\u{1040d}', '\u{10435}'), - ('\u{1040e}', '\u{10436}'), ('\u{1040f}', '\u{10437}'), ('\u{10410}', '\u{10438}'), - ('\u{10411}', '\u{10439}'), ('\u{10412}', '\u{1043a}'), ('\u{10413}', '\u{1043b}'), - ('\u{10414}', '\u{1043c}'), ('\u{10415}', '\u{1043d}'), ('\u{10416}', '\u{1043e}'), - ('\u{10417}', '\u{1043f}'), ('\u{10418}', '\u{10440}'), ('\u{10419}', '\u{10441}'), - ('\u{1041a}', '\u{10442}'), ('\u{1041b}', '\u{10443}'), ('\u{1041c}', '\u{10444}'), - ('\u{1041d}', '\u{10445}'), ('\u{1041e}', '\u{10446}'), ('\u{1041f}', '\u{10447}'), - ('\u{10420}', '\u{10448}'), ('\u{10421}', '\u{10449}'), ('\u{10422}', '\u{1044a}'), - ('\u{10423}', '\u{1044b}'), ('\u{10424}', '\u{1044c}'), ('\u{10425}', '\u{1044d}'), - ('\u{10426}', '\u{1044e}'), ('\u{10427}', '\u{1044f}'), ('\u{104b0}', '\u{104d8}'), - ('\u{104b1}', '\u{104d9}'), ('\u{104b2}', '\u{104da}'), ('\u{104b3}', '\u{104db}'), - ('\u{104b4}', '\u{104dc}'), ('\u{104b5}', '\u{104dd}'), ('\u{104b6}', '\u{104de}'), - ('\u{104b7}', '\u{104df}'), ('\u{104b8}', '\u{104e0}'), ('\u{104b9}', '\u{104e1}'), - ('\u{104ba}', '\u{104e2}'), ('\u{104bb}', '\u{104e3}'), ('\u{104bc}', '\u{104e4}'), - ('\u{104bd}', '\u{104e5}'), ('\u{104be}', '\u{104e6}'), ('\u{104bf}', '\u{104e7}'), - ('\u{104c0}', '\u{104e8}'), ('\u{104c1}', '\u{104e9}'), ('\u{104c2}', '\u{104ea}'), - ('\u{104c3}', '\u{104eb}'), ('\u{104c4}', '\u{104ec}'), ('\u{104c5}', '\u{104ed}'), - ('\u{104c6}', '\u{104ee}'), ('\u{104c7}', '\u{104ef}'), ('\u{104c8}', '\u{104f0}'), - ('\u{104c9}', '\u{104f1}'), ('\u{104ca}', '\u{104f2}'), ('\u{104cb}', '\u{104f3}'), - ('\u{104cc}', '\u{104f4}'), ('\u{104cd}', '\u{104f5}'), ('\u{104ce}', '\u{104f6}'), - ('\u{104cf}', '\u{104f7}'), ('\u{104d0}', '\u{104f8}'), ('\u{104d1}', '\u{104f9}'), - ('\u{104d2}', '\u{104fa}'), ('\u{104d3}', '\u{104fb}'), ('\u{10570}', '\u{10597}'), - ('\u{10571}', '\u{10598}'), ('\u{10572}', '\u{10599}'), ('\u{10573}', '\u{1059a}'), - ('\u{10574}', '\u{1059b}'), ('\u{10575}', '\u{1059c}'), ('\u{10576}', '\u{1059d}'), - ('\u{10577}', '\u{1059e}'), ('\u{10578}', '\u{1059f}'), ('\u{10579}', '\u{105a0}'), - ('\u{1057a}', '\u{105a1}'), ('\u{1057c}', '\u{105a3}'), ('\u{1057d}', '\u{105a4}'), - ('\u{1057e}', '\u{105a5}'), ('\u{1057f}', '\u{105a6}'), ('\u{10580}', '\u{105a7}'), - ('\u{10581}', '\u{105a8}'), ('\u{10582}', '\u{105a9}'), ('\u{10583}', '\u{105aa}'), - ('\u{10584}', '\u{105ab}'), ('\u{10585}', '\u{105ac}'), ('\u{10586}', '\u{105ad}'), - ('\u{10587}', '\u{105ae}'), ('\u{10588}', '\u{105af}'), ('\u{10589}', '\u{105b0}'), - ('\u{1058a}', '\u{105b1}'), ('\u{1058c}', '\u{105b3}'), ('\u{1058d}', '\u{105b4}'), - ('\u{1058e}', '\u{105b5}'), ('\u{1058f}', '\u{105b6}'), ('\u{10590}', '\u{105b7}'), - ('\u{10591}', '\u{105b8}'), ('\u{10592}', '\u{105b9}'), ('\u{10594}', '\u{105bb}'), - ('\u{10595}', '\u{105bc}'), ('\u{10c80}', '\u{10cc0}'), ('\u{10c81}', '\u{10cc1}'), - ('\u{10c82}', '\u{10cc2}'), ('\u{10c83}', '\u{10cc3}'), ('\u{10c84}', '\u{10cc4}'), - ('\u{10c85}', '\u{10cc5}'), ('\u{10c86}', '\u{10cc6}'), ('\u{10c87}', '\u{10cc7}'), - ('\u{10c88}', '\u{10cc8}'), ('\u{10c89}', '\u{10cc9}'), ('\u{10c8a}', '\u{10cca}'), - ('\u{10c8b}', '\u{10ccb}'), ('\u{10c8c}', '\u{10ccc}'), ('\u{10c8d}', '\u{10ccd}'), - ('\u{10c8e}', '\u{10cce}'), ('\u{10c8f}', '\u{10ccf}'), ('\u{10c90}', '\u{10cd0}'), - ('\u{10c91}', '\u{10cd1}'), ('\u{10c92}', '\u{10cd2}'), ('\u{10c93}', '\u{10cd3}'), - ('\u{10c94}', '\u{10cd4}'), ('\u{10c95}', '\u{10cd5}'), ('\u{10c96}', '\u{10cd6}'), - ('\u{10c97}', '\u{10cd7}'), ('\u{10c98}', '\u{10cd8}'), ('\u{10c99}', '\u{10cd9}'), - ('\u{10c9a}', '\u{10cda}'), ('\u{10c9b}', '\u{10cdb}'), ('\u{10c9c}', '\u{10cdc}'), - ('\u{10c9d}', '\u{10cdd}'), ('\u{10c9e}', '\u{10cde}'), ('\u{10c9f}', '\u{10cdf}'), - ('\u{10ca0}', '\u{10ce0}'), ('\u{10ca1}', '\u{10ce1}'), ('\u{10ca2}', '\u{10ce2}'), - ('\u{10ca3}', '\u{10ce3}'), ('\u{10ca4}', '\u{10ce4}'), ('\u{10ca5}', '\u{10ce5}'), - ('\u{10ca6}', '\u{10ce6}'), ('\u{10ca7}', '\u{10ce7}'), ('\u{10ca8}', '\u{10ce8}'), - ('\u{10ca9}', '\u{10ce9}'), ('\u{10caa}', '\u{10cea}'), ('\u{10cab}', '\u{10ceb}'), - ('\u{10cac}', '\u{10cec}'), ('\u{10cad}', '\u{10ced}'), ('\u{10cae}', '\u{10cee}'), - ('\u{10caf}', '\u{10cef}'), ('\u{10cb0}', '\u{10cf0}'), ('\u{10cb1}', '\u{10cf1}'), - ('\u{10cb2}', '\u{10cf2}'), ('\u{118a0}', '\u{118c0}'), ('\u{118a1}', '\u{118c1}'), - ('\u{118a2}', '\u{118c2}'), ('\u{118a3}', '\u{118c3}'), ('\u{118a4}', '\u{118c4}'), - ('\u{118a5}', '\u{118c5}'), ('\u{118a6}', '\u{118c6}'), ('\u{118a7}', '\u{118c7}'), - ('\u{118a8}', '\u{118c8}'), ('\u{118a9}', '\u{118c9}'), ('\u{118aa}', '\u{118ca}'), - ('\u{118ab}', '\u{118cb}'), ('\u{118ac}', '\u{118cc}'), ('\u{118ad}', '\u{118cd}'), - ('\u{118ae}', '\u{118ce}'), ('\u{118af}', '\u{118cf}'), ('\u{118b0}', '\u{118d0}'), - ('\u{118b1}', '\u{118d1}'), ('\u{118b2}', '\u{118d2}'), ('\u{118b3}', '\u{118d3}'), - ('\u{118b4}', '\u{118d4}'), ('\u{118b5}', '\u{118d5}'), ('\u{118b6}', '\u{118d6}'), - ('\u{118b7}', '\u{118d7}'), ('\u{118b8}', '\u{118d8}'), ('\u{118b9}', '\u{118d9}'), - ('\u{118ba}', '\u{118da}'), ('\u{118bb}', '\u{118db}'), ('\u{118bc}', '\u{118dc}'), - ('\u{118bd}', '\u{118dd}'), ('\u{118be}', '\u{118de}'), ('\u{118bf}', '\u{118df}'), - ('\u{16e40}', '\u{16e60}'), ('\u{16e41}', '\u{16e61}'), ('\u{16e42}', '\u{16e62}'), - ('\u{16e43}', '\u{16e63}'), ('\u{16e44}', '\u{16e64}'), ('\u{16e45}', '\u{16e65}'), - ('\u{16e46}', '\u{16e66}'), ('\u{16e47}', '\u{16e67}'), ('\u{16e48}', '\u{16e68}'), - ('\u{16e49}', '\u{16e69}'), ('\u{16e4a}', '\u{16e6a}'), ('\u{16e4b}', '\u{16e6b}'), - ('\u{16e4c}', '\u{16e6c}'), ('\u{16e4d}', '\u{16e6d}'), ('\u{16e4e}', '\u{16e6e}'), - ('\u{16e4f}', '\u{16e6f}'), ('\u{16e50}', '\u{16e70}'), ('\u{16e51}', '\u{16e71}'), - ('\u{16e52}', '\u{16e72}'), ('\u{16e53}', '\u{16e73}'), ('\u{16e54}', '\u{16e74}'), - ('\u{16e55}', '\u{16e75}'), ('\u{16e56}', '\u{16e76}'), ('\u{16e57}', '\u{16e77}'), - ('\u{16e58}', '\u{16e78}'), ('\u{16e59}', '\u{16e79}'), ('\u{16e5a}', '\u{16e7a}'), - ('\u{16e5b}', '\u{16e7b}'), ('\u{16e5c}', '\u{16e7c}'), ('\u{16e5d}', '\u{16e7d}'), - ('\u{16e5e}', '\u{16e7e}'), ('\u{16e5f}', '\u{16e7f}'), ('\u{1e900}', '\u{1e922}'), - ('\u{1e901}', '\u{1e923}'), ('\u{1e902}', '\u{1e924}'), ('\u{1e903}', '\u{1e925}'), - ('\u{1e904}', '\u{1e926}'), ('\u{1e905}', '\u{1e927}'), ('\u{1e906}', '\u{1e928}'), - ('\u{1e907}', '\u{1e929}'), ('\u{1e908}', '\u{1e92a}'), ('\u{1e909}', '\u{1e92b}'), - ('\u{1e90a}', '\u{1e92c}'), ('\u{1e90b}', '\u{1e92d}'), ('\u{1e90c}', '\u{1e92e}'), - ('\u{1e90d}', '\u{1e92f}'), ('\u{1e90e}', '\u{1e930}'), ('\u{1e90f}', '\u{1e931}'), - ('\u{1e910}', '\u{1e932}'), ('\u{1e911}', '\u{1e933}'), ('\u{1e912}', '\u{1e934}'), - ('\u{1e913}', '\u{1e935}'), ('\u{1e914}', '\u{1e936}'), ('\u{1e915}', '\u{1e937}'), - ('\u{1e916}', '\u{1e938}'), ('\u{1e917}', '\u{1e939}'), ('\u{1e918}', '\u{1e93a}'), - ('\u{1e919}', '\u{1e93b}'), ('\u{1e91a}', '\u{1e93c}'), ('\u{1e91b}', '\u{1e93d}'), - ('\u{1e91c}', '\u{1e93e}'), ('\u{1e91d}', '\u{1e93f}'), ('\u{1e91e}', '\u{1e940}'), - ('\u{1e91f}', '\u{1e941}'), ('\u{1e920}', '\u{1e942}'), ('\u{1e921}', '\u{1e943}'), + static LOWERCASE_TABLE: &[(char, u32)] = &[ + ('\u{c0}', 224), ('\u{c1}', 225), ('\u{c2}', 226), ('\u{c3}', 227), ('\u{c4}', 228), + ('\u{c5}', 229), ('\u{c6}', 230), ('\u{c7}', 231), ('\u{c8}', 232), ('\u{c9}', 233), + ('\u{ca}', 234), ('\u{cb}', 235), ('\u{cc}', 236), ('\u{cd}', 237), ('\u{ce}', 238), + ('\u{cf}', 239), ('\u{d0}', 240), ('\u{d1}', 241), ('\u{d2}', 242), ('\u{d3}', 243), + ('\u{d4}', 244), ('\u{d5}', 245), ('\u{d6}', 246), ('\u{d8}', 248), ('\u{d9}', 249), + ('\u{da}', 250), ('\u{db}', 251), ('\u{dc}', 252), ('\u{dd}', 253), ('\u{de}', 254), + ('\u{100}', 257), ('\u{102}', 259), ('\u{104}', 261), ('\u{106}', 263), ('\u{108}', 265), + ('\u{10a}', 267), ('\u{10c}', 269), ('\u{10e}', 271), ('\u{110}', 273), ('\u{112}', 275), + ('\u{114}', 277), ('\u{116}', 279), ('\u{118}', 281), ('\u{11a}', 283), ('\u{11c}', 285), + ('\u{11e}', 287), ('\u{120}', 289), ('\u{122}', 291), ('\u{124}', 293), ('\u{126}', 295), + ('\u{128}', 297), ('\u{12a}', 299), ('\u{12c}', 301), ('\u{12e}', 303), + ('\u{130}', 4194304), ('\u{132}', 307), ('\u{134}', 309), ('\u{136}', 311), + ('\u{139}', 314), ('\u{13b}', 316), ('\u{13d}', 318), ('\u{13f}', 320), ('\u{141}', 322), + ('\u{143}', 324), ('\u{145}', 326), ('\u{147}', 328), ('\u{14a}', 331), ('\u{14c}', 333), + ('\u{14e}', 335), ('\u{150}', 337), ('\u{152}', 339), ('\u{154}', 341), ('\u{156}', 343), + ('\u{158}', 345), ('\u{15a}', 347), ('\u{15c}', 349), ('\u{15e}', 351), ('\u{160}', 353), + ('\u{162}', 355), ('\u{164}', 357), ('\u{166}', 359), ('\u{168}', 361), ('\u{16a}', 363), + ('\u{16c}', 365), ('\u{16e}', 367), ('\u{170}', 369), ('\u{172}', 371), ('\u{174}', 373), + ('\u{176}', 375), ('\u{178}', 255), ('\u{179}', 378), ('\u{17b}', 380), ('\u{17d}', 382), + ('\u{181}', 595), ('\u{182}', 387), ('\u{184}', 389), ('\u{186}', 596), ('\u{187}', 392), + ('\u{189}', 598), ('\u{18a}', 599), ('\u{18b}', 396), ('\u{18e}', 477), ('\u{18f}', 601), + ('\u{190}', 603), ('\u{191}', 402), ('\u{193}', 608), ('\u{194}', 611), ('\u{196}', 617), + ('\u{197}', 616), ('\u{198}', 409), ('\u{19c}', 623), ('\u{19d}', 626), ('\u{19f}', 629), + ('\u{1a0}', 417), ('\u{1a2}', 419), ('\u{1a4}', 421), ('\u{1a6}', 640), ('\u{1a7}', 424), + ('\u{1a9}', 643), ('\u{1ac}', 429), ('\u{1ae}', 648), ('\u{1af}', 432), ('\u{1b1}', 650), + ('\u{1b2}', 651), ('\u{1b3}', 436), ('\u{1b5}', 438), ('\u{1b7}', 658), ('\u{1b8}', 441), + ('\u{1bc}', 445), ('\u{1c4}', 454), ('\u{1c5}', 454), ('\u{1c7}', 457), ('\u{1c8}', 457), + ('\u{1ca}', 460), ('\u{1cb}', 460), ('\u{1cd}', 462), ('\u{1cf}', 464), ('\u{1d1}', 466), + ('\u{1d3}', 468), ('\u{1d5}', 470), ('\u{1d7}', 472), ('\u{1d9}', 474), ('\u{1db}', 476), + ('\u{1de}', 479), ('\u{1e0}', 481), ('\u{1e2}', 483), ('\u{1e4}', 485), ('\u{1e6}', 487), + ('\u{1e8}', 489), ('\u{1ea}', 491), ('\u{1ec}', 493), ('\u{1ee}', 495), ('\u{1f1}', 499), + ('\u{1f2}', 499), ('\u{1f4}', 501), ('\u{1f6}', 405), ('\u{1f7}', 447), ('\u{1f8}', 505), + ('\u{1fa}', 507), ('\u{1fc}', 509), ('\u{1fe}', 511), ('\u{200}', 513), ('\u{202}', 515), + ('\u{204}', 517), ('\u{206}', 519), ('\u{208}', 521), ('\u{20a}', 523), ('\u{20c}', 525), + ('\u{20e}', 527), ('\u{210}', 529), ('\u{212}', 531), ('\u{214}', 533), ('\u{216}', 535), + ('\u{218}', 537), ('\u{21a}', 539), ('\u{21c}', 541), ('\u{21e}', 543), ('\u{220}', 414), + ('\u{222}', 547), ('\u{224}', 549), ('\u{226}', 551), ('\u{228}', 553), ('\u{22a}', 555), + ('\u{22c}', 557), ('\u{22e}', 559), ('\u{230}', 561), ('\u{232}', 563), ('\u{23a}', 11365), + ('\u{23b}', 572), ('\u{23d}', 410), ('\u{23e}', 11366), ('\u{241}', 578), ('\u{243}', 384), + ('\u{244}', 649), ('\u{245}', 652), ('\u{246}', 583), ('\u{248}', 585), ('\u{24a}', 587), + ('\u{24c}', 589), ('\u{24e}', 591), ('\u{370}', 881), ('\u{372}', 883), ('\u{376}', 887), + ('\u{37f}', 1011), ('\u{386}', 940), ('\u{388}', 941), ('\u{389}', 942), ('\u{38a}', 943), + ('\u{38c}', 972), ('\u{38e}', 973), ('\u{38f}', 974), ('\u{391}', 945), ('\u{392}', 946), + ('\u{393}', 947), ('\u{394}', 948), ('\u{395}', 949), ('\u{396}', 950), ('\u{397}', 951), + ('\u{398}', 952), ('\u{399}', 953), ('\u{39a}', 954), ('\u{39b}', 955), ('\u{39c}', 956), + ('\u{39d}', 957), ('\u{39e}', 958), ('\u{39f}', 959), ('\u{3a0}', 960), ('\u{3a1}', 961), + ('\u{3a3}', 963), ('\u{3a4}', 964), ('\u{3a5}', 965), ('\u{3a6}', 966), ('\u{3a7}', 967), + ('\u{3a8}', 968), ('\u{3a9}', 969), ('\u{3aa}', 970), ('\u{3ab}', 971), ('\u{3cf}', 983), + ('\u{3d8}', 985), ('\u{3da}', 987), ('\u{3dc}', 989), ('\u{3de}', 991), ('\u{3e0}', 993), + ('\u{3e2}', 995), ('\u{3e4}', 997), ('\u{3e6}', 999), ('\u{3e8}', 1001), ('\u{3ea}', 1003), + ('\u{3ec}', 1005), ('\u{3ee}', 1007), ('\u{3f4}', 952), ('\u{3f7}', 1016), + ('\u{3f9}', 1010), ('\u{3fa}', 1019), ('\u{3fd}', 891), ('\u{3fe}', 892), ('\u{3ff}', 893), + ('\u{400}', 1104), ('\u{401}', 1105), ('\u{402}', 1106), ('\u{403}', 1107), + ('\u{404}', 1108), ('\u{405}', 1109), ('\u{406}', 1110), ('\u{407}', 1111), + ('\u{408}', 1112), ('\u{409}', 1113), ('\u{40a}', 1114), ('\u{40b}', 1115), + ('\u{40c}', 1116), ('\u{40d}', 1117), ('\u{40e}', 1118), ('\u{40f}', 1119), + ('\u{410}', 1072), ('\u{411}', 1073), ('\u{412}', 1074), ('\u{413}', 1075), + ('\u{414}', 1076), ('\u{415}', 1077), ('\u{416}', 1078), ('\u{417}', 1079), + ('\u{418}', 1080), ('\u{419}', 1081), ('\u{41a}', 1082), ('\u{41b}', 1083), + ('\u{41c}', 1084), ('\u{41d}', 1085), ('\u{41e}', 1086), ('\u{41f}', 1087), + ('\u{420}', 1088), ('\u{421}', 1089), ('\u{422}', 1090), ('\u{423}', 1091), + ('\u{424}', 1092), ('\u{425}', 1093), ('\u{426}', 1094), ('\u{427}', 1095), + ('\u{428}', 1096), ('\u{429}', 1097), ('\u{42a}', 1098), ('\u{42b}', 1099), + ('\u{42c}', 1100), ('\u{42d}', 1101), ('\u{42e}', 1102), ('\u{42f}', 1103), + ('\u{460}', 1121), ('\u{462}', 1123), ('\u{464}', 1125), ('\u{466}', 1127), + ('\u{468}', 1129), ('\u{46a}', 1131), ('\u{46c}', 1133), ('\u{46e}', 1135), + ('\u{470}', 1137), ('\u{472}', 1139), ('\u{474}', 1141), ('\u{476}', 1143), + ('\u{478}', 1145), ('\u{47a}', 1147), ('\u{47c}', 1149), ('\u{47e}', 1151), + ('\u{480}', 1153), ('\u{48a}', 1163), ('\u{48c}', 1165), ('\u{48e}', 1167), + ('\u{490}', 1169), ('\u{492}', 1171), ('\u{494}', 1173), ('\u{496}', 1175), + ('\u{498}', 1177), ('\u{49a}', 1179), ('\u{49c}', 1181), ('\u{49e}', 1183), + ('\u{4a0}', 1185), ('\u{4a2}', 1187), ('\u{4a4}', 1189), ('\u{4a6}', 1191), + ('\u{4a8}', 1193), ('\u{4aa}', 1195), ('\u{4ac}', 1197), ('\u{4ae}', 1199), + ('\u{4b0}', 1201), ('\u{4b2}', 1203), ('\u{4b4}', 1205), ('\u{4b6}', 1207), + ('\u{4b8}', 1209), ('\u{4ba}', 1211), ('\u{4bc}', 1213), ('\u{4be}', 1215), + ('\u{4c0}', 1231), ('\u{4c1}', 1218), ('\u{4c3}', 1220), ('\u{4c5}', 1222), + ('\u{4c7}', 1224), ('\u{4c9}', 1226), ('\u{4cb}', 1228), ('\u{4cd}', 1230), + ('\u{4d0}', 1233), ('\u{4d2}', 1235), ('\u{4d4}', 1237), ('\u{4d6}', 1239), + ('\u{4d8}', 1241), ('\u{4da}', 1243), ('\u{4dc}', 1245), ('\u{4de}', 1247), + ('\u{4e0}', 1249), ('\u{4e2}', 1251), ('\u{4e4}', 1253), ('\u{4e6}', 1255), + ('\u{4e8}', 1257), ('\u{4ea}', 1259), ('\u{4ec}', 1261), ('\u{4ee}', 1263), + ('\u{4f0}', 1265), ('\u{4f2}', 1267), ('\u{4f4}', 1269), ('\u{4f6}', 1271), + ('\u{4f8}', 1273), ('\u{4fa}', 1275), ('\u{4fc}', 1277), ('\u{4fe}', 1279), + ('\u{500}', 1281), ('\u{502}', 1283), ('\u{504}', 1285), ('\u{506}', 1287), + ('\u{508}', 1289), ('\u{50a}', 1291), ('\u{50c}', 1293), ('\u{50e}', 1295), + ('\u{510}', 1297), ('\u{512}', 1299), ('\u{514}', 1301), ('\u{516}', 1303), + ('\u{518}', 1305), ('\u{51a}', 1307), ('\u{51c}', 1309), ('\u{51e}', 1311), + ('\u{520}', 1313), ('\u{522}', 1315), ('\u{524}', 1317), ('\u{526}', 1319), + ('\u{528}', 1321), ('\u{52a}', 1323), ('\u{52c}', 1325), ('\u{52e}', 1327), + ('\u{531}', 1377), ('\u{532}', 1378), ('\u{533}', 1379), ('\u{534}', 1380), + ('\u{535}', 1381), ('\u{536}', 1382), ('\u{537}', 1383), ('\u{538}', 1384), + ('\u{539}', 1385), ('\u{53a}', 1386), ('\u{53b}', 1387), ('\u{53c}', 1388), + ('\u{53d}', 1389), ('\u{53e}', 1390), ('\u{53f}', 1391), ('\u{540}', 1392), + ('\u{541}', 1393), ('\u{542}', 1394), ('\u{543}', 1395), ('\u{544}', 1396), + ('\u{545}', 1397), ('\u{546}', 1398), ('\u{547}', 1399), ('\u{548}', 1400), + ('\u{549}', 1401), ('\u{54a}', 1402), ('\u{54b}', 1403), ('\u{54c}', 1404), + ('\u{54d}', 1405), ('\u{54e}', 1406), ('\u{54f}', 1407), ('\u{550}', 1408), + ('\u{551}', 1409), ('\u{552}', 1410), ('\u{553}', 1411), ('\u{554}', 1412), + ('\u{555}', 1413), ('\u{556}', 1414), ('\u{10a0}', 11520), ('\u{10a1}', 11521), + ('\u{10a2}', 11522), ('\u{10a3}', 11523), ('\u{10a4}', 11524), ('\u{10a5}', 11525), + ('\u{10a6}', 11526), ('\u{10a7}', 11527), ('\u{10a8}', 11528), ('\u{10a9}', 11529), + ('\u{10aa}', 11530), ('\u{10ab}', 11531), ('\u{10ac}', 11532), ('\u{10ad}', 11533), + ('\u{10ae}', 11534), ('\u{10af}', 11535), ('\u{10b0}', 11536), ('\u{10b1}', 11537), + ('\u{10b2}', 11538), ('\u{10b3}', 11539), ('\u{10b4}', 11540), ('\u{10b5}', 11541), + ('\u{10b6}', 11542), ('\u{10b7}', 11543), ('\u{10b8}', 11544), ('\u{10b9}', 11545), + ('\u{10ba}', 11546), ('\u{10bb}', 11547), ('\u{10bc}', 11548), ('\u{10bd}', 11549), + ('\u{10be}', 11550), ('\u{10bf}', 11551), ('\u{10c0}', 11552), ('\u{10c1}', 11553), + ('\u{10c2}', 11554), ('\u{10c3}', 11555), ('\u{10c4}', 11556), ('\u{10c5}', 11557), + ('\u{10c7}', 11559), ('\u{10cd}', 11565), ('\u{13a0}', 43888), ('\u{13a1}', 43889), + ('\u{13a2}', 43890), ('\u{13a3}', 43891), ('\u{13a4}', 43892), ('\u{13a5}', 43893), + ('\u{13a6}', 43894), ('\u{13a7}', 43895), ('\u{13a8}', 43896), ('\u{13a9}', 43897), + ('\u{13aa}', 43898), ('\u{13ab}', 43899), ('\u{13ac}', 43900), ('\u{13ad}', 43901), + ('\u{13ae}', 43902), ('\u{13af}', 43903), ('\u{13b0}', 43904), ('\u{13b1}', 43905), + ('\u{13b2}', 43906), ('\u{13b3}', 43907), ('\u{13b4}', 43908), ('\u{13b5}', 43909), + ('\u{13b6}', 43910), ('\u{13b7}', 43911), ('\u{13b8}', 43912), ('\u{13b9}', 43913), + ('\u{13ba}', 43914), ('\u{13bb}', 43915), ('\u{13bc}', 43916), ('\u{13bd}', 43917), + ('\u{13be}', 43918), ('\u{13bf}', 43919), ('\u{13c0}', 43920), ('\u{13c1}', 43921), + ('\u{13c2}', 43922), ('\u{13c3}', 43923), ('\u{13c4}', 43924), ('\u{13c5}', 43925), + ('\u{13c6}', 43926), ('\u{13c7}', 43927), ('\u{13c8}', 43928), ('\u{13c9}', 43929), + ('\u{13ca}', 43930), ('\u{13cb}', 43931), ('\u{13cc}', 43932), ('\u{13cd}', 43933), + ('\u{13ce}', 43934), ('\u{13cf}', 43935), ('\u{13d0}', 43936), ('\u{13d1}', 43937), + ('\u{13d2}', 43938), ('\u{13d3}', 43939), ('\u{13d4}', 43940), ('\u{13d5}', 43941), + ('\u{13d6}', 43942), ('\u{13d7}', 43943), ('\u{13d8}', 43944), ('\u{13d9}', 43945), + ('\u{13da}', 43946), ('\u{13db}', 43947), ('\u{13dc}', 43948), ('\u{13dd}', 43949), + ('\u{13de}', 43950), ('\u{13df}', 43951), ('\u{13e0}', 43952), ('\u{13e1}', 43953), + ('\u{13e2}', 43954), ('\u{13e3}', 43955), ('\u{13e4}', 43956), ('\u{13e5}', 43957), + ('\u{13e6}', 43958), ('\u{13e7}', 43959), ('\u{13e8}', 43960), ('\u{13e9}', 43961), + ('\u{13ea}', 43962), ('\u{13eb}', 43963), ('\u{13ec}', 43964), ('\u{13ed}', 43965), + ('\u{13ee}', 43966), ('\u{13ef}', 43967), ('\u{13f0}', 5112), ('\u{13f1}', 5113), + ('\u{13f2}', 5114), ('\u{13f3}', 5115), ('\u{13f4}', 5116), ('\u{13f5}', 5117), + ('\u{1c90}', 4304), ('\u{1c91}', 4305), ('\u{1c92}', 4306), ('\u{1c93}', 4307), + ('\u{1c94}', 4308), ('\u{1c95}', 4309), ('\u{1c96}', 4310), ('\u{1c97}', 4311), + ('\u{1c98}', 4312), ('\u{1c99}', 4313), ('\u{1c9a}', 4314), ('\u{1c9b}', 4315), + ('\u{1c9c}', 4316), ('\u{1c9d}', 4317), ('\u{1c9e}', 4318), ('\u{1c9f}', 4319), + ('\u{1ca0}', 4320), ('\u{1ca1}', 4321), ('\u{1ca2}', 4322), ('\u{1ca3}', 4323), + ('\u{1ca4}', 4324), ('\u{1ca5}', 4325), ('\u{1ca6}', 4326), ('\u{1ca7}', 4327), + ('\u{1ca8}', 4328), ('\u{1ca9}', 4329), ('\u{1caa}', 4330), ('\u{1cab}', 4331), + ('\u{1cac}', 4332), ('\u{1cad}', 4333), ('\u{1cae}', 4334), ('\u{1caf}', 4335), + ('\u{1cb0}', 4336), ('\u{1cb1}', 4337), ('\u{1cb2}', 4338), ('\u{1cb3}', 4339), + ('\u{1cb4}', 4340), ('\u{1cb5}', 4341), ('\u{1cb6}', 4342), ('\u{1cb7}', 4343), + ('\u{1cb8}', 4344), ('\u{1cb9}', 4345), ('\u{1cba}', 4346), ('\u{1cbd}', 4349), + ('\u{1cbe}', 4350), ('\u{1cbf}', 4351), ('\u{1e00}', 7681), ('\u{1e02}', 7683), + ('\u{1e04}', 7685), ('\u{1e06}', 7687), ('\u{1e08}', 7689), ('\u{1e0a}', 7691), + ('\u{1e0c}', 7693), ('\u{1e0e}', 7695), ('\u{1e10}', 7697), ('\u{1e12}', 7699), + ('\u{1e14}', 7701), ('\u{1e16}', 7703), ('\u{1e18}', 7705), ('\u{1e1a}', 7707), + ('\u{1e1c}', 7709), ('\u{1e1e}', 7711), ('\u{1e20}', 7713), ('\u{1e22}', 7715), + ('\u{1e24}', 7717), ('\u{1e26}', 7719), ('\u{1e28}', 7721), ('\u{1e2a}', 7723), + ('\u{1e2c}', 7725), ('\u{1e2e}', 7727), ('\u{1e30}', 7729), ('\u{1e32}', 7731), + ('\u{1e34}', 7733), ('\u{1e36}', 7735), ('\u{1e38}', 7737), ('\u{1e3a}', 7739), + ('\u{1e3c}', 7741), ('\u{1e3e}', 7743), ('\u{1e40}', 7745), ('\u{1e42}', 7747), + ('\u{1e44}', 7749), ('\u{1e46}', 7751), ('\u{1e48}', 7753), ('\u{1e4a}', 7755), + ('\u{1e4c}', 7757), ('\u{1e4e}', 7759), ('\u{1e50}', 7761), ('\u{1e52}', 7763), + ('\u{1e54}', 7765), ('\u{1e56}', 7767), ('\u{1e58}', 7769), ('\u{1e5a}', 7771), + ('\u{1e5c}', 7773), ('\u{1e5e}', 7775), ('\u{1e60}', 7777), ('\u{1e62}', 7779), + ('\u{1e64}', 7781), ('\u{1e66}', 7783), ('\u{1e68}', 7785), ('\u{1e6a}', 7787), + ('\u{1e6c}', 7789), ('\u{1e6e}', 7791), ('\u{1e70}', 7793), ('\u{1e72}', 7795), + ('\u{1e74}', 7797), ('\u{1e76}', 7799), ('\u{1e78}', 7801), ('\u{1e7a}', 7803), + ('\u{1e7c}', 7805), ('\u{1e7e}', 7807), ('\u{1e80}', 7809), ('\u{1e82}', 7811), + ('\u{1e84}', 7813), ('\u{1e86}', 7815), ('\u{1e88}', 7817), ('\u{1e8a}', 7819), + ('\u{1e8c}', 7821), ('\u{1e8e}', 7823), ('\u{1e90}', 7825), ('\u{1e92}', 7827), + ('\u{1e94}', 7829), ('\u{1e9e}', 223), ('\u{1ea0}', 7841), ('\u{1ea2}', 7843), + ('\u{1ea4}', 7845), ('\u{1ea6}', 7847), ('\u{1ea8}', 7849), ('\u{1eaa}', 7851), + ('\u{1eac}', 7853), ('\u{1eae}', 7855), ('\u{1eb0}', 7857), ('\u{1eb2}', 7859), + ('\u{1eb4}', 7861), ('\u{1eb6}', 7863), ('\u{1eb8}', 7865), ('\u{1eba}', 7867), + ('\u{1ebc}', 7869), ('\u{1ebe}', 7871), ('\u{1ec0}', 7873), ('\u{1ec2}', 7875), + ('\u{1ec4}', 7877), ('\u{1ec6}', 7879), ('\u{1ec8}', 7881), ('\u{1eca}', 7883), + ('\u{1ecc}', 7885), ('\u{1ece}', 7887), ('\u{1ed0}', 7889), ('\u{1ed2}', 7891), + ('\u{1ed4}', 7893), ('\u{1ed6}', 7895), ('\u{1ed8}', 7897), ('\u{1eda}', 7899), + ('\u{1edc}', 7901), ('\u{1ede}', 7903), ('\u{1ee0}', 7905), ('\u{1ee2}', 7907), + ('\u{1ee4}', 7909), ('\u{1ee6}', 7911), ('\u{1ee8}', 7913), ('\u{1eea}', 7915), + ('\u{1eec}', 7917), ('\u{1eee}', 7919), ('\u{1ef0}', 7921), ('\u{1ef2}', 7923), + ('\u{1ef4}', 7925), ('\u{1ef6}', 7927), ('\u{1ef8}', 7929), ('\u{1efa}', 7931), + ('\u{1efc}', 7933), ('\u{1efe}', 7935), ('\u{1f08}', 7936), ('\u{1f09}', 7937), + ('\u{1f0a}', 7938), ('\u{1f0b}', 7939), ('\u{1f0c}', 7940), ('\u{1f0d}', 7941), + ('\u{1f0e}', 7942), ('\u{1f0f}', 7943), ('\u{1f18}', 7952), ('\u{1f19}', 7953), + ('\u{1f1a}', 7954), ('\u{1f1b}', 7955), ('\u{1f1c}', 7956), ('\u{1f1d}', 7957), + ('\u{1f28}', 7968), ('\u{1f29}', 7969), ('\u{1f2a}', 7970), ('\u{1f2b}', 7971), + ('\u{1f2c}', 7972), ('\u{1f2d}', 7973), ('\u{1f2e}', 7974), ('\u{1f2f}', 7975), + ('\u{1f38}', 7984), ('\u{1f39}', 7985), ('\u{1f3a}', 7986), ('\u{1f3b}', 7987), + ('\u{1f3c}', 7988), ('\u{1f3d}', 7989), ('\u{1f3e}', 7990), ('\u{1f3f}', 7991), + ('\u{1f48}', 8000), ('\u{1f49}', 8001), ('\u{1f4a}', 8002), ('\u{1f4b}', 8003), + ('\u{1f4c}', 8004), ('\u{1f4d}', 8005), ('\u{1f59}', 8017), ('\u{1f5b}', 8019), + ('\u{1f5d}', 8021), ('\u{1f5f}', 8023), ('\u{1f68}', 8032), ('\u{1f69}', 8033), + ('\u{1f6a}', 8034), ('\u{1f6b}', 8035), ('\u{1f6c}', 8036), ('\u{1f6d}', 8037), + ('\u{1f6e}', 8038), ('\u{1f6f}', 8039), ('\u{1f88}', 8064), ('\u{1f89}', 8065), + ('\u{1f8a}', 8066), ('\u{1f8b}', 8067), ('\u{1f8c}', 8068), ('\u{1f8d}', 8069), + ('\u{1f8e}', 8070), ('\u{1f8f}', 8071), ('\u{1f98}', 8080), ('\u{1f99}', 8081), + ('\u{1f9a}', 8082), ('\u{1f9b}', 8083), ('\u{1f9c}', 8084), ('\u{1f9d}', 8085), + ('\u{1f9e}', 8086), ('\u{1f9f}', 8087), ('\u{1fa8}', 8096), ('\u{1fa9}', 8097), + ('\u{1faa}', 8098), ('\u{1fab}', 8099), ('\u{1fac}', 8100), ('\u{1fad}', 8101), + ('\u{1fae}', 8102), ('\u{1faf}', 8103), ('\u{1fb8}', 8112), ('\u{1fb9}', 8113), + ('\u{1fba}', 8048), ('\u{1fbb}', 8049), ('\u{1fbc}', 8115), ('\u{1fc8}', 8050), + ('\u{1fc9}', 8051), ('\u{1fca}', 8052), ('\u{1fcb}', 8053), ('\u{1fcc}', 8131), + ('\u{1fd8}', 8144), ('\u{1fd9}', 8145), ('\u{1fda}', 8054), ('\u{1fdb}', 8055), + ('\u{1fe8}', 8160), ('\u{1fe9}', 8161), ('\u{1fea}', 8058), ('\u{1feb}', 8059), + ('\u{1fec}', 8165), ('\u{1ff8}', 8056), ('\u{1ff9}', 8057), ('\u{1ffa}', 8060), + ('\u{1ffb}', 8061), ('\u{1ffc}', 8179), ('\u{2126}', 969), ('\u{212a}', 107), + ('\u{212b}', 229), ('\u{2132}', 8526), ('\u{2160}', 8560), ('\u{2161}', 8561), + ('\u{2162}', 8562), ('\u{2163}', 8563), ('\u{2164}', 8564), ('\u{2165}', 8565), + ('\u{2166}', 8566), ('\u{2167}', 8567), ('\u{2168}', 8568), ('\u{2169}', 8569), + ('\u{216a}', 8570), ('\u{216b}', 8571), ('\u{216c}', 8572), ('\u{216d}', 8573), + ('\u{216e}', 8574), ('\u{216f}', 8575), ('\u{2183}', 8580), ('\u{24b6}', 9424), + ('\u{24b7}', 9425), ('\u{24b8}', 9426), ('\u{24b9}', 9427), ('\u{24ba}', 9428), + ('\u{24bb}', 9429), ('\u{24bc}', 9430), ('\u{24bd}', 9431), ('\u{24be}', 9432), + ('\u{24bf}', 9433), ('\u{24c0}', 9434), ('\u{24c1}', 9435), ('\u{24c2}', 9436), + ('\u{24c3}', 9437), ('\u{24c4}', 9438), ('\u{24c5}', 9439), ('\u{24c6}', 9440), + ('\u{24c7}', 9441), ('\u{24c8}', 9442), ('\u{24c9}', 9443), ('\u{24ca}', 9444), + ('\u{24cb}', 9445), ('\u{24cc}', 9446), ('\u{24cd}', 9447), ('\u{24ce}', 9448), + ('\u{24cf}', 9449), ('\u{2c00}', 11312), ('\u{2c01}', 11313), ('\u{2c02}', 11314), + ('\u{2c03}', 11315), ('\u{2c04}', 11316), ('\u{2c05}', 11317), ('\u{2c06}', 11318), + ('\u{2c07}', 11319), ('\u{2c08}', 11320), ('\u{2c09}', 11321), ('\u{2c0a}', 11322), + ('\u{2c0b}', 11323), ('\u{2c0c}', 11324), ('\u{2c0d}', 11325), ('\u{2c0e}', 11326), + ('\u{2c0f}', 11327), ('\u{2c10}', 11328), ('\u{2c11}', 11329), ('\u{2c12}', 11330), + ('\u{2c13}', 11331), ('\u{2c14}', 11332), ('\u{2c15}', 11333), ('\u{2c16}', 11334), + ('\u{2c17}', 11335), ('\u{2c18}', 11336), ('\u{2c19}', 11337), ('\u{2c1a}', 11338), + ('\u{2c1b}', 11339), ('\u{2c1c}', 11340), ('\u{2c1d}', 11341), ('\u{2c1e}', 11342), + ('\u{2c1f}', 11343), ('\u{2c20}', 11344), ('\u{2c21}', 11345), ('\u{2c22}', 11346), + ('\u{2c23}', 11347), ('\u{2c24}', 11348), ('\u{2c25}', 11349), ('\u{2c26}', 11350), + ('\u{2c27}', 11351), ('\u{2c28}', 11352), ('\u{2c29}', 11353), ('\u{2c2a}', 11354), + ('\u{2c2b}', 11355), ('\u{2c2c}', 11356), ('\u{2c2d}', 11357), ('\u{2c2e}', 11358), + ('\u{2c2f}', 11359), ('\u{2c60}', 11361), ('\u{2c62}', 619), ('\u{2c63}', 7549), + ('\u{2c64}', 637), ('\u{2c67}', 11368), ('\u{2c69}', 11370), ('\u{2c6b}', 11372), + ('\u{2c6d}', 593), ('\u{2c6e}', 625), ('\u{2c6f}', 592), ('\u{2c70}', 594), + ('\u{2c72}', 11379), ('\u{2c75}', 11382), ('\u{2c7e}', 575), ('\u{2c7f}', 576), + ('\u{2c80}', 11393), ('\u{2c82}', 11395), ('\u{2c84}', 11397), ('\u{2c86}', 11399), + ('\u{2c88}', 11401), ('\u{2c8a}', 11403), ('\u{2c8c}', 11405), ('\u{2c8e}', 11407), + ('\u{2c90}', 11409), ('\u{2c92}', 11411), ('\u{2c94}', 11413), ('\u{2c96}', 11415), + ('\u{2c98}', 11417), ('\u{2c9a}', 11419), ('\u{2c9c}', 11421), ('\u{2c9e}', 11423), + ('\u{2ca0}', 11425), ('\u{2ca2}', 11427), ('\u{2ca4}', 11429), ('\u{2ca6}', 11431), + ('\u{2ca8}', 11433), ('\u{2caa}', 11435), ('\u{2cac}', 11437), ('\u{2cae}', 11439), + ('\u{2cb0}', 11441), ('\u{2cb2}', 11443), ('\u{2cb4}', 11445), ('\u{2cb6}', 11447), + ('\u{2cb8}', 11449), ('\u{2cba}', 11451), ('\u{2cbc}', 11453), ('\u{2cbe}', 11455), + ('\u{2cc0}', 11457), ('\u{2cc2}', 11459), ('\u{2cc4}', 11461), ('\u{2cc6}', 11463), + ('\u{2cc8}', 11465), ('\u{2cca}', 11467), ('\u{2ccc}', 11469), ('\u{2cce}', 11471), + ('\u{2cd0}', 11473), ('\u{2cd2}', 11475), ('\u{2cd4}', 11477), ('\u{2cd6}', 11479), + ('\u{2cd8}', 11481), ('\u{2cda}', 11483), ('\u{2cdc}', 11485), ('\u{2cde}', 11487), + ('\u{2ce0}', 11489), ('\u{2ce2}', 11491), ('\u{2ceb}', 11500), ('\u{2ced}', 11502), + ('\u{2cf2}', 11507), ('\u{a640}', 42561), ('\u{a642}', 42563), ('\u{a644}', 42565), + ('\u{a646}', 42567), ('\u{a648}', 42569), ('\u{a64a}', 42571), ('\u{a64c}', 42573), + ('\u{a64e}', 42575), ('\u{a650}', 42577), ('\u{a652}', 42579), ('\u{a654}', 42581), + ('\u{a656}', 42583), ('\u{a658}', 42585), ('\u{a65a}', 42587), ('\u{a65c}', 42589), + ('\u{a65e}', 42591), ('\u{a660}', 42593), ('\u{a662}', 42595), ('\u{a664}', 42597), + ('\u{a666}', 42599), ('\u{a668}', 42601), ('\u{a66a}', 42603), ('\u{a66c}', 42605), + ('\u{a680}', 42625), ('\u{a682}', 42627), ('\u{a684}', 42629), ('\u{a686}', 42631), + ('\u{a688}', 42633), ('\u{a68a}', 42635), ('\u{a68c}', 42637), ('\u{a68e}', 42639), + ('\u{a690}', 42641), ('\u{a692}', 42643), ('\u{a694}', 42645), ('\u{a696}', 42647), + ('\u{a698}', 42649), ('\u{a69a}', 42651), ('\u{a722}', 42787), ('\u{a724}', 42789), + ('\u{a726}', 42791), ('\u{a728}', 42793), ('\u{a72a}', 42795), ('\u{a72c}', 42797), + ('\u{a72e}', 42799), ('\u{a732}', 42803), ('\u{a734}', 42805), ('\u{a736}', 42807), + ('\u{a738}', 42809), ('\u{a73a}', 42811), ('\u{a73c}', 42813), ('\u{a73e}', 42815), + ('\u{a740}', 42817), ('\u{a742}', 42819), ('\u{a744}', 42821), ('\u{a746}', 42823), + ('\u{a748}', 42825), ('\u{a74a}', 42827), ('\u{a74c}', 42829), ('\u{a74e}', 42831), + ('\u{a750}', 42833), ('\u{a752}', 42835), ('\u{a754}', 42837), ('\u{a756}', 42839), + ('\u{a758}', 42841), ('\u{a75a}', 42843), ('\u{a75c}', 42845), ('\u{a75e}', 42847), + ('\u{a760}', 42849), ('\u{a762}', 42851), ('\u{a764}', 42853), ('\u{a766}', 42855), + ('\u{a768}', 42857), ('\u{a76a}', 42859), ('\u{a76c}', 42861), ('\u{a76e}', 42863), + ('\u{a779}', 42874), ('\u{a77b}', 42876), ('\u{a77d}', 7545), ('\u{a77e}', 42879), + ('\u{a780}', 42881), ('\u{a782}', 42883), ('\u{a784}', 42885), ('\u{a786}', 42887), + ('\u{a78b}', 42892), ('\u{a78d}', 613), ('\u{a790}', 42897), ('\u{a792}', 42899), + ('\u{a796}', 42903), ('\u{a798}', 42905), ('\u{a79a}', 42907), ('\u{a79c}', 42909), + ('\u{a79e}', 42911), ('\u{a7a0}', 42913), ('\u{a7a2}', 42915), ('\u{a7a4}', 42917), + ('\u{a7a6}', 42919), ('\u{a7a8}', 42921), ('\u{a7aa}', 614), ('\u{a7ab}', 604), + ('\u{a7ac}', 609), ('\u{a7ad}', 620), ('\u{a7ae}', 618), ('\u{a7b0}', 670), + ('\u{a7b1}', 647), ('\u{a7b2}', 669), ('\u{a7b3}', 43859), ('\u{a7b4}', 42933), + ('\u{a7b6}', 42935), ('\u{a7b8}', 42937), ('\u{a7ba}', 42939), ('\u{a7bc}', 42941), + ('\u{a7be}', 42943), ('\u{a7c0}', 42945), ('\u{a7c2}', 42947), ('\u{a7c4}', 42900), + ('\u{a7c5}', 642), ('\u{a7c6}', 7566), ('\u{a7c7}', 42952), ('\u{a7c9}', 42954), + ('\u{a7d0}', 42961), ('\u{a7d6}', 42967), ('\u{a7d8}', 42969), ('\u{a7f5}', 42998), + ('\u{ff21}', 65345), ('\u{ff22}', 65346), ('\u{ff23}', 65347), ('\u{ff24}', 65348), + ('\u{ff25}', 65349), ('\u{ff26}', 65350), ('\u{ff27}', 65351), ('\u{ff28}', 65352), + ('\u{ff29}', 65353), ('\u{ff2a}', 65354), ('\u{ff2b}', 65355), ('\u{ff2c}', 65356), + ('\u{ff2d}', 65357), ('\u{ff2e}', 65358), ('\u{ff2f}', 65359), ('\u{ff30}', 65360), + ('\u{ff31}', 65361), ('\u{ff32}', 65362), ('\u{ff33}', 65363), ('\u{ff34}', 65364), + ('\u{ff35}', 65365), ('\u{ff36}', 65366), ('\u{ff37}', 65367), ('\u{ff38}', 65368), + ('\u{ff39}', 65369), ('\u{ff3a}', 65370), ('\u{10400}', 66600), ('\u{10401}', 66601), + ('\u{10402}', 66602), ('\u{10403}', 66603), ('\u{10404}', 66604), ('\u{10405}', 66605), + ('\u{10406}', 66606), ('\u{10407}', 66607), ('\u{10408}', 66608), ('\u{10409}', 66609), + ('\u{1040a}', 66610), ('\u{1040b}', 66611), ('\u{1040c}', 66612), ('\u{1040d}', 66613), + ('\u{1040e}', 66614), ('\u{1040f}', 66615), ('\u{10410}', 66616), ('\u{10411}', 66617), + ('\u{10412}', 66618), ('\u{10413}', 66619), ('\u{10414}', 66620), ('\u{10415}', 66621), + ('\u{10416}', 66622), ('\u{10417}', 66623), ('\u{10418}', 66624), ('\u{10419}', 66625), + ('\u{1041a}', 66626), ('\u{1041b}', 66627), ('\u{1041c}', 66628), ('\u{1041d}', 66629), + ('\u{1041e}', 66630), ('\u{1041f}', 66631), ('\u{10420}', 66632), ('\u{10421}', 66633), + ('\u{10422}', 66634), ('\u{10423}', 66635), ('\u{10424}', 66636), ('\u{10425}', 66637), + ('\u{10426}', 66638), ('\u{10427}', 66639), ('\u{104b0}', 66776), ('\u{104b1}', 66777), + ('\u{104b2}', 66778), ('\u{104b3}', 66779), ('\u{104b4}', 66780), ('\u{104b5}', 66781), + ('\u{104b6}', 66782), ('\u{104b7}', 66783), ('\u{104b8}', 66784), ('\u{104b9}', 66785), + ('\u{104ba}', 66786), ('\u{104bb}', 66787), ('\u{104bc}', 66788), ('\u{104bd}', 66789), + ('\u{104be}', 66790), ('\u{104bf}', 66791), ('\u{104c0}', 66792), ('\u{104c1}', 66793), + ('\u{104c2}', 66794), ('\u{104c3}', 66795), ('\u{104c4}', 66796), ('\u{104c5}', 66797), + ('\u{104c6}', 66798), ('\u{104c7}', 66799), ('\u{104c8}', 66800), ('\u{104c9}', 66801), + ('\u{104ca}', 66802), ('\u{104cb}', 66803), ('\u{104cc}', 66804), ('\u{104cd}', 66805), + ('\u{104ce}', 66806), ('\u{104cf}', 66807), ('\u{104d0}', 66808), ('\u{104d1}', 66809), + ('\u{104d2}', 66810), ('\u{104d3}', 66811), ('\u{10570}', 66967), ('\u{10571}', 66968), + ('\u{10572}', 66969), ('\u{10573}', 66970), ('\u{10574}', 66971), ('\u{10575}', 66972), + ('\u{10576}', 66973), ('\u{10577}', 66974), ('\u{10578}', 66975), ('\u{10579}', 66976), + ('\u{1057a}', 66977), ('\u{1057c}', 66979), ('\u{1057d}', 66980), ('\u{1057e}', 66981), + ('\u{1057f}', 66982), ('\u{10580}', 66983), ('\u{10581}', 66984), ('\u{10582}', 66985), + ('\u{10583}', 66986), ('\u{10584}', 66987), ('\u{10585}', 66988), ('\u{10586}', 66989), + ('\u{10587}', 66990), ('\u{10588}', 66991), ('\u{10589}', 66992), ('\u{1058a}', 66993), + ('\u{1058c}', 66995), ('\u{1058d}', 66996), ('\u{1058e}', 66997), ('\u{1058f}', 66998), + ('\u{10590}', 66999), ('\u{10591}', 67000), ('\u{10592}', 67001), ('\u{10594}', 67003), + ('\u{10595}', 67004), ('\u{10c80}', 68800), ('\u{10c81}', 68801), ('\u{10c82}', 68802), + ('\u{10c83}', 68803), ('\u{10c84}', 68804), ('\u{10c85}', 68805), ('\u{10c86}', 68806), + ('\u{10c87}', 68807), ('\u{10c88}', 68808), ('\u{10c89}', 68809), ('\u{10c8a}', 68810), + ('\u{10c8b}', 68811), ('\u{10c8c}', 68812), ('\u{10c8d}', 68813), ('\u{10c8e}', 68814), + ('\u{10c8f}', 68815), ('\u{10c90}', 68816), ('\u{10c91}', 68817), ('\u{10c92}', 68818), + ('\u{10c93}', 68819), ('\u{10c94}', 68820), ('\u{10c95}', 68821), ('\u{10c96}', 68822), + ('\u{10c97}', 68823), ('\u{10c98}', 68824), ('\u{10c99}', 68825), ('\u{10c9a}', 68826), + ('\u{10c9b}', 68827), ('\u{10c9c}', 68828), ('\u{10c9d}', 68829), ('\u{10c9e}', 68830), + ('\u{10c9f}', 68831), ('\u{10ca0}', 68832), ('\u{10ca1}', 68833), ('\u{10ca2}', 68834), + ('\u{10ca3}', 68835), ('\u{10ca4}', 68836), ('\u{10ca5}', 68837), ('\u{10ca6}', 68838), + ('\u{10ca7}', 68839), ('\u{10ca8}', 68840), ('\u{10ca9}', 68841), ('\u{10caa}', 68842), + ('\u{10cab}', 68843), ('\u{10cac}', 68844), ('\u{10cad}', 68845), ('\u{10cae}', 68846), + ('\u{10caf}', 68847), ('\u{10cb0}', 68848), ('\u{10cb1}', 68849), ('\u{10cb2}', 68850), + ('\u{118a0}', 71872), ('\u{118a1}', 71873), ('\u{118a2}', 71874), ('\u{118a3}', 71875), + ('\u{118a4}', 71876), ('\u{118a5}', 71877), ('\u{118a6}', 71878), ('\u{118a7}', 71879), + ('\u{118a8}', 71880), ('\u{118a9}', 71881), ('\u{118aa}', 71882), ('\u{118ab}', 71883), + ('\u{118ac}', 71884), ('\u{118ad}', 71885), ('\u{118ae}', 71886), ('\u{118af}', 71887), + ('\u{118b0}', 71888), ('\u{118b1}', 71889), ('\u{118b2}', 71890), ('\u{118b3}', 71891), + ('\u{118b4}', 71892), ('\u{118b5}', 71893), ('\u{118b6}', 71894), ('\u{118b7}', 71895), + ('\u{118b8}', 71896), ('\u{118b9}', 71897), ('\u{118ba}', 71898), ('\u{118bb}', 71899), + ('\u{118bc}', 71900), ('\u{118bd}', 71901), ('\u{118be}', 71902), ('\u{118bf}', 71903), + ('\u{16e40}', 93792), ('\u{16e41}', 93793), ('\u{16e42}', 93794), ('\u{16e43}', 93795), + ('\u{16e44}', 93796), ('\u{16e45}', 93797), ('\u{16e46}', 93798), ('\u{16e47}', 93799), + ('\u{16e48}', 93800), ('\u{16e49}', 93801), ('\u{16e4a}', 93802), ('\u{16e4b}', 93803), + ('\u{16e4c}', 93804), ('\u{16e4d}', 93805), ('\u{16e4e}', 93806), ('\u{16e4f}', 93807), + ('\u{16e50}', 93808), ('\u{16e51}', 93809), ('\u{16e52}', 93810), ('\u{16e53}', 93811), + ('\u{16e54}', 93812), ('\u{16e55}', 93813), ('\u{16e56}', 93814), ('\u{16e57}', 93815), + ('\u{16e58}', 93816), ('\u{16e59}', 93817), ('\u{16e5a}', 93818), ('\u{16e5b}', 93819), + ('\u{16e5c}', 93820), ('\u{16e5d}', 93821), ('\u{16e5e}', 93822), ('\u{16e5f}', 93823), + ('\u{1e900}', 125218), ('\u{1e901}', 125219), ('\u{1e902}', 125220), ('\u{1e903}', 125221), + ('\u{1e904}', 125222), ('\u{1e905}', 125223), ('\u{1e906}', 125224), ('\u{1e907}', 125225), + ('\u{1e908}', 125226), ('\u{1e909}', 125227), ('\u{1e90a}', 125228), ('\u{1e90b}', 125229), + ('\u{1e90c}', 125230), ('\u{1e90d}', 125231), ('\u{1e90e}', 125232), ('\u{1e90f}', 125233), + ('\u{1e910}', 125234), ('\u{1e911}', 125235), ('\u{1e912}', 125236), ('\u{1e913}', 125237), + ('\u{1e914}', 125238), ('\u{1e915}', 125239), ('\u{1e916}', 125240), ('\u{1e917}', 125241), + ('\u{1e918}', 125242), ('\u{1e919}', 125243), ('\u{1e91a}', 125244), ('\u{1e91b}', 125245), + ('\u{1e91c}', 125246), ('\u{1e91d}', 125247), ('\u{1e91e}', 125248), ('\u{1e91f}', 125249), + ('\u{1e920}', 125250), ('\u{1e921}', 125251), ]; - static LOWERCASE_TABLE_MULTI: &[(char, [char; 3])] = &[ - ('\u{130}', ['i', '\u{307}', '\u{0}']), + static LOWERCASE_TABLE_MULTI: &[[char; 3]] = &[ + ['i', '\u{307}', '\u{0}'], ]; - static UPPERCASE_TABLE_SINGLE: &[(char, char)] = &[ - ('\u{b5}', '\u{39c}'), ('\u{e0}', '\u{c0}'), ('\u{e1}', '\u{c1}'), ('\u{e2}', '\u{c2}'), - ('\u{e3}', '\u{c3}'), ('\u{e4}', '\u{c4}'), ('\u{e5}', '\u{c5}'), ('\u{e6}', '\u{c6}'), - ('\u{e7}', '\u{c7}'), ('\u{e8}', '\u{c8}'), ('\u{e9}', '\u{c9}'), ('\u{ea}', '\u{ca}'), - ('\u{eb}', '\u{cb}'), ('\u{ec}', '\u{cc}'), ('\u{ed}', '\u{cd}'), ('\u{ee}', '\u{ce}'), - ('\u{ef}', '\u{cf}'), ('\u{f0}', '\u{d0}'), ('\u{f1}', '\u{d1}'), ('\u{f2}', '\u{d2}'), - ('\u{f3}', '\u{d3}'), ('\u{f4}', '\u{d4}'), ('\u{f5}', '\u{d5}'), ('\u{f6}', '\u{d6}'), - ('\u{f8}', '\u{d8}'), ('\u{f9}', '\u{d9}'), ('\u{fa}', '\u{da}'), ('\u{fb}', '\u{db}'), - ('\u{fc}', '\u{dc}'), ('\u{fd}', '\u{dd}'), ('\u{fe}', '\u{de}'), ('\u{ff}', '\u{178}'), - ('\u{101}', '\u{100}'), ('\u{103}', '\u{102}'), ('\u{105}', '\u{104}'), - ('\u{107}', '\u{106}'), ('\u{109}', '\u{108}'), ('\u{10b}', '\u{10a}'), - ('\u{10d}', '\u{10c}'), ('\u{10f}', '\u{10e}'), ('\u{111}', '\u{110}'), - ('\u{113}', '\u{112}'), ('\u{115}', '\u{114}'), ('\u{117}', '\u{116}'), - ('\u{119}', '\u{118}'), ('\u{11b}', '\u{11a}'), ('\u{11d}', '\u{11c}'), - ('\u{11f}', '\u{11e}'), ('\u{121}', '\u{120}'), ('\u{123}', '\u{122}'), - ('\u{125}', '\u{124}'), ('\u{127}', '\u{126}'), ('\u{129}', '\u{128}'), - ('\u{12b}', '\u{12a}'), ('\u{12d}', '\u{12c}'), ('\u{12f}', '\u{12e}'), ('\u{131}', 'I'), - ('\u{133}', '\u{132}'), ('\u{135}', '\u{134}'), ('\u{137}', '\u{136}'), - ('\u{13a}', '\u{139}'), ('\u{13c}', '\u{13b}'), ('\u{13e}', '\u{13d}'), - ('\u{140}', '\u{13f}'), ('\u{142}', '\u{141}'), ('\u{144}', '\u{143}'), - ('\u{146}', '\u{145}'), ('\u{148}', '\u{147}'), ('\u{14b}', '\u{14a}'), - ('\u{14d}', '\u{14c}'), ('\u{14f}', '\u{14e}'), ('\u{151}', '\u{150}'), - ('\u{153}', '\u{152}'), ('\u{155}', '\u{154}'), ('\u{157}', '\u{156}'), - ('\u{159}', '\u{158}'), ('\u{15b}', '\u{15a}'), ('\u{15d}', '\u{15c}'), - ('\u{15f}', '\u{15e}'), ('\u{161}', '\u{160}'), ('\u{163}', '\u{162}'), - ('\u{165}', '\u{164}'), ('\u{167}', '\u{166}'), ('\u{169}', '\u{168}'), - ('\u{16b}', '\u{16a}'), ('\u{16d}', '\u{16c}'), ('\u{16f}', '\u{16e}'), - ('\u{171}', '\u{170}'), ('\u{173}', '\u{172}'), ('\u{175}', '\u{174}'), - ('\u{177}', '\u{176}'), ('\u{17a}', '\u{179}'), ('\u{17c}', '\u{17b}'), - ('\u{17e}', '\u{17d}'), ('\u{17f}', 'S'), ('\u{180}', '\u{243}'), ('\u{183}', '\u{182}'), - ('\u{185}', '\u{184}'), ('\u{188}', '\u{187}'), ('\u{18c}', '\u{18b}'), - ('\u{192}', '\u{191}'), ('\u{195}', '\u{1f6}'), ('\u{199}', '\u{198}'), - ('\u{19a}', '\u{23d}'), ('\u{19e}', '\u{220}'), ('\u{1a1}', '\u{1a0}'), - ('\u{1a3}', '\u{1a2}'), ('\u{1a5}', '\u{1a4}'), ('\u{1a8}', '\u{1a7}'), - ('\u{1ad}', '\u{1ac}'), ('\u{1b0}', '\u{1af}'), ('\u{1b4}', '\u{1b3}'), - ('\u{1b6}', '\u{1b5}'), ('\u{1b9}', '\u{1b8}'), ('\u{1bd}', '\u{1bc}'), - ('\u{1bf}', '\u{1f7}'), ('\u{1c5}', '\u{1c4}'), ('\u{1c6}', '\u{1c4}'), - ('\u{1c8}', '\u{1c7}'), ('\u{1c9}', '\u{1c7}'), ('\u{1cb}', '\u{1ca}'), - ('\u{1cc}', '\u{1ca}'), ('\u{1ce}', '\u{1cd}'), ('\u{1d0}', '\u{1cf}'), - ('\u{1d2}', '\u{1d1}'), ('\u{1d4}', '\u{1d3}'), ('\u{1d6}', '\u{1d5}'), - ('\u{1d8}', '\u{1d7}'), ('\u{1da}', '\u{1d9}'), ('\u{1dc}', '\u{1db}'), - ('\u{1dd}', '\u{18e}'), ('\u{1df}', '\u{1de}'), ('\u{1e1}', '\u{1e0}'), - ('\u{1e3}', '\u{1e2}'), ('\u{1e5}', '\u{1e4}'), ('\u{1e7}', '\u{1e6}'), - ('\u{1e9}', '\u{1e8}'), ('\u{1eb}', '\u{1ea}'), ('\u{1ed}', '\u{1ec}'), - ('\u{1ef}', '\u{1ee}'), ('\u{1f2}', '\u{1f1}'), ('\u{1f3}', '\u{1f1}'), - ('\u{1f5}', '\u{1f4}'), ('\u{1f9}', '\u{1f8}'), ('\u{1fb}', '\u{1fa}'), - ('\u{1fd}', '\u{1fc}'), ('\u{1ff}', '\u{1fe}'), ('\u{201}', '\u{200}'), - ('\u{203}', '\u{202}'), ('\u{205}', '\u{204}'), ('\u{207}', '\u{206}'), - ('\u{209}', '\u{208}'), ('\u{20b}', '\u{20a}'), ('\u{20d}', '\u{20c}'), - ('\u{20f}', '\u{20e}'), ('\u{211}', '\u{210}'), ('\u{213}', '\u{212}'), - ('\u{215}', '\u{214}'), ('\u{217}', '\u{216}'), ('\u{219}', '\u{218}'), - ('\u{21b}', '\u{21a}'), ('\u{21d}', '\u{21c}'), ('\u{21f}', '\u{21e}'), - ('\u{223}', '\u{222}'), ('\u{225}', '\u{224}'), ('\u{227}', '\u{226}'), - ('\u{229}', '\u{228}'), ('\u{22b}', '\u{22a}'), ('\u{22d}', '\u{22c}'), - ('\u{22f}', '\u{22e}'), ('\u{231}', '\u{230}'), ('\u{233}', '\u{232}'), - ('\u{23c}', '\u{23b}'), ('\u{23f}', '\u{2c7e}'), ('\u{240}', '\u{2c7f}'), - ('\u{242}', '\u{241}'), ('\u{247}', '\u{246}'), ('\u{249}', '\u{248}'), - ('\u{24b}', '\u{24a}'), ('\u{24d}', '\u{24c}'), ('\u{24f}', '\u{24e}'), - ('\u{250}', '\u{2c6f}'), ('\u{251}', '\u{2c6d}'), ('\u{252}', '\u{2c70}'), - ('\u{253}', '\u{181}'), ('\u{254}', '\u{186}'), ('\u{256}', '\u{189}'), - ('\u{257}', '\u{18a}'), ('\u{259}', '\u{18f}'), ('\u{25b}', '\u{190}'), - ('\u{25c}', '\u{a7ab}'), ('\u{260}', '\u{193}'), ('\u{261}', '\u{a7ac}'), - ('\u{263}', '\u{194}'), ('\u{265}', '\u{a78d}'), ('\u{266}', '\u{a7aa}'), - ('\u{268}', '\u{197}'), ('\u{269}', '\u{196}'), ('\u{26a}', '\u{a7ae}'), - ('\u{26b}', '\u{2c62}'), ('\u{26c}', '\u{a7ad}'), ('\u{26f}', '\u{19c}'), - ('\u{271}', '\u{2c6e}'), ('\u{272}', '\u{19d}'), ('\u{275}', '\u{19f}'), - ('\u{27d}', '\u{2c64}'), ('\u{280}', '\u{1a6}'), ('\u{282}', '\u{a7c5}'), - ('\u{283}', '\u{1a9}'), ('\u{287}', '\u{a7b1}'), ('\u{288}', '\u{1ae}'), - ('\u{289}', '\u{244}'), ('\u{28a}', '\u{1b1}'), ('\u{28b}', '\u{1b2}'), - ('\u{28c}', '\u{245}'), ('\u{292}', '\u{1b7}'), ('\u{29d}', '\u{a7b2}'), - ('\u{29e}', '\u{a7b0}'), ('\u{345}', '\u{399}'), ('\u{371}', '\u{370}'), - ('\u{373}', '\u{372}'), ('\u{377}', '\u{376}'), ('\u{37b}', '\u{3fd}'), - ('\u{37c}', '\u{3fe}'), ('\u{37d}', '\u{3ff}'), ('\u{3ac}', '\u{386}'), - ('\u{3ad}', '\u{388}'), ('\u{3ae}', '\u{389}'), ('\u{3af}', '\u{38a}'), - ('\u{3b1}', '\u{391}'), ('\u{3b2}', '\u{392}'), ('\u{3b3}', '\u{393}'), - ('\u{3b4}', '\u{394}'), ('\u{3b5}', '\u{395}'), ('\u{3b6}', '\u{396}'), - ('\u{3b7}', '\u{397}'), ('\u{3b8}', '\u{398}'), ('\u{3b9}', '\u{399}'), - ('\u{3ba}', '\u{39a}'), ('\u{3bb}', '\u{39b}'), ('\u{3bc}', '\u{39c}'), - ('\u{3bd}', '\u{39d}'), ('\u{3be}', '\u{39e}'), ('\u{3bf}', '\u{39f}'), - ('\u{3c0}', '\u{3a0}'), ('\u{3c1}', '\u{3a1}'), ('\u{3c2}', '\u{3a3}'), - ('\u{3c3}', '\u{3a3}'), ('\u{3c4}', '\u{3a4}'), ('\u{3c5}', '\u{3a5}'), - ('\u{3c6}', '\u{3a6}'), ('\u{3c7}', '\u{3a7}'), ('\u{3c8}', '\u{3a8}'), - ('\u{3c9}', '\u{3a9}'), ('\u{3ca}', '\u{3aa}'), ('\u{3cb}', '\u{3ab}'), - ('\u{3cc}', '\u{38c}'), ('\u{3cd}', '\u{38e}'), ('\u{3ce}', '\u{38f}'), - ('\u{3d0}', '\u{392}'), ('\u{3d1}', '\u{398}'), ('\u{3d5}', '\u{3a6}'), - ('\u{3d6}', '\u{3a0}'), ('\u{3d7}', '\u{3cf}'), ('\u{3d9}', '\u{3d8}'), - ('\u{3db}', '\u{3da}'), ('\u{3dd}', '\u{3dc}'), ('\u{3df}', '\u{3de}'), - ('\u{3e1}', '\u{3e0}'), ('\u{3e3}', '\u{3e2}'), ('\u{3e5}', '\u{3e4}'), - ('\u{3e7}', '\u{3e6}'), ('\u{3e9}', '\u{3e8}'), ('\u{3eb}', '\u{3ea}'), - ('\u{3ed}', '\u{3ec}'), ('\u{3ef}', '\u{3ee}'), ('\u{3f0}', '\u{39a}'), - ('\u{3f1}', '\u{3a1}'), ('\u{3f2}', '\u{3f9}'), ('\u{3f3}', '\u{37f}'), - ('\u{3f5}', '\u{395}'), ('\u{3f8}', '\u{3f7}'), ('\u{3fb}', '\u{3fa}'), - ('\u{430}', '\u{410}'), ('\u{431}', '\u{411}'), ('\u{432}', '\u{412}'), - ('\u{433}', '\u{413}'), ('\u{434}', '\u{414}'), ('\u{435}', '\u{415}'), - ('\u{436}', '\u{416}'), ('\u{437}', '\u{417}'), ('\u{438}', '\u{418}'), - ('\u{439}', '\u{419}'), ('\u{43a}', '\u{41a}'), ('\u{43b}', '\u{41b}'), - ('\u{43c}', '\u{41c}'), ('\u{43d}', '\u{41d}'), ('\u{43e}', '\u{41e}'), - ('\u{43f}', '\u{41f}'), ('\u{440}', '\u{420}'), ('\u{441}', '\u{421}'), - ('\u{442}', '\u{422}'), ('\u{443}', '\u{423}'), ('\u{444}', '\u{424}'), - ('\u{445}', '\u{425}'), ('\u{446}', '\u{426}'), ('\u{447}', '\u{427}'), - ('\u{448}', '\u{428}'), ('\u{449}', '\u{429}'), ('\u{44a}', '\u{42a}'), - ('\u{44b}', '\u{42b}'), ('\u{44c}', '\u{42c}'), ('\u{44d}', '\u{42d}'), - ('\u{44e}', '\u{42e}'), ('\u{44f}', '\u{42f}'), ('\u{450}', '\u{400}'), - ('\u{451}', '\u{401}'), ('\u{452}', '\u{402}'), ('\u{453}', '\u{403}'), - ('\u{454}', '\u{404}'), ('\u{455}', '\u{405}'), ('\u{456}', '\u{406}'), - ('\u{457}', '\u{407}'), ('\u{458}', '\u{408}'), ('\u{459}', '\u{409}'), - ('\u{45a}', '\u{40a}'), ('\u{45b}', '\u{40b}'), ('\u{45c}', '\u{40c}'), - ('\u{45d}', '\u{40d}'), ('\u{45e}', '\u{40e}'), ('\u{45f}', '\u{40f}'), - ('\u{461}', '\u{460}'), ('\u{463}', '\u{462}'), ('\u{465}', '\u{464}'), - ('\u{467}', '\u{466}'), ('\u{469}', '\u{468}'), ('\u{46b}', '\u{46a}'), - ('\u{46d}', '\u{46c}'), ('\u{46f}', '\u{46e}'), ('\u{471}', '\u{470}'), - ('\u{473}', '\u{472}'), ('\u{475}', '\u{474}'), ('\u{477}', '\u{476}'), - ('\u{479}', '\u{478}'), ('\u{47b}', '\u{47a}'), ('\u{47d}', '\u{47c}'), - ('\u{47f}', '\u{47e}'), ('\u{481}', '\u{480}'), ('\u{48b}', '\u{48a}'), - ('\u{48d}', '\u{48c}'), ('\u{48f}', '\u{48e}'), ('\u{491}', '\u{490}'), - ('\u{493}', '\u{492}'), ('\u{495}', '\u{494}'), ('\u{497}', '\u{496}'), - ('\u{499}', '\u{498}'), ('\u{49b}', '\u{49a}'), ('\u{49d}', '\u{49c}'), - ('\u{49f}', '\u{49e}'), ('\u{4a1}', '\u{4a0}'), ('\u{4a3}', '\u{4a2}'), - ('\u{4a5}', '\u{4a4}'), ('\u{4a7}', '\u{4a6}'), ('\u{4a9}', '\u{4a8}'), - ('\u{4ab}', '\u{4aa}'), ('\u{4ad}', '\u{4ac}'), ('\u{4af}', '\u{4ae}'), - ('\u{4b1}', '\u{4b0}'), ('\u{4b3}', '\u{4b2}'), ('\u{4b5}', '\u{4b4}'), - ('\u{4b7}', '\u{4b6}'), ('\u{4b9}', '\u{4b8}'), ('\u{4bb}', '\u{4ba}'), - ('\u{4bd}', '\u{4bc}'), ('\u{4bf}', '\u{4be}'), ('\u{4c2}', '\u{4c1}'), - ('\u{4c4}', '\u{4c3}'), ('\u{4c6}', '\u{4c5}'), ('\u{4c8}', '\u{4c7}'), - ('\u{4ca}', '\u{4c9}'), ('\u{4cc}', '\u{4cb}'), ('\u{4ce}', '\u{4cd}'), - ('\u{4cf}', '\u{4c0}'), ('\u{4d1}', '\u{4d0}'), ('\u{4d3}', '\u{4d2}'), - ('\u{4d5}', '\u{4d4}'), ('\u{4d7}', '\u{4d6}'), ('\u{4d9}', '\u{4d8}'), - ('\u{4db}', '\u{4da}'), ('\u{4dd}', '\u{4dc}'), ('\u{4df}', '\u{4de}'), - ('\u{4e1}', '\u{4e0}'), ('\u{4e3}', '\u{4e2}'), ('\u{4e5}', '\u{4e4}'), - ('\u{4e7}', '\u{4e6}'), ('\u{4e9}', '\u{4e8}'), ('\u{4eb}', '\u{4ea}'), - ('\u{4ed}', '\u{4ec}'), ('\u{4ef}', '\u{4ee}'), ('\u{4f1}', '\u{4f0}'), - ('\u{4f3}', '\u{4f2}'), ('\u{4f5}', '\u{4f4}'), ('\u{4f7}', '\u{4f6}'), - ('\u{4f9}', '\u{4f8}'), ('\u{4fb}', '\u{4fa}'), ('\u{4fd}', '\u{4fc}'), - ('\u{4ff}', '\u{4fe}'), ('\u{501}', '\u{500}'), ('\u{503}', '\u{502}'), - ('\u{505}', '\u{504}'), ('\u{507}', '\u{506}'), ('\u{509}', '\u{508}'), - ('\u{50b}', '\u{50a}'), ('\u{50d}', '\u{50c}'), ('\u{50f}', '\u{50e}'), - ('\u{511}', '\u{510}'), ('\u{513}', '\u{512}'), ('\u{515}', '\u{514}'), - ('\u{517}', '\u{516}'), ('\u{519}', '\u{518}'), ('\u{51b}', '\u{51a}'), - ('\u{51d}', '\u{51c}'), ('\u{51f}', '\u{51e}'), ('\u{521}', '\u{520}'), - ('\u{523}', '\u{522}'), ('\u{525}', '\u{524}'), ('\u{527}', '\u{526}'), - ('\u{529}', '\u{528}'), ('\u{52b}', '\u{52a}'), ('\u{52d}', '\u{52c}'), - ('\u{52f}', '\u{52e}'), ('\u{561}', '\u{531}'), ('\u{562}', '\u{532}'), - ('\u{563}', '\u{533}'), ('\u{564}', '\u{534}'), ('\u{565}', '\u{535}'), - ('\u{566}', '\u{536}'), ('\u{567}', '\u{537}'), ('\u{568}', '\u{538}'), - ('\u{569}', '\u{539}'), ('\u{56a}', '\u{53a}'), ('\u{56b}', '\u{53b}'), - ('\u{56c}', '\u{53c}'), ('\u{56d}', '\u{53d}'), ('\u{56e}', '\u{53e}'), - ('\u{56f}', '\u{53f}'), ('\u{570}', '\u{540}'), ('\u{571}', '\u{541}'), - ('\u{572}', '\u{542}'), ('\u{573}', '\u{543}'), ('\u{574}', '\u{544}'), - ('\u{575}', '\u{545}'), ('\u{576}', '\u{546}'), ('\u{577}', '\u{547}'), - ('\u{578}', '\u{548}'), ('\u{579}', '\u{549}'), ('\u{57a}', '\u{54a}'), - ('\u{57b}', '\u{54b}'), ('\u{57c}', '\u{54c}'), ('\u{57d}', '\u{54d}'), - ('\u{57e}', '\u{54e}'), ('\u{57f}', '\u{54f}'), ('\u{580}', '\u{550}'), - ('\u{581}', '\u{551}'), ('\u{582}', '\u{552}'), ('\u{583}', '\u{553}'), - ('\u{584}', '\u{554}'), ('\u{585}', '\u{555}'), ('\u{586}', '\u{556}'), - ('\u{10d0}', '\u{1c90}'), ('\u{10d1}', '\u{1c91}'), ('\u{10d2}', '\u{1c92}'), - ('\u{10d3}', '\u{1c93}'), ('\u{10d4}', '\u{1c94}'), ('\u{10d5}', '\u{1c95}'), - ('\u{10d6}', '\u{1c96}'), ('\u{10d7}', '\u{1c97}'), ('\u{10d8}', '\u{1c98}'), - ('\u{10d9}', '\u{1c99}'), ('\u{10da}', '\u{1c9a}'), ('\u{10db}', '\u{1c9b}'), - ('\u{10dc}', '\u{1c9c}'), ('\u{10dd}', '\u{1c9d}'), ('\u{10de}', '\u{1c9e}'), - ('\u{10df}', '\u{1c9f}'), ('\u{10e0}', '\u{1ca0}'), ('\u{10e1}', '\u{1ca1}'), - ('\u{10e2}', '\u{1ca2}'), ('\u{10e3}', '\u{1ca3}'), ('\u{10e4}', '\u{1ca4}'), - ('\u{10e5}', '\u{1ca5}'), ('\u{10e6}', '\u{1ca6}'), ('\u{10e7}', '\u{1ca7}'), - ('\u{10e8}', '\u{1ca8}'), ('\u{10e9}', '\u{1ca9}'), ('\u{10ea}', '\u{1caa}'), - ('\u{10eb}', '\u{1cab}'), ('\u{10ec}', '\u{1cac}'), ('\u{10ed}', '\u{1cad}'), - ('\u{10ee}', '\u{1cae}'), ('\u{10ef}', '\u{1caf}'), ('\u{10f0}', '\u{1cb0}'), - ('\u{10f1}', '\u{1cb1}'), ('\u{10f2}', '\u{1cb2}'), ('\u{10f3}', '\u{1cb3}'), - ('\u{10f4}', '\u{1cb4}'), ('\u{10f5}', '\u{1cb5}'), ('\u{10f6}', '\u{1cb6}'), - ('\u{10f7}', '\u{1cb7}'), ('\u{10f8}', '\u{1cb8}'), ('\u{10f9}', '\u{1cb9}'), - ('\u{10fa}', '\u{1cba}'), ('\u{10fd}', '\u{1cbd}'), ('\u{10fe}', '\u{1cbe}'), - ('\u{10ff}', '\u{1cbf}'), ('\u{13f8}', '\u{13f0}'), ('\u{13f9}', '\u{13f1}'), - ('\u{13fa}', '\u{13f2}'), ('\u{13fb}', '\u{13f3}'), ('\u{13fc}', '\u{13f4}'), - ('\u{13fd}', '\u{13f5}'), ('\u{1c80}', '\u{412}'), ('\u{1c81}', '\u{414}'), - ('\u{1c82}', '\u{41e}'), ('\u{1c83}', '\u{421}'), ('\u{1c84}', '\u{422}'), - ('\u{1c85}', '\u{422}'), ('\u{1c86}', '\u{42a}'), ('\u{1c87}', '\u{462}'), - ('\u{1c88}', '\u{a64a}'), ('\u{1d79}', '\u{a77d}'), ('\u{1d7d}', '\u{2c63}'), - ('\u{1d8e}', '\u{a7c6}'), ('\u{1e01}', '\u{1e00}'), ('\u{1e03}', '\u{1e02}'), - ('\u{1e05}', '\u{1e04}'), ('\u{1e07}', '\u{1e06}'), ('\u{1e09}', '\u{1e08}'), - ('\u{1e0b}', '\u{1e0a}'), ('\u{1e0d}', '\u{1e0c}'), ('\u{1e0f}', '\u{1e0e}'), - ('\u{1e11}', '\u{1e10}'), ('\u{1e13}', '\u{1e12}'), ('\u{1e15}', '\u{1e14}'), - ('\u{1e17}', '\u{1e16}'), ('\u{1e19}', '\u{1e18}'), ('\u{1e1b}', '\u{1e1a}'), - ('\u{1e1d}', '\u{1e1c}'), ('\u{1e1f}', '\u{1e1e}'), ('\u{1e21}', '\u{1e20}'), - ('\u{1e23}', '\u{1e22}'), ('\u{1e25}', '\u{1e24}'), ('\u{1e27}', '\u{1e26}'), - ('\u{1e29}', '\u{1e28}'), ('\u{1e2b}', '\u{1e2a}'), ('\u{1e2d}', '\u{1e2c}'), - ('\u{1e2f}', '\u{1e2e}'), ('\u{1e31}', '\u{1e30}'), ('\u{1e33}', '\u{1e32}'), - ('\u{1e35}', '\u{1e34}'), ('\u{1e37}', '\u{1e36}'), ('\u{1e39}', '\u{1e38}'), - ('\u{1e3b}', '\u{1e3a}'), ('\u{1e3d}', '\u{1e3c}'), ('\u{1e3f}', '\u{1e3e}'), - ('\u{1e41}', '\u{1e40}'), ('\u{1e43}', '\u{1e42}'), ('\u{1e45}', '\u{1e44}'), - ('\u{1e47}', '\u{1e46}'), ('\u{1e49}', '\u{1e48}'), ('\u{1e4b}', '\u{1e4a}'), - ('\u{1e4d}', '\u{1e4c}'), ('\u{1e4f}', '\u{1e4e}'), ('\u{1e51}', '\u{1e50}'), - ('\u{1e53}', '\u{1e52}'), ('\u{1e55}', '\u{1e54}'), ('\u{1e57}', '\u{1e56}'), - ('\u{1e59}', '\u{1e58}'), ('\u{1e5b}', '\u{1e5a}'), ('\u{1e5d}', '\u{1e5c}'), - ('\u{1e5f}', '\u{1e5e}'), ('\u{1e61}', '\u{1e60}'), ('\u{1e63}', '\u{1e62}'), - ('\u{1e65}', '\u{1e64}'), ('\u{1e67}', '\u{1e66}'), ('\u{1e69}', '\u{1e68}'), - ('\u{1e6b}', '\u{1e6a}'), ('\u{1e6d}', '\u{1e6c}'), ('\u{1e6f}', '\u{1e6e}'), - ('\u{1e71}', '\u{1e70}'), ('\u{1e73}', '\u{1e72}'), ('\u{1e75}', '\u{1e74}'), - ('\u{1e77}', '\u{1e76}'), ('\u{1e79}', '\u{1e78}'), ('\u{1e7b}', '\u{1e7a}'), - ('\u{1e7d}', '\u{1e7c}'), ('\u{1e7f}', '\u{1e7e}'), ('\u{1e81}', '\u{1e80}'), - ('\u{1e83}', '\u{1e82}'), ('\u{1e85}', '\u{1e84}'), ('\u{1e87}', '\u{1e86}'), - ('\u{1e89}', '\u{1e88}'), ('\u{1e8b}', '\u{1e8a}'), ('\u{1e8d}', '\u{1e8c}'), - ('\u{1e8f}', '\u{1e8e}'), ('\u{1e91}', '\u{1e90}'), ('\u{1e93}', '\u{1e92}'), - ('\u{1e95}', '\u{1e94}'), ('\u{1e9b}', '\u{1e60}'), ('\u{1ea1}', '\u{1ea0}'), - ('\u{1ea3}', '\u{1ea2}'), ('\u{1ea5}', '\u{1ea4}'), ('\u{1ea7}', '\u{1ea6}'), - ('\u{1ea9}', '\u{1ea8}'), ('\u{1eab}', '\u{1eaa}'), ('\u{1ead}', '\u{1eac}'), - ('\u{1eaf}', '\u{1eae}'), ('\u{1eb1}', '\u{1eb0}'), ('\u{1eb3}', '\u{1eb2}'), - ('\u{1eb5}', '\u{1eb4}'), ('\u{1eb7}', '\u{1eb6}'), ('\u{1eb9}', '\u{1eb8}'), - ('\u{1ebb}', '\u{1eba}'), ('\u{1ebd}', '\u{1ebc}'), ('\u{1ebf}', '\u{1ebe}'), - ('\u{1ec1}', '\u{1ec0}'), ('\u{1ec3}', '\u{1ec2}'), ('\u{1ec5}', '\u{1ec4}'), - ('\u{1ec7}', '\u{1ec6}'), ('\u{1ec9}', '\u{1ec8}'), ('\u{1ecb}', '\u{1eca}'), - ('\u{1ecd}', '\u{1ecc}'), ('\u{1ecf}', '\u{1ece}'), ('\u{1ed1}', '\u{1ed0}'), - ('\u{1ed3}', '\u{1ed2}'), ('\u{1ed5}', '\u{1ed4}'), ('\u{1ed7}', '\u{1ed6}'), - ('\u{1ed9}', '\u{1ed8}'), ('\u{1edb}', '\u{1eda}'), ('\u{1edd}', '\u{1edc}'), - ('\u{1edf}', '\u{1ede}'), ('\u{1ee1}', '\u{1ee0}'), ('\u{1ee3}', '\u{1ee2}'), - ('\u{1ee5}', '\u{1ee4}'), ('\u{1ee7}', '\u{1ee6}'), ('\u{1ee9}', '\u{1ee8}'), - ('\u{1eeb}', '\u{1eea}'), ('\u{1eed}', '\u{1eec}'), ('\u{1eef}', '\u{1eee}'), - ('\u{1ef1}', '\u{1ef0}'), ('\u{1ef3}', '\u{1ef2}'), ('\u{1ef5}', '\u{1ef4}'), - ('\u{1ef7}', '\u{1ef6}'), ('\u{1ef9}', '\u{1ef8}'), ('\u{1efb}', '\u{1efa}'), - ('\u{1efd}', '\u{1efc}'), ('\u{1eff}', '\u{1efe}'), ('\u{1f00}', '\u{1f08}'), - ('\u{1f01}', '\u{1f09}'), ('\u{1f02}', '\u{1f0a}'), ('\u{1f03}', '\u{1f0b}'), - ('\u{1f04}', '\u{1f0c}'), ('\u{1f05}', '\u{1f0d}'), ('\u{1f06}', '\u{1f0e}'), - ('\u{1f07}', '\u{1f0f}'), ('\u{1f10}', '\u{1f18}'), ('\u{1f11}', '\u{1f19}'), - ('\u{1f12}', '\u{1f1a}'), ('\u{1f13}', '\u{1f1b}'), ('\u{1f14}', '\u{1f1c}'), - ('\u{1f15}', '\u{1f1d}'), ('\u{1f20}', '\u{1f28}'), ('\u{1f21}', '\u{1f29}'), - ('\u{1f22}', '\u{1f2a}'), ('\u{1f23}', '\u{1f2b}'), ('\u{1f24}', '\u{1f2c}'), - ('\u{1f25}', '\u{1f2d}'), ('\u{1f26}', '\u{1f2e}'), ('\u{1f27}', '\u{1f2f}'), - ('\u{1f30}', '\u{1f38}'), ('\u{1f31}', '\u{1f39}'), ('\u{1f32}', '\u{1f3a}'), - ('\u{1f33}', '\u{1f3b}'), ('\u{1f34}', '\u{1f3c}'), ('\u{1f35}', '\u{1f3d}'), - ('\u{1f36}', '\u{1f3e}'), ('\u{1f37}', '\u{1f3f}'), ('\u{1f40}', '\u{1f48}'), - ('\u{1f41}', '\u{1f49}'), ('\u{1f42}', '\u{1f4a}'), ('\u{1f43}', '\u{1f4b}'), - ('\u{1f44}', '\u{1f4c}'), ('\u{1f45}', '\u{1f4d}'), ('\u{1f51}', '\u{1f59}'), - ('\u{1f53}', '\u{1f5b}'), ('\u{1f55}', '\u{1f5d}'), ('\u{1f57}', '\u{1f5f}'), - ('\u{1f60}', '\u{1f68}'), ('\u{1f61}', '\u{1f69}'), ('\u{1f62}', '\u{1f6a}'), - ('\u{1f63}', '\u{1f6b}'), ('\u{1f64}', '\u{1f6c}'), ('\u{1f65}', '\u{1f6d}'), - ('\u{1f66}', '\u{1f6e}'), ('\u{1f67}', '\u{1f6f}'), ('\u{1f70}', '\u{1fba}'), - ('\u{1f71}', '\u{1fbb}'), ('\u{1f72}', '\u{1fc8}'), ('\u{1f73}', '\u{1fc9}'), - ('\u{1f74}', '\u{1fca}'), ('\u{1f75}', '\u{1fcb}'), ('\u{1f76}', '\u{1fda}'), - ('\u{1f77}', '\u{1fdb}'), ('\u{1f78}', '\u{1ff8}'), ('\u{1f79}', '\u{1ff9}'), - ('\u{1f7a}', '\u{1fea}'), ('\u{1f7b}', '\u{1feb}'), ('\u{1f7c}', '\u{1ffa}'), - ('\u{1f7d}', '\u{1ffb}'), ('\u{1fb0}', '\u{1fb8}'), ('\u{1fb1}', '\u{1fb9}'), - ('\u{1fbe}', '\u{399}'), ('\u{1fd0}', '\u{1fd8}'), ('\u{1fd1}', '\u{1fd9}'), - ('\u{1fe0}', '\u{1fe8}'), ('\u{1fe1}', '\u{1fe9}'), ('\u{1fe5}', '\u{1fec}'), - ('\u{214e}', '\u{2132}'), ('\u{2170}', '\u{2160}'), ('\u{2171}', '\u{2161}'), - ('\u{2172}', '\u{2162}'), ('\u{2173}', '\u{2163}'), ('\u{2174}', '\u{2164}'), - ('\u{2175}', '\u{2165}'), ('\u{2176}', '\u{2166}'), ('\u{2177}', '\u{2167}'), - ('\u{2178}', '\u{2168}'), ('\u{2179}', '\u{2169}'), ('\u{217a}', '\u{216a}'), - ('\u{217b}', '\u{216b}'), ('\u{217c}', '\u{216c}'), ('\u{217d}', '\u{216d}'), - ('\u{217e}', '\u{216e}'), ('\u{217f}', '\u{216f}'), ('\u{2184}', '\u{2183}'), - ('\u{24d0}', '\u{24b6}'), ('\u{24d1}', '\u{24b7}'), ('\u{24d2}', '\u{24b8}'), - ('\u{24d3}', '\u{24b9}'), ('\u{24d4}', '\u{24ba}'), ('\u{24d5}', '\u{24bb}'), - ('\u{24d6}', '\u{24bc}'), ('\u{24d7}', '\u{24bd}'), ('\u{24d8}', '\u{24be}'), - ('\u{24d9}', '\u{24bf}'), ('\u{24da}', '\u{24c0}'), ('\u{24db}', '\u{24c1}'), - ('\u{24dc}', '\u{24c2}'), ('\u{24dd}', '\u{24c3}'), ('\u{24de}', '\u{24c4}'), - ('\u{24df}', '\u{24c5}'), ('\u{24e0}', '\u{24c6}'), ('\u{24e1}', '\u{24c7}'), - ('\u{24e2}', '\u{24c8}'), ('\u{24e3}', '\u{24c9}'), ('\u{24e4}', '\u{24ca}'), - ('\u{24e5}', '\u{24cb}'), ('\u{24e6}', '\u{24cc}'), ('\u{24e7}', '\u{24cd}'), - ('\u{24e8}', '\u{24ce}'), ('\u{24e9}', '\u{24cf}'), ('\u{2c30}', '\u{2c00}'), - ('\u{2c31}', '\u{2c01}'), ('\u{2c32}', '\u{2c02}'), ('\u{2c33}', '\u{2c03}'), - ('\u{2c34}', '\u{2c04}'), ('\u{2c35}', '\u{2c05}'), ('\u{2c36}', '\u{2c06}'), - ('\u{2c37}', '\u{2c07}'), ('\u{2c38}', '\u{2c08}'), ('\u{2c39}', '\u{2c09}'), - ('\u{2c3a}', '\u{2c0a}'), ('\u{2c3b}', '\u{2c0b}'), ('\u{2c3c}', '\u{2c0c}'), - ('\u{2c3d}', '\u{2c0d}'), ('\u{2c3e}', '\u{2c0e}'), ('\u{2c3f}', '\u{2c0f}'), - ('\u{2c40}', '\u{2c10}'), ('\u{2c41}', '\u{2c11}'), ('\u{2c42}', '\u{2c12}'), - ('\u{2c43}', '\u{2c13}'), ('\u{2c44}', '\u{2c14}'), ('\u{2c45}', '\u{2c15}'), - ('\u{2c46}', '\u{2c16}'), ('\u{2c47}', '\u{2c17}'), ('\u{2c48}', '\u{2c18}'), - ('\u{2c49}', '\u{2c19}'), ('\u{2c4a}', '\u{2c1a}'), ('\u{2c4b}', '\u{2c1b}'), - ('\u{2c4c}', '\u{2c1c}'), ('\u{2c4d}', '\u{2c1d}'), ('\u{2c4e}', '\u{2c1e}'), - ('\u{2c4f}', '\u{2c1f}'), ('\u{2c50}', '\u{2c20}'), ('\u{2c51}', '\u{2c21}'), - ('\u{2c52}', '\u{2c22}'), ('\u{2c53}', '\u{2c23}'), ('\u{2c54}', '\u{2c24}'), - ('\u{2c55}', '\u{2c25}'), ('\u{2c56}', '\u{2c26}'), ('\u{2c57}', '\u{2c27}'), - ('\u{2c58}', '\u{2c28}'), ('\u{2c59}', '\u{2c29}'), ('\u{2c5a}', '\u{2c2a}'), - ('\u{2c5b}', '\u{2c2b}'), ('\u{2c5c}', '\u{2c2c}'), ('\u{2c5d}', '\u{2c2d}'), - ('\u{2c5e}', '\u{2c2e}'), ('\u{2c5f}', '\u{2c2f}'), ('\u{2c61}', '\u{2c60}'), - ('\u{2c65}', '\u{23a}'), ('\u{2c66}', '\u{23e}'), ('\u{2c68}', '\u{2c67}'), - ('\u{2c6a}', '\u{2c69}'), ('\u{2c6c}', '\u{2c6b}'), ('\u{2c73}', '\u{2c72}'), - ('\u{2c76}', '\u{2c75}'), ('\u{2c81}', '\u{2c80}'), ('\u{2c83}', '\u{2c82}'), - ('\u{2c85}', '\u{2c84}'), ('\u{2c87}', '\u{2c86}'), ('\u{2c89}', '\u{2c88}'), - ('\u{2c8b}', '\u{2c8a}'), ('\u{2c8d}', '\u{2c8c}'), ('\u{2c8f}', '\u{2c8e}'), - ('\u{2c91}', '\u{2c90}'), ('\u{2c93}', '\u{2c92}'), ('\u{2c95}', '\u{2c94}'), - ('\u{2c97}', '\u{2c96}'), ('\u{2c99}', '\u{2c98}'), ('\u{2c9b}', '\u{2c9a}'), - ('\u{2c9d}', '\u{2c9c}'), ('\u{2c9f}', '\u{2c9e}'), ('\u{2ca1}', '\u{2ca0}'), - ('\u{2ca3}', '\u{2ca2}'), ('\u{2ca5}', '\u{2ca4}'), ('\u{2ca7}', '\u{2ca6}'), - ('\u{2ca9}', '\u{2ca8}'), ('\u{2cab}', '\u{2caa}'), ('\u{2cad}', '\u{2cac}'), - ('\u{2caf}', '\u{2cae}'), ('\u{2cb1}', '\u{2cb0}'), ('\u{2cb3}', '\u{2cb2}'), - ('\u{2cb5}', '\u{2cb4}'), ('\u{2cb7}', '\u{2cb6}'), ('\u{2cb9}', '\u{2cb8}'), - ('\u{2cbb}', '\u{2cba}'), ('\u{2cbd}', '\u{2cbc}'), ('\u{2cbf}', '\u{2cbe}'), - ('\u{2cc1}', '\u{2cc0}'), ('\u{2cc3}', '\u{2cc2}'), ('\u{2cc5}', '\u{2cc4}'), - ('\u{2cc7}', '\u{2cc6}'), ('\u{2cc9}', '\u{2cc8}'), ('\u{2ccb}', '\u{2cca}'), - ('\u{2ccd}', '\u{2ccc}'), ('\u{2ccf}', '\u{2cce}'), ('\u{2cd1}', '\u{2cd0}'), - ('\u{2cd3}', '\u{2cd2}'), ('\u{2cd5}', '\u{2cd4}'), ('\u{2cd7}', '\u{2cd6}'), - ('\u{2cd9}', '\u{2cd8}'), ('\u{2cdb}', '\u{2cda}'), ('\u{2cdd}', '\u{2cdc}'), - ('\u{2cdf}', '\u{2cde}'), ('\u{2ce1}', '\u{2ce0}'), ('\u{2ce3}', '\u{2ce2}'), - ('\u{2cec}', '\u{2ceb}'), ('\u{2cee}', '\u{2ced}'), ('\u{2cf3}', '\u{2cf2}'), - ('\u{2d00}', '\u{10a0}'), ('\u{2d01}', '\u{10a1}'), ('\u{2d02}', '\u{10a2}'), - ('\u{2d03}', '\u{10a3}'), ('\u{2d04}', '\u{10a4}'), ('\u{2d05}', '\u{10a5}'), - ('\u{2d06}', '\u{10a6}'), ('\u{2d07}', '\u{10a7}'), ('\u{2d08}', '\u{10a8}'), - ('\u{2d09}', '\u{10a9}'), ('\u{2d0a}', '\u{10aa}'), ('\u{2d0b}', '\u{10ab}'), - ('\u{2d0c}', '\u{10ac}'), ('\u{2d0d}', '\u{10ad}'), ('\u{2d0e}', '\u{10ae}'), - ('\u{2d0f}', '\u{10af}'), ('\u{2d10}', '\u{10b0}'), ('\u{2d11}', '\u{10b1}'), - ('\u{2d12}', '\u{10b2}'), ('\u{2d13}', '\u{10b3}'), ('\u{2d14}', '\u{10b4}'), - ('\u{2d15}', '\u{10b5}'), ('\u{2d16}', '\u{10b6}'), ('\u{2d17}', '\u{10b7}'), - ('\u{2d18}', '\u{10b8}'), ('\u{2d19}', '\u{10b9}'), ('\u{2d1a}', '\u{10ba}'), - ('\u{2d1b}', '\u{10bb}'), ('\u{2d1c}', '\u{10bc}'), ('\u{2d1d}', '\u{10bd}'), - ('\u{2d1e}', '\u{10be}'), ('\u{2d1f}', '\u{10bf}'), ('\u{2d20}', '\u{10c0}'), - ('\u{2d21}', '\u{10c1}'), ('\u{2d22}', '\u{10c2}'), ('\u{2d23}', '\u{10c3}'), - ('\u{2d24}', '\u{10c4}'), ('\u{2d25}', '\u{10c5}'), ('\u{2d27}', '\u{10c7}'), - ('\u{2d2d}', '\u{10cd}'), ('\u{a641}', '\u{a640}'), ('\u{a643}', '\u{a642}'), - ('\u{a645}', '\u{a644}'), ('\u{a647}', '\u{a646}'), ('\u{a649}', '\u{a648}'), - ('\u{a64b}', '\u{a64a}'), ('\u{a64d}', '\u{a64c}'), ('\u{a64f}', '\u{a64e}'), - ('\u{a651}', '\u{a650}'), ('\u{a653}', '\u{a652}'), ('\u{a655}', '\u{a654}'), - ('\u{a657}', '\u{a656}'), ('\u{a659}', '\u{a658}'), ('\u{a65b}', '\u{a65a}'), - ('\u{a65d}', '\u{a65c}'), ('\u{a65f}', '\u{a65e}'), ('\u{a661}', '\u{a660}'), - ('\u{a663}', '\u{a662}'), ('\u{a665}', '\u{a664}'), ('\u{a667}', '\u{a666}'), - ('\u{a669}', '\u{a668}'), ('\u{a66b}', '\u{a66a}'), ('\u{a66d}', '\u{a66c}'), - ('\u{a681}', '\u{a680}'), ('\u{a683}', '\u{a682}'), ('\u{a685}', '\u{a684}'), - ('\u{a687}', '\u{a686}'), ('\u{a689}', '\u{a688}'), ('\u{a68b}', '\u{a68a}'), - ('\u{a68d}', '\u{a68c}'), ('\u{a68f}', '\u{a68e}'), ('\u{a691}', '\u{a690}'), - ('\u{a693}', '\u{a692}'), ('\u{a695}', '\u{a694}'), ('\u{a697}', '\u{a696}'), - ('\u{a699}', '\u{a698}'), ('\u{a69b}', '\u{a69a}'), ('\u{a723}', '\u{a722}'), - ('\u{a725}', '\u{a724}'), ('\u{a727}', '\u{a726}'), ('\u{a729}', '\u{a728}'), - ('\u{a72b}', '\u{a72a}'), ('\u{a72d}', '\u{a72c}'), ('\u{a72f}', '\u{a72e}'), - ('\u{a733}', '\u{a732}'), ('\u{a735}', '\u{a734}'), ('\u{a737}', '\u{a736}'), - ('\u{a739}', '\u{a738}'), ('\u{a73b}', '\u{a73a}'), ('\u{a73d}', '\u{a73c}'), - ('\u{a73f}', '\u{a73e}'), ('\u{a741}', '\u{a740}'), ('\u{a743}', '\u{a742}'), - ('\u{a745}', '\u{a744}'), ('\u{a747}', '\u{a746}'), ('\u{a749}', '\u{a748}'), - ('\u{a74b}', '\u{a74a}'), ('\u{a74d}', '\u{a74c}'), ('\u{a74f}', '\u{a74e}'), - ('\u{a751}', '\u{a750}'), ('\u{a753}', '\u{a752}'), ('\u{a755}', '\u{a754}'), - ('\u{a757}', '\u{a756}'), ('\u{a759}', '\u{a758}'), ('\u{a75b}', '\u{a75a}'), - ('\u{a75d}', '\u{a75c}'), ('\u{a75f}', '\u{a75e}'), ('\u{a761}', '\u{a760}'), - ('\u{a763}', '\u{a762}'), ('\u{a765}', '\u{a764}'), ('\u{a767}', '\u{a766}'), - ('\u{a769}', '\u{a768}'), ('\u{a76b}', '\u{a76a}'), ('\u{a76d}', '\u{a76c}'), - ('\u{a76f}', '\u{a76e}'), ('\u{a77a}', '\u{a779}'), ('\u{a77c}', '\u{a77b}'), - ('\u{a77f}', '\u{a77e}'), ('\u{a781}', '\u{a780}'), ('\u{a783}', '\u{a782}'), - ('\u{a785}', '\u{a784}'), ('\u{a787}', '\u{a786}'), ('\u{a78c}', '\u{a78b}'), - ('\u{a791}', '\u{a790}'), ('\u{a793}', '\u{a792}'), ('\u{a794}', '\u{a7c4}'), - ('\u{a797}', '\u{a796}'), ('\u{a799}', '\u{a798}'), ('\u{a79b}', '\u{a79a}'), - ('\u{a79d}', '\u{a79c}'), ('\u{a79f}', '\u{a79e}'), ('\u{a7a1}', '\u{a7a0}'), - ('\u{a7a3}', '\u{a7a2}'), ('\u{a7a5}', '\u{a7a4}'), ('\u{a7a7}', '\u{a7a6}'), - ('\u{a7a9}', '\u{a7a8}'), ('\u{a7b5}', '\u{a7b4}'), ('\u{a7b7}', '\u{a7b6}'), - ('\u{a7b9}', '\u{a7b8}'), ('\u{a7bb}', '\u{a7ba}'), ('\u{a7bd}', '\u{a7bc}'), - ('\u{a7bf}', '\u{a7be}'), ('\u{a7c1}', '\u{a7c0}'), ('\u{a7c3}', '\u{a7c2}'), - ('\u{a7c8}', '\u{a7c7}'), ('\u{a7ca}', '\u{a7c9}'), ('\u{a7d1}', '\u{a7d0}'), - ('\u{a7d7}', '\u{a7d6}'), ('\u{a7d9}', '\u{a7d8}'), ('\u{a7f6}', '\u{a7f5}'), - ('\u{ab53}', '\u{a7b3}'), ('\u{ab70}', '\u{13a0}'), ('\u{ab71}', '\u{13a1}'), - ('\u{ab72}', '\u{13a2}'), ('\u{ab73}', '\u{13a3}'), ('\u{ab74}', '\u{13a4}'), - ('\u{ab75}', '\u{13a5}'), ('\u{ab76}', '\u{13a6}'), ('\u{ab77}', '\u{13a7}'), - ('\u{ab78}', '\u{13a8}'), ('\u{ab79}', '\u{13a9}'), ('\u{ab7a}', '\u{13aa}'), - ('\u{ab7b}', '\u{13ab}'), ('\u{ab7c}', '\u{13ac}'), ('\u{ab7d}', '\u{13ad}'), - ('\u{ab7e}', '\u{13ae}'), ('\u{ab7f}', '\u{13af}'), ('\u{ab80}', '\u{13b0}'), - ('\u{ab81}', '\u{13b1}'), ('\u{ab82}', '\u{13b2}'), ('\u{ab83}', '\u{13b3}'), - ('\u{ab84}', '\u{13b4}'), ('\u{ab85}', '\u{13b5}'), ('\u{ab86}', '\u{13b6}'), - ('\u{ab87}', '\u{13b7}'), ('\u{ab88}', '\u{13b8}'), ('\u{ab89}', '\u{13b9}'), - ('\u{ab8a}', '\u{13ba}'), ('\u{ab8b}', '\u{13bb}'), ('\u{ab8c}', '\u{13bc}'), - ('\u{ab8d}', '\u{13bd}'), ('\u{ab8e}', '\u{13be}'), ('\u{ab8f}', '\u{13bf}'), - ('\u{ab90}', '\u{13c0}'), ('\u{ab91}', '\u{13c1}'), ('\u{ab92}', '\u{13c2}'), - ('\u{ab93}', '\u{13c3}'), ('\u{ab94}', '\u{13c4}'), ('\u{ab95}', '\u{13c5}'), - ('\u{ab96}', '\u{13c6}'), ('\u{ab97}', '\u{13c7}'), ('\u{ab98}', '\u{13c8}'), - ('\u{ab99}', '\u{13c9}'), ('\u{ab9a}', '\u{13ca}'), ('\u{ab9b}', '\u{13cb}'), - ('\u{ab9c}', '\u{13cc}'), ('\u{ab9d}', '\u{13cd}'), ('\u{ab9e}', '\u{13ce}'), - ('\u{ab9f}', '\u{13cf}'), ('\u{aba0}', '\u{13d0}'), ('\u{aba1}', '\u{13d1}'), - ('\u{aba2}', '\u{13d2}'), ('\u{aba3}', '\u{13d3}'), ('\u{aba4}', '\u{13d4}'), - ('\u{aba5}', '\u{13d5}'), ('\u{aba6}', '\u{13d6}'), ('\u{aba7}', '\u{13d7}'), - ('\u{aba8}', '\u{13d8}'), ('\u{aba9}', '\u{13d9}'), ('\u{abaa}', '\u{13da}'), - ('\u{abab}', '\u{13db}'), ('\u{abac}', '\u{13dc}'), ('\u{abad}', '\u{13dd}'), - ('\u{abae}', '\u{13de}'), ('\u{abaf}', '\u{13df}'), ('\u{abb0}', '\u{13e0}'), - ('\u{abb1}', '\u{13e1}'), ('\u{abb2}', '\u{13e2}'), ('\u{abb3}', '\u{13e3}'), - ('\u{abb4}', '\u{13e4}'), ('\u{abb5}', '\u{13e5}'), ('\u{abb6}', '\u{13e6}'), - ('\u{abb7}', '\u{13e7}'), ('\u{abb8}', '\u{13e8}'), ('\u{abb9}', '\u{13e9}'), - ('\u{abba}', '\u{13ea}'), ('\u{abbb}', '\u{13eb}'), ('\u{abbc}', '\u{13ec}'), - ('\u{abbd}', '\u{13ed}'), ('\u{abbe}', '\u{13ee}'), ('\u{abbf}', '\u{13ef}'), - ('\u{ff41}', '\u{ff21}'), ('\u{ff42}', '\u{ff22}'), ('\u{ff43}', '\u{ff23}'), - ('\u{ff44}', '\u{ff24}'), ('\u{ff45}', '\u{ff25}'), ('\u{ff46}', '\u{ff26}'), - ('\u{ff47}', '\u{ff27}'), ('\u{ff48}', '\u{ff28}'), ('\u{ff49}', '\u{ff29}'), - ('\u{ff4a}', '\u{ff2a}'), ('\u{ff4b}', '\u{ff2b}'), ('\u{ff4c}', '\u{ff2c}'), - ('\u{ff4d}', '\u{ff2d}'), ('\u{ff4e}', '\u{ff2e}'), ('\u{ff4f}', '\u{ff2f}'), - ('\u{ff50}', '\u{ff30}'), ('\u{ff51}', '\u{ff31}'), ('\u{ff52}', '\u{ff32}'), - ('\u{ff53}', '\u{ff33}'), ('\u{ff54}', '\u{ff34}'), ('\u{ff55}', '\u{ff35}'), - ('\u{ff56}', '\u{ff36}'), ('\u{ff57}', '\u{ff37}'), ('\u{ff58}', '\u{ff38}'), - ('\u{ff59}', '\u{ff39}'), ('\u{ff5a}', '\u{ff3a}'), ('\u{10428}', '\u{10400}'), - ('\u{10429}', '\u{10401}'), ('\u{1042a}', '\u{10402}'), ('\u{1042b}', '\u{10403}'), - ('\u{1042c}', '\u{10404}'), ('\u{1042d}', '\u{10405}'), ('\u{1042e}', '\u{10406}'), - ('\u{1042f}', '\u{10407}'), ('\u{10430}', '\u{10408}'), ('\u{10431}', '\u{10409}'), - ('\u{10432}', '\u{1040a}'), ('\u{10433}', '\u{1040b}'), ('\u{10434}', '\u{1040c}'), - ('\u{10435}', '\u{1040d}'), ('\u{10436}', '\u{1040e}'), ('\u{10437}', '\u{1040f}'), - ('\u{10438}', '\u{10410}'), ('\u{10439}', '\u{10411}'), ('\u{1043a}', '\u{10412}'), - ('\u{1043b}', '\u{10413}'), ('\u{1043c}', '\u{10414}'), ('\u{1043d}', '\u{10415}'), - ('\u{1043e}', '\u{10416}'), ('\u{1043f}', '\u{10417}'), ('\u{10440}', '\u{10418}'), - ('\u{10441}', '\u{10419}'), ('\u{10442}', '\u{1041a}'), ('\u{10443}', '\u{1041b}'), - ('\u{10444}', '\u{1041c}'), ('\u{10445}', '\u{1041d}'), ('\u{10446}', '\u{1041e}'), - ('\u{10447}', '\u{1041f}'), ('\u{10448}', '\u{10420}'), ('\u{10449}', '\u{10421}'), - ('\u{1044a}', '\u{10422}'), ('\u{1044b}', '\u{10423}'), ('\u{1044c}', '\u{10424}'), - ('\u{1044d}', '\u{10425}'), ('\u{1044e}', '\u{10426}'), ('\u{1044f}', '\u{10427}'), - ('\u{104d8}', '\u{104b0}'), ('\u{104d9}', '\u{104b1}'), ('\u{104da}', '\u{104b2}'), - ('\u{104db}', '\u{104b3}'), ('\u{104dc}', '\u{104b4}'), ('\u{104dd}', '\u{104b5}'), - ('\u{104de}', '\u{104b6}'), ('\u{104df}', '\u{104b7}'), ('\u{104e0}', '\u{104b8}'), - ('\u{104e1}', '\u{104b9}'), ('\u{104e2}', '\u{104ba}'), ('\u{104e3}', '\u{104bb}'), - ('\u{104e4}', '\u{104bc}'), ('\u{104e5}', '\u{104bd}'), ('\u{104e6}', '\u{104be}'), - ('\u{104e7}', '\u{104bf}'), ('\u{104e8}', '\u{104c0}'), ('\u{104e9}', '\u{104c1}'), - ('\u{104ea}', '\u{104c2}'), ('\u{104eb}', '\u{104c3}'), ('\u{104ec}', '\u{104c4}'), - ('\u{104ed}', '\u{104c5}'), ('\u{104ee}', '\u{104c6}'), ('\u{104ef}', '\u{104c7}'), - ('\u{104f0}', '\u{104c8}'), ('\u{104f1}', '\u{104c9}'), ('\u{104f2}', '\u{104ca}'), - ('\u{104f3}', '\u{104cb}'), ('\u{104f4}', '\u{104cc}'), ('\u{104f5}', '\u{104cd}'), - ('\u{104f6}', '\u{104ce}'), ('\u{104f7}', '\u{104cf}'), ('\u{104f8}', '\u{104d0}'), - ('\u{104f9}', '\u{104d1}'), ('\u{104fa}', '\u{104d2}'), ('\u{104fb}', '\u{104d3}'), - ('\u{10597}', '\u{10570}'), ('\u{10598}', '\u{10571}'), ('\u{10599}', '\u{10572}'), - ('\u{1059a}', '\u{10573}'), ('\u{1059b}', '\u{10574}'), ('\u{1059c}', '\u{10575}'), - ('\u{1059d}', '\u{10576}'), ('\u{1059e}', '\u{10577}'), ('\u{1059f}', '\u{10578}'), - ('\u{105a0}', '\u{10579}'), ('\u{105a1}', '\u{1057a}'), ('\u{105a3}', '\u{1057c}'), - ('\u{105a4}', '\u{1057d}'), ('\u{105a5}', '\u{1057e}'), ('\u{105a6}', '\u{1057f}'), - ('\u{105a7}', '\u{10580}'), ('\u{105a8}', '\u{10581}'), ('\u{105a9}', '\u{10582}'), - ('\u{105aa}', '\u{10583}'), ('\u{105ab}', '\u{10584}'), ('\u{105ac}', '\u{10585}'), - ('\u{105ad}', '\u{10586}'), ('\u{105ae}', '\u{10587}'), ('\u{105af}', '\u{10588}'), - ('\u{105b0}', '\u{10589}'), ('\u{105b1}', '\u{1058a}'), ('\u{105b3}', '\u{1058c}'), - ('\u{105b4}', '\u{1058d}'), ('\u{105b5}', '\u{1058e}'), ('\u{105b6}', '\u{1058f}'), - ('\u{105b7}', '\u{10590}'), ('\u{105b8}', '\u{10591}'), ('\u{105b9}', '\u{10592}'), - ('\u{105bb}', '\u{10594}'), ('\u{105bc}', '\u{10595}'), ('\u{10cc0}', '\u{10c80}'), - ('\u{10cc1}', '\u{10c81}'), ('\u{10cc2}', '\u{10c82}'), ('\u{10cc3}', '\u{10c83}'), - ('\u{10cc4}', '\u{10c84}'), ('\u{10cc5}', '\u{10c85}'), ('\u{10cc6}', '\u{10c86}'), - ('\u{10cc7}', '\u{10c87}'), ('\u{10cc8}', '\u{10c88}'), ('\u{10cc9}', '\u{10c89}'), - ('\u{10cca}', '\u{10c8a}'), ('\u{10ccb}', '\u{10c8b}'), ('\u{10ccc}', '\u{10c8c}'), - ('\u{10ccd}', '\u{10c8d}'), ('\u{10cce}', '\u{10c8e}'), ('\u{10ccf}', '\u{10c8f}'), - ('\u{10cd0}', '\u{10c90}'), ('\u{10cd1}', '\u{10c91}'), ('\u{10cd2}', '\u{10c92}'), - ('\u{10cd3}', '\u{10c93}'), ('\u{10cd4}', '\u{10c94}'), ('\u{10cd5}', '\u{10c95}'), - ('\u{10cd6}', '\u{10c96}'), ('\u{10cd7}', '\u{10c97}'), ('\u{10cd8}', '\u{10c98}'), - ('\u{10cd9}', '\u{10c99}'), ('\u{10cda}', '\u{10c9a}'), ('\u{10cdb}', '\u{10c9b}'), - ('\u{10cdc}', '\u{10c9c}'), ('\u{10cdd}', '\u{10c9d}'), ('\u{10cde}', '\u{10c9e}'), - ('\u{10cdf}', '\u{10c9f}'), ('\u{10ce0}', '\u{10ca0}'), ('\u{10ce1}', '\u{10ca1}'), - ('\u{10ce2}', '\u{10ca2}'), ('\u{10ce3}', '\u{10ca3}'), ('\u{10ce4}', '\u{10ca4}'), - ('\u{10ce5}', '\u{10ca5}'), ('\u{10ce6}', '\u{10ca6}'), ('\u{10ce7}', '\u{10ca7}'), - ('\u{10ce8}', '\u{10ca8}'), ('\u{10ce9}', '\u{10ca9}'), ('\u{10cea}', '\u{10caa}'), - ('\u{10ceb}', '\u{10cab}'), ('\u{10cec}', '\u{10cac}'), ('\u{10ced}', '\u{10cad}'), - ('\u{10cee}', '\u{10cae}'), ('\u{10cef}', '\u{10caf}'), ('\u{10cf0}', '\u{10cb0}'), - ('\u{10cf1}', '\u{10cb1}'), ('\u{10cf2}', '\u{10cb2}'), ('\u{118c0}', '\u{118a0}'), - ('\u{118c1}', '\u{118a1}'), ('\u{118c2}', '\u{118a2}'), ('\u{118c3}', '\u{118a3}'), - ('\u{118c4}', '\u{118a4}'), ('\u{118c5}', '\u{118a5}'), ('\u{118c6}', '\u{118a6}'), - ('\u{118c7}', '\u{118a7}'), ('\u{118c8}', '\u{118a8}'), ('\u{118c9}', '\u{118a9}'), - ('\u{118ca}', '\u{118aa}'), ('\u{118cb}', '\u{118ab}'), ('\u{118cc}', '\u{118ac}'), - ('\u{118cd}', '\u{118ad}'), ('\u{118ce}', '\u{118ae}'), ('\u{118cf}', '\u{118af}'), - ('\u{118d0}', '\u{118b0}'), ('\u{118d1}', '\u{118b1}'), ('\u{118d2}', '\u{118b2}'), - ('\u{118d3}', '\u{118b3}'), ('\u{118d4}', '\u{118b4}'), ('\u{118d5}', '\u{118b5}'), - ('\u{118d6}', '\u{118b6}'), ('\u{118d7}', '\u{118b7}'), ('\u{118d8}', '\u{118b8}'), - ('\u{118d9}', '\u{118b9}'), ('\u{118da}', '\u{118ba}'), ('\u{118db}', '\u{118bb}'), - ('\u{118dc}', '\u{118bc}'), ('\u{118dd}', '\u{118bd}'), ('\u{118de}', '\u{118be}'), - ('\u{118df}', '\u{118bf}'), ('\u{16e60}', '\u{16e40}'), ('\u{16e61}', '\u{16e41}'), - ('\u{16e62}', '\u{16e42}'), ('\u{16e63}', '\u{16e43}'), ('\u{16e64}', '\u{16e44}'), - ('\u{16e65}', '\u{16e45}'), ('\u{16e66}', '\u{16e46}'), ('\u{16e67}', '\u{16e47}'), - ('\u{16e68}', '\u{16e48}'), ('\u{16e69}', '\u{16e49}'), ('\u{16e6a}', '\u{16e4a}'), - ('\u{16e6b}', '\u{16e4b}'), ('\u{16e6c}', '\u{16e4c}'), ('\u{16e6d}', '\u{16e4d}'), - ('\u{16e6e}', '\u{16e4e}'), ('\u{16e6f}', '\u{16e4f}'), ('\u{16e70}', '\u{16e50}'), - ('\u{16e71}', '\u{16e51}'), ('\u{16e72}', '\u{16e52}'), ('\u{16e73}', '\u{16e53}'), - ('\u{16e74}', '\u{16e54}'), ('\u{16e75}', '\u{16e55}'), ('\u{16e76}', '\u{16e56}'), - ('\u{16e77}', '\u{16e57}'), ('\u{16e78}', '\u{16e58}'), ('\u{16e79}', '\u{16e59}'), - ('\u{16e7a}', '\u{16e5a}'), ('\u{16e7b}', '\u{16e5b}'), ('\u{16e7c}', '\u{16e5c}'), - ('\u{16e7d}', '\u{16e5d}'), ('\u{16e7e}', '\u{16e5e}'), ('\u{16e7f}', '\u{16e5f}'), - ('\u{1e922}', '\u{1e900}'), ('\u{1e923}', '\u{1e901}'), ('\u{1e924}', '\u{1e902}'), - ('\u{1e925}', '\u{1e903}'), ('\u{1e926}', '\u{1e904}'), ('\u{1e927}', '\u{1e905}'), - ('\u{1e928}', '\u{1e906}'), ('\u{1e929}', '\u{1e907}'), ('\u{1e92a}', '\u{1e908}'), - ('\u{1e92b}', '\u{1e909}'), ('\u{1e92c}', '\u{1e90a}'), ('\u{1e92d}', '\u{1e90b}'), - ('\u{1e92e}', '\u{1e90c}'), ('\u{1e92f}', '\u{1e90d}'), ('\u{1e930}', '\u{1e90e}'), - ('\u{1e931}', '\u{1e90f}'), ('\u{1e932}', '\u{1e910}'), ('\u{1e933}', '\u{1e911}'), - ('\u{1e934}', '\u{1e912}'), ('\u{1e935}', '\u{1e913}'), ('\u{1e936}', '\u{1e914}'), - ('\u{1e937}', '\u{1e915}'), ('\u{1e938}', '\u{1e916}'), ('\u{1e939}', '\u{1e917}'), - ('\u{1e93a}', '\u{1e918}'), ('\u{1e93b}', '\u{1e919}'), ('\u{1e93c}', '\u{1e91a}'), - ('\u{1e93d}', '\u{1e91b}'), ('\u{1e93e}', '\u{1e91c}'), ('\u{1e93f}', '\u{1e91d}'), - ('\u{1e940}', '\u{1e91e}'), ('\u{1e941}', '\u{1e91f}'), ('\u{1e942}', '\u{1e920}'), - ('\u{1e943}', '\u{1e921}'), + static UPPERCASE_TABLE: &[(char, u32)] = &[ + ('\u{b5}', 924), ('\u{df}', 4194304), ('\u{e0}', 192), ('\u{e1}', 193), ('\u{e2}', 194), + ('\u{e3}', 195), ('\u{e4}', 196), ('\u{e5}', 197), ('\u{e6}', 198), ('\u{e7}', 199), + ('\u{e8}', 200), ('\u{e9}', 201), ('\u{ea}', 202), ('\u{eb}', 203), ('\u{ec}', 204), + ('\u{ed}', 205), ('\u{ee}', 206), ('\u{ef}', 207), ('\u{f0}', 208), ('\u{f1}', 209), + ('\u{f2}', 210), ('\u{f3}', 211), ('\u{f4}', 212), ('\u{f5}', 213), ('\u{f6}', 214), + ('\u{f8}', 216), ('\u{f9}', 217), ('\u{fa}', 218), ('\u{fb}', 219), ('\u{fc}', 220), + ('\u{fd}', 221), ('\u{fe}', 222), ('\u{ff}', 376), ('\u{101}', 256), ('\u{103}', 258), + ('\u{105}', 260), ('\u{107}', 262), ('\u{109}', 264), ('\u{10b}', 266), ('\u{10d}', 268), + ('\u{10f}', 270), ('\u{111}', 272), ('\u{113}', 274), ('\u{115}', 276), ('\u{117}', 278), + ('\u{119}', 280), ('\u{11b}', 282), ('\u{11d}', 284), ('\u{11f}', 286), ('\u{121}', 288), + ('\u{123}', 290), ('\u{125}', 292), ('\u{127}', 294), ('\u{129}', 296), ('\u{12b}', 298), + ('\u{12d}', 300), ('\u{12f}', 302), ('\u{131}', 73), ('\u{133}', 306), ('\u{135}', 308), + ('\u{137}', 310), ('\u{13a}', 313), ('\u{13c}', 315), ('\u{13e}', 317), ('\u{140}', 319), + ('\u{142}', 321), ('\u{144}', 323), ('\u{146}', 325), ('\u{148}', 327), + ('\u{149}', 4194305), ('\u{14b}', 330), ('\u{14d}', 332), ('\u{14f}', 334), + ('\u{151}', 336), ('\u{153}', 338), ('\u{155}', 340), ('\u{157}', 342), ('\u{159}', 344), + ('\u{15b}', 346), ('\u{15d}', 348), ('\u{15f}', 350), ('\u{161}', 352), ('\u{163}', 354), + ('\u{165}', 356), ('\u{167}', 358), ('\u{169}', 360), ('\u{16b}', 362), ('\u{16d}', 364), + ('\u{16f}', 366), ('\u{171}', 368), ('\u{173}', 370), ('\u{175}', 372), ('\u{177}', 374), + ('\u{17a}', 377), ('\u{17c}', 379), ('\u{17e}', 381), ('\u{17f}', 83), ('\u{180}', 579), + ('\u{183}', 386), ('\u{185}', 388), ('\u{188}', 391), ('\u{18c}', 395), ('\u{192}', 401), + ('\u{195}', 502), ('\u{199}', 408), ('\u{19a}', 573), ('\u{19e}', 544), ('\u{1a1}', 416), + ('\u{1a3}', 418), ('\u{1a5}', 420), ('\u{1a8}', 423), ('\u{1ad}', 428), ('\u{1b0}', 431), + ('\u{1b4}', 435), ('\u{1b6}', 437), ('\u{1b9}', 440), ('\u{1bd}', 444), ('\u{1bf}', 503), + ('\u{1c5}', 452), ('\u{1c6}', 452), ('\u{1c8}', 455), ('\u{1c9}', 455), ('\u{1cb}', 458), + ('\u{1cc}', 458), ('\u{1ce}', 461), ('\u{1d0}', 463), ('\u{1d2}', 465), ('\u{1d4}', 467), + ('\u{1d6}', 469), ('\u{1d8}', 471), ('\u{1da}', 473), ('\u{1dc}', 475), ('\u{1dd}', 398), + ('\u{1df}', 478), ('\u{1e1}', 480), ('\u{1e3}', 482), ('\u{1e5}', 484), ('\u{1e7}', 486), + ('\u{1e9}', 488), ('\u{1eb}', 490), ('\u{1ed}', 492), ('\u{1ef}', 494), + ('\u{1f0}', 4194306), ('\u{1f2}', 497), ('\u{1f3}', 497), ('\u{1f5}', 500), + ('\u{1f9}', 504), ('\u{1fb}', 506), ('\u{1fd}', 508), ('\u{1ff}', 510), ('\u{201}', 512), + ('\u{203}', 514), ('\u{205}', 516), ('\u{207}', 518), ('\u{209}', 520), ('\u{20b}', 522), + ('\u{20d}', 524), ('\u{20f}', 526), ('\u{211}', 528), ('\u{213}', 530), ('\u{215}', 532), + ('\u{217}', 534), ('\u{219}', 536), ('\u{21b}', 538), ('\u{21d}', 540), ('\u{21f}', 542), + ('\u{223}', 546), ('\u{225}', 548), ('\u{227}', 550), ('\u{229}', 552), ('\u{22b}', 554), + ('\u{22d}', 556), ('\u{22f}', 558), ('\u{231}', 560), ('\u{233}', 562), ('\u{23c}', 571), + ('\u{23f}', 11390), ('\u{240}', 11391), ('\u{242}', 577), ('\u{247}', 582), + ('\u{249}', 584), ('\u{24b}', 586), ('\u{24d}', 588), ('\u{24f}', 590), ('\u{250}', 11375), + ('\u{251}', 11373), ('\u{252}', 11376), ('\u{253}', 385), ('\u{254}', 390), + ('\u{256}', 393), ('\u{257}', 394), ('\u{259}', 399), ('\u{25b}', 400), ('\u{25c}', 42923), + ('\u{260}', 403), ('\u{261}', 42924), ('\u{263}', 404), ('\u{265}', 42893), + ('\u{266}', 42922), ('\u{268}', 407), ('\u{269}', 406), ('\u{26a}', 42926), + ('\u{26b}', 11362), ('\u{26c}', 42925), ('\u{26f}', 412), ('\u{271}', 11374), + ('\u{272}', 413), ('\u{275}', 415), ('\u{27d}', 11364), ('\u{280}', 422), + ('\u{282}', 42949), ('\u{283}', 425), ('\u{287}', 42929), ('\u{288}', 430), + ('\u{289}', 580), ('\u{28a}', 433), ('\u{28b}', 434), ('\u{28c}', 581), ('\u{292}', 439), + ('\u{29d}', 42930), ('\u{29e}', 42928), ('\u{345}', 921), ('\u{371}', 880), + ('\u{373}', 882), ('\u{377}', 886), ('\u{37b}', 1021), ('\u{37c}', 1022), ('\u{37d}', 1023), + ('\u{390}', 4194307), ('\u{3ac}', 902), ('\u{3ad}', 904), ('\u{3ae}', 905), + ('\u{3af}', 906), ('\u{3b0}', 4194308), ('\u{3b1}', 913), ('\u{3b2}', 914), + ('\u{3b3}', 915), ('\u{3b4}', 916), ('\u{3b5}', 917), ('\u{3b6}', 918), ('\u{3b7}', 919), + ('\u{3b8}', 920), ('\u{3b9}', 921), ('\u{3ba}', 922), ('\u{3bb}', 923), ('\u{3bc}', 924), + ('\u{3bd}', 925), ('\u{3be}', 926), ('\u{3bf}', 927), ('\u{3c0}', 928), ('\u{3c1}', 929), + ('\u{3c2}', 931), ('\u{3c3}', 931), ('\u{3c4}', 932), ('\u{3c5}', 933), ('\u{3c6}', 934), + ('\u{3c7}', 935), ('\u{3c8}', 936), ('\u{3c9}', 937), ('\u{3ca}', 938), ('\u{3cb}', 939), + ('\u{3cc}', 908), ('\u{3cd}', 910), ('\u{3ce}', 911), ('\u{3d0}', 914), ('\u{3d1}', 920), + ('\u{3d5}', 934), ('\u{3d6}', 928), ('\u{3d7}', 975), ('\u{3d9}', 984), ('\u{3db}', 986), + ('\u{3dd}', 988), ('\u{3df}', 990), ('\u{3e1}', 992), ('\u{3e3}', 994), ('\u{3e5}', 996), + ('\u{3e7}', 998), ('\u{3e9}', 1000), ('\u{3eb}', 1002), ('\u{3ed}', 1004), + ('\u{3ef}', 1006), ('\u{3f0}', 922), ('\u{3f1}', 929), ('\u{3f2}', 1017), ('\u{3f3}', 895), + ('\u{3f5}', 917), ('\u{3f8}', 1015), ('\u{3fb}', 1018), ('\u{430}', 1040), + ('\u{431}', 1041), ('\u{432}', 1042), ('\u{433}', 1043), ('\u{434}', 1044), + ('\u{435}', 1045), ('\u{436}', 1046), ('\u{437}', 1047), ('\u{438}', 1048), + ('\u{439}', 1049), ('\u{43a}', 1050), ('\u{43b}', 1051), ('\u{43c}', 1052), + ('\u{43d}', 1053), ('\u{43e}', 1054), ('\u{43f}', 1055), ('\u{440}', 1056), + ('\u{441}', 1057), ('\u{442}', 1058), ('\u{443}', 1059), ('\u{444}', 1060), + ('\u{445}', 1061), ('\u{446}', 1062), ('\u{447}', 1063), ('\u{448}', 1064), + ('\u{449}', 1065), ('\u{44a}', 1066), ('\u{44b}', 1067), ('\u{44c}', 1068), + ('\u{44d}', 1069), ('\u{44e}', 1070), ('\u{44f}', 1071), ('\u{450}', 1024), + ('\u{451}', 1025), ('\u{452}', 1026), ('\u{453}', 1027), ('\u{454}', 1028), + ('\u{455}', 1029), ('\u{456}', 1030), ('\u{457}', 1031), ('\u{458}', 1032), + ('\u{459}', 1033), ('\u{45a}', 1034), ('\u{45b}', 1035), ('\u{45c}', 1036), + ('\u{45d}', 1037), ('\u{45e}', 1038), ('\u{45f}', 1039), ('\u{461}', 1120), + ('\u{463}', 1122), ('\u{465}', 1124), ('\u{467}', 1126), ('\u{469}', 1128), + ('\u{46b}', 1130), ('\u{46d}', 1132), ('\u{46f}', 1134), ('\u{471}', 1136), + ('\u{473}', 1138), ('\u{475}', 1140), ('\u{477}', 1142), ('\u{479}', 1144), + ('\u{47b}', 1146), ('\u{47d}', 1148), ('\u{47f}', 1150), ('\u{481}', 1152), + ('\u{48b}', 1162), ('\u{48d}', 1164), ('\u{48f}', 1166), ('\u{491}', 1168), + ('\u{493}', 1170), ('\u{495}', 1172), ('\u{497}', 1174), ('\u{499}', 1176), + ('\u{49b}', 1178), ('\u{49d}', 1180), ('\u{49f}', 1182), ('\u{4a1}', 1184), + ('\u{4a3}', 1186), ('\u{4a5}', 1188), ('\u{4a7}', 1190), ('\u{4a9}', 1192), + ('\u{4ab}', 1194), ('\u{4ad}', 1196), ('\u{4af}', 1198), ('\u{4b1}', 1200), + ('\u{4b3}', 1202), ('\u{4b5}', 1204), ('\u{4b7}', 1206), ('\u{4b9}', 1208), + ('\u{4bb}', 1210), ('\u{4bd}', 1212), ('\u{4bf}', 1214), ('\u{4c2}', 1217), + ('\u{4c4}', 1219), ('\u{4c6}', 1221), ('\u{4c8}', 1223), ('\u{4ca}', 1225), + ('\u{4cc}', 1227), ('\u{4ce}', 1229), ('\u{4cf}', 1216), ('\u{4d1}', 1232), + ('\u{4d3}', 1234), ('\u{4d5}', 1236), ('\u{4d7}', 1238), ('\u{4d9}', 1240), + ('\u{4db}', 1242), ('\u{4dd}', 1244), ('\u{4df}', 1246), ('\u{4e1}', 1248), + ('\u{4e3}', 1250), ('\u{4e5}', 1252), ('\u{4e7}', 1254), ('\u{4e9}', 1256), + ('\u{4eb}', 1258), ('\u{4ed}', 1260), ('\u{4ef}', 1262), ('\u{4f1}', 1264), + ('\u{4f3}', 1266), ('\u{4f5}', 1268), ('\u{4f7}', 1270), ('\u{4f9}', 1272), + ('\u{4fb}', 1274), ('\u{4fd}', 1276), ('\u{4ff}', 1278), ('\u{501}', 1280), + ('\u{503}', 1282), ('\u{505}', 1284), ('\u{507}', 1286), ('\u{509}', 1288), + ('\u{50b}', 1290), ('\u{50d}', 1292), ('\u{50f}', 1294), ('\u{511}', 1296), + ('\u{513}', 1298), ('\u{515}', 1300), ('\u{517}', 1302), ('\u{519}', 1304), + ('\u{51b}', 1306), ('\u{51d}', 1308), ('\u{51f}', 1310), ('\u{521}', 1312), + ('\u{523}', 1314), ('\u{525}', 1316), ('\u{527}', 1318), ('\u{529}', 1320), + ('\u{52b}', 1322), ('\u{52d}', 1324), ('\u{52f}', 1326), ('\u{561}', 1329), + ('\u{562}', 1330), ('\u{563}', 1331), ('\u{564}', 1332), ('\u{565}', 1333), + ('\u{566}', 1334), ('\u{567}', 1335), ('\u{568}', 1336), ('\u{569}', 1337), + ('\u{56a}', 1338), ('\u{56b}', 1339), ('\u{56c}', 1340), ('\u{56d}', 1341), + ('\u{56e}', 1342), ('\u{56f}', 1343), ('\u{570}', 1344), ('\u{571}', 1345), + ('\u{572}', 1346), ('\u{573}', 1347), ('\u{574}', 1348), ('\u{575}', 1349), + ('\u{576}', 1350), ('\u{577}', 1351), ('\u{578}', 1352), ('\u{579}', 1353), + ('\u{57a}', 1354), ('\u{57b}', 1355), ('\u{57c}', 1356), ('\u{57d}', 1357), + ('\u{57e}', 1358), ('\u{57f}', 1359), ('\u{580}', 1360), ('\u{581}', 1361), + ('\u{582}', 1362), ('\u{583}', 1363), ('\u{584}', 1364), ('\u{585}', 1365), + ('\u{586}', 1366), ('\u{587}', 4194309), ('\u{10d0}', 7312), ('\u{10d1}', 7313), + ('\u{10d2}', 7314), ('\u{10d3}', 7315), ('\u{10d4}', 7316), ('\u{10d5}', 7317), + ('\u{10d6}', 7318), ('\u{10d7}', 7319), ('\u{10d8}', 7320), ('\u{10d9}', 7321), + ('\u{10da}', 7322), ('\u{10db}', 7323), ('\u{10dc}', 7324), ('\u{10dd}', 7325), + ('\u{10de}', 7326), ('\u{10df}', 7327), ('\u{10e0}', 7328), ('\u{10e1}', 7329), + ('\u{10e2}', 7330), ('\u{10e3}', 7331), ('\u{10e4}', 7332), ('\u{10e5}', 7333), + ('\u{10e6}', 7334), ('\u{10e7}', 7335), ('\u{10e8}', 7336), ('\u{10e9}', 7337), + ('\u{10ea}', 7338), ('\u{10eb}', 7339), ('\u{10ec}', 7340), ('\u{10ed}', 7341), + ('\u{10ee}', 7342), ('\u{10ef}', 7343), ('\u{10f0}', 7344), ('\u{10f1}', 7345), + ('\u{10f2}', 7346), ('\u{10f3}', 7347), ('\u{10f4}', 7348), ('\u{10f5}', 7349), + ('\u{10f6}', 7350), ('\u{10f7}', 7351), ('\u{10f8}', 7352), ('\u{10f9}', 7353), + ('\u{10fa}', 7354), ('\u{10fd}', 7357), ('\u{10fe}', 7358), ('\u{10ff}', 7359), + ('\u{13f8}', 5104), ('\u{13f9}', 5105), ('\u{13fa}', 5106), ('\u{13fb}', 5107), + ('\u{13fc}', 5108), ('\u{13fd}', 5109), ('\u{1c80}', 1042), ('\u{1c81}', 1044), + ('\u{1c82}', 1054), ('\u{1c83}', 1057), ('\u{1c84}', 1058), ('\u{1c85}', 1058), + ('\u{1c86}', 1066), ('\u{1c87}', 1122), ('\u{1c88}', 42570), ('\u{1d79}', 42877), + ('\u{1d7d}', 11363), ('\u{1d8e}', 42950), ('\u{1e01}', 7680), ('\u{1e03}', 7682), + ('\u{1e05}', 7684), ('\u{1e07}', 7686), ('\u{1e09}', 7688), ('\u{1e0b}', 7690), + ('\u{1e0d}', 7692), ('\u{1e0f}', 7694), ('\u{1e11}', 7696), ('\u{1e13}', 7698), + ('\u{1e15}', 7700), ('\u{1e17}', 7702), ('\u{1e19}', 7704), ('\u{1e1b}', 7706), + ('\u{1e1d}', 7708), ('\u{1e1f}', 7710), ('\u{1e21}', 7712), ('\u{1e23}', 7714), + ('\u{1e25}', 7716), ('\u{1e27}', 7718), ('\u{1e29}', 7720), ('\u{1e2b}', 7722), + ('\u{1e2d}', 7724), ('\u{1e2f}', 7726), ('\u{1e31}', 7728), ('\u{1e33}', 7730), + ('\u{1e35}', 7732), ('\u{1e37}', 7734), ('\u{1e39}', 7736), ('\u{1e3b}', 7738), + ('\u{1e3d}', 7740), ('\u{1e3f}', 7742), ('\u{1e41}', 7744), ('\u{1e43}', 7746), + ('\u{1e45}', 7748), ('\u{1e47}', 7750), ('\u{1e49}', 7752), ('\u{1e4b}', 7754), + ('\u{1e4d}', 7756), ('\u{1e4f}', 7758), ('\u{1e51}', 7760), ('\u{1e53}', 7762), + ('\u{1e55}', 7764), ('\u{1e57}', 7766), ('\u{1e59}', 7768), ('\u{1e5b}', 7770), + ('\u{1e5d}', 7772), ('\u{1e5f}', 7774), ('\u{1e61}', 7776), ('\u{1e63}', 7778), + ('\u{1e65}', 7780), ('\u{1e67}', 7782), ('\u{1e69}', 7784), ('\u{1e6b}', 7786), + ('\u{1e6d}', 7788), ('\u{1e6f}', 7790), ('\u{1e71}', 7792), ('\u{1e73}', 7794), + ('\u{1e75}', 7796), ('\u{1e77}', 7798), ('\u{1e79}', 7800), ('\u{1e7b}', 7802), + ('\u{1e7d}', 7804), ('\u{1e7f}', 7806), ('\u{1e81}', 7808), ('\u{1e83}', 7810), + ('\u{1e85}', 7812), ('\u{1e87}', 7814), ('\u{1e89}', 7816), ('\u{1e8b}', 7818), + ('\u{1e8d}', 7820), ('\u{1e8f}', 7822), ('\u{1e91}', 7824), ('\u{1e93}', 7826), + ('\u{1e95}', 7828), ('\u{1e96}', 4194310), ('\u{1e97}', 4194311), ('\u{1e98}', 4194312), + ('\u{1e99}', 4194313), ('\u{1e9a}', 4194314), ('\u{1e9b}', 7776), ('\u{1ea1}', 7840), + ('\u{1ea3}', 7842), ('\u{1ea5}', 7844), ('\u{1ea7}', 7846), ('\u{1ea9}', 7848), + ('\u{1eab}', 7850), ('\u{1ead}', 7852), ('\u{1eaf}', 7854), ('\u{1eb1}', 7856), + ('\u{1eb3}', 7858), ('\u{1eb5}', 7860), ('\u{1eb7}', 7862), ('\u{1eb9}', 7864), + ('\u{1ebb}', 7866), ('\u{1ebd}', 7868), ('\u{1ebf}', 7870), ('\u{1ec1}', 7872), + ('\u{1ec3}', 7874), ('\u{1ec5}', 7876), ('\u{1ec7}', 7878), ('\u{1ec9}', 7880), + ('\u{1ecb}', 7882), ('\u{1ecd}', 7884), ('\u{1ecf}', 7886), ('\u{1ed1}', 7888), + ('\u{1ed3}', 7890), ('\u{1ed5}', 7892), ('\u{1ed7}', 7894), ('\u{1ed9}', 7896), + ('\u{1edb}', 7898), ('\u{1edd}', 7900), ('\u{1edf}', 7902), ('\u{1ee1}', 7904), + ('\u{1ee3}', 7906), ('\u{1ee5}', 7908), ('\u{1ee7}', 7910), ('\u{1ee9}', 7912), + ('\u{1eeb}', 7914), ('\u{1eed}', 7916), ('\u{1eef}', 7918), ('\u{1ef1}', 7920), + ('\u{1ef3}', 7922), ('\u{1ef5}', 7924), ('\u{1ef7}', 7926), ('\u{1ef9}', 7928), + ('\u{1efb}', 7930), ('\u{1efd}', 7932), ('\u{1eff}', 7934), ('\u{1f00}', 7944), + ('\u{1f01}', 7945), ('\u{1f02}', 7946), ('\u{1f03}', 7947), ('\u{1f04}', 7948), + ('\u{1f05}', 7949), ('\u{1f06}', 7950), ('\u{1f07}', 7951), ('\u{1f10}', 7960), + ('\u{1f11}', 7961), ('\u{1f12}', 7962), ('\u{1f13}', 7963), ('\u{1f14}', 7964), + ('\u{1f15}', 7965), ('\u{1f20}', 7976), ('\u{1f21}', 7977), ('\u{1f22}', 7978), + ('\u{1f23}', 7979), ('\u{1f24}', 7980), ('\u{1f25}', 7981), ('\u{1f26}', 7982), + ('\u{1f27}', 7983), ('\u{1f30}', 7992), ('\u{1f31}', 7993), ('\u{1f32}', 7994), + ('\u{1f33}', 7995), ('\u{1f34}', 7996), ('\u{1f35}', 7997), ('\u{1f36}', 7998), + ('\u{1f37}', 7999), ('\u{1f40}', 8008), ('\u{1f41}', 8009), ('\u{1f42}', 8010), + ('\u{1f43}', 8011), ('\u{1f44}', 8012), ('\u{1f45}', 8013), ('\u{1f50}', 4194315), + ('\u{1f51}', 8025), ('\u{1f52}', 4194316), ('\u{1f53}', 8027), ('\u{1f54}', 4194317), + ('\u{1f55}', 8029), ('\u{1f56}', 4194318), ('\u{1f57}', 8031), ('\u{1f60}', 8040), + ('\u{1f61}', 8041), ('\u{1f62}', 8042), ('\u{1f63}', 8043), ('\u{1f64}', 8044), + ('\u{1f65}', 8045), ('\u{1f66}', 8046), ('\u{1f67}', 8047), ('\u{1f70}', 8122), + ('\u{1f71}', 8123), ('\u{1f72}', 8136), ('\u{1f73}', 8137), ('\u{1f74}', 8138), + ('\u{1f75}', 8139), ('\u{1f76}', 8154), ('\u{1f77}', 8155), ('\u{1f78}', 8184), + ('\u{1f79}', 8185), ('\u{1f7a}', 8170), ('\u{1f7b}', 8171), ('\u{1f7c}', 8186), + ('\u{1f7d}', 8187), ('\u{1f80}', 4194319), ('\u{1f81}', 4194320), ('\u{1f82}', 4194321), + ('\u{1f83}', 4194322), ('\u{1f84}', 4194323), ('\u{1f85}', 4194324), ('\u{1f86}', 4194325), + ('\u{1f87}', 4194326), ('\u{1f88}', 4194327), ('\u{1f89}', 4194328), ('\u{1f8a}', 4194329), + ('\u{1f8b}', 4194330), ('\u{1f8c}', 4194331), ('\u{1f8d}', 4194332), ('\u{1f8e}', 4194333), + ('\u{1f8f}', 4194334), ('\u{1f90}', 4194335), ('\u{1f91}', 4194336), ('\u{1f92}', 4194337), + ('\u{1f93}', 4194338), ('\u{1f94}', 4194339), ('\u{1f95}', 4194340), ('\u{1f96}', 4194341), + ('\u{1f97}', 4194342), ('\u{1f98}', 4194343), ('\u{1f99}', 4194344), ('\u{1f9a}', 4194345), + ('\u{1f9b}', 4194346), ('\u{1f9c}', 4194347), ('\u{1f9d}', 4194348), ('\u{1f9e}', 4194349), + ('\u{1f9f}', 4194350), ('\u{1fa0}', 4194351), ('\u{1fa1}', 4194352), ('\u{1fa2}', 4194353), + ('\u{1fa3}', 4194354), ('\u{1fa4}', 4194355), ('\u{1fa5}', 4194356), ('\u{1fa6}', 4194357), + ('\u{1fa7}', 4194358), ('\u{1fa8}', 4194359), ('\u{1fa9}', 4194360), ('\u{1faa}', 4194361), + ('\u{1fab}', 4194362), ('\u{1fac}', 4194363), ('\u{1fad}', 4194364), ('\u{1fae}', 4194365), + ('\u{1faf}', 4194366), ('\u{1fb0}', 8120), ('\u{1fb1}', 8121), ('\u{1fb2}', 4194367), + ('\u{1fb3}', 4194368), ('\u{1fb4}', 4194369), ('\u{1fb6}', 4194370), ('\u{1fb7}', 4194371), + ('\u{1fbc}', 4194372), ('\u{1fbe}', 921), ('\u{1fc2}', 4194373), ('\u{1fc3}', 4194374), + ('\u{1fc4}', 4194375), ('\u{1fc6}', 4194376), ('\u{1fc7}', 4194377), ('\u{1fcc}', 4194378), + ('\u{1fd0}', 8152), ('\u{1fd1}', 8153), ('\u{1fd2}', 4194379), ('\u{1fd3}', 4194380), + ('\u{1fd6}', 4194381), ('\u{1fd7}', 4194382), ('\u{1fe0}', 8168), ('\u{1fe1}', 8169), + ('\u{1fe2}', 4194383), ('\u{1fe3}', 4194384), ('\u{1fe4}', 4194385), ('\u{1fe5}', 8172), + ('\u{1fe6}', 4194386), ('\u{1fe7}', 4194387), ('\u{1ff2}', 4194388), ('\u{1ff3}', 4194389), + ('\u{1ff4}', 4194390), ('\u{1ff6}', 4194391), ('\u{1ff7}', 4194392), ('\u{1ffc}', 4194393), + ('\u{214e}', 8498), ('\u{2170}', 8544), ('\u{2171}', 8545), ('\u{2172}', 8546), + ('\u{2173}', 8547), ('\u{2174}', 8548), ('\u{2175}', 8549), ('\u{2176}', 8550), + ('\u{2177}', 8551), ('\u{2178}', 8552), ('\u{2179}', 8553), ('\u{217a}', 8554), + ('\u{217b}', 8555), ('\u{217c}', 8556), ('\u{217d}', 8557), ('\u{217e}', 8558), + ('\u{217f}', 8559), ('\u{2184}', 8579), ('\u{24d0}', 9398), ('\u{24d1}', 9399), + ('\u{24d2}', 9400), ('\u{24d3}', 9401), ('\u{24d4}', 9402), ('\u{24d5}', 9403), + ('\u{24d6}', 9404), ('\u{24d7}', 9405), ('\u{24d8}', 9406), ('\u{24d9}', 9407), + ('\u{24da}', 9408), ('\u{24db}', 9409), ('\u{24dc}', 9410), ('\u{24dd}', 9411), + ('\u{24de}', 9412), ('\u{24df}', 9413), ('\u{24e0}', 9414), ('\u{24e1}', 9415), + ('\u{24e2}', 9416), ('\u{24e3}', 9417), ('\u{24e4}', 9418), ('\u{24e5}', 9419), + ('\u{24e6}', 9420), ('\u{24e7}', 9421), ('\u{24e8}', 9422), ('\u{24e9}', 9423), + ('\u{2c30}', 11264), ('\u{2c31}', 11265), ('\u{2c32}', 11266), ('\u{2c33}', 11267), + ('\u{2c34}', 11268), ('\u{2c35}', 11269), ('\u{2c36}', 11270), ('\u{2c37}', 11271), + ('\u{2c38}', 11272), ('\u{2c39}', 11273), ('\u{2c3a}', 11274), ('\u{2c3b}', 11275), + ('\u{2c3c}', 11276), ('\u{2c3d}', 11277), ('\u{2c3e}', 11278), ('\u{2c3f}', 11279), + ('\u{2c40}', 11280), ('\u{2c41}', 11281), ('\u{2c42}', 11282), ('\u{2c43}', 11283), + ('\u{2c44}', 11284), ('\u{2c45}', 11285), ('\u{2c46}', 11286), ('\u{2c47}', 11287), + ('\u{2c48}', 11288), ('\u{2c49}', 11289), ('\u{2c4a}', 11290), ('\u{2c4b}', 11291), + ('\u{2c4c}', 11292), ('\u{2c4d}', 11293), ('\u{2c4e}', 11294), ('\u{2c4f}', 11295), + ('\u{2c50}', 11296), ('\u{2c51}', 11297), ('\u{2c52}', 11298), ('\u{2c53}', 11299), + ('\u{2c54}', 11300), ('\u{2c55}', 11301), ('\u{2c56}', 11302), ('\u{2c57}', 11303), + ('\u{2c58}', 11304), ('\u{2c59}', 11305), ('\u{2c5a}', 11306), ('\u{2c5b}', 11307), + ('\u{2c5c}', 11308), ('\u{2c5d}', 11309), ('\u{2c5e}', 11310), ('\u{2c5f}', 11311), + ('\u{2c61}', 11360), ('\u{2c65}', 570), ('\u{2c66}', 574), ('\u{2c68}', 11367), + ('\u{2c6a}', 11369), ('\u{2c6c}', 11371), ('\u{2c73}', 11378), ('\u{2c76}', 11381), + ('\u{2c81}', 11392), ('\u{2c83}', 11394), ('\u{2c85}', 11396), ('\u{2c87}', 11398), + ('\u{2c89}', 11400), ('\u{2c8b}', 11402), ('\u{2c8d}', 11404), ('\u{2c8f}', 11406), + ('\u{2c91}', 11408), ('\u{2c93}', 11410), ('\u{2c95}', 11412), ('\u{2c97}', 11414), + ('\u{2c99}', 11416), ('\u{2c9b}', 11418), ('\u{2c9d}', 11420), ('\u{2c9f}', 11422), + ('\u{2ca1}', 11424), ('\u{2ca3}', 11426), ('\u{2ca5}', 11428), ('\u{2ca7}', 11430), + ('\u{2ca9}', 11432), ('\u{2cab}', 11434), ('\u{2cad}', 11436), ('\u{2caf}', 11438), + ('\u{2cb1}', 11440), ('\u{2cb3}', 11442), ('\u{2cb5}', 11444), ('\u{2cb7}', 11446), + ('\u{2cb9}', 11448), ('\u{2cbb}', 11450), ('\u{2cbd}', 11452), ('\u{2cbf}', 11454), + ('\u{2cc1}', 11456), ('\u{2cc3}', 11458), ('\u{2cc5}', 11460), ('\u{2cc7}', 11462), + ('\u{2cc9}', 11464), ('\u{2ccb}', 11466), ('\u{2ccd}', 11468), ('\u{2ccf}', 11470), + ('\u{2cd1}', 11472), ('\u{2cd3}', 11474), ('\u{2cd5}', 11476), ('\u{2cd7}', 11478), + ('\u{2cd9}', 11480), ('\u{2cdb}', 11482), ('\u{2cdd}', 11484), ('\u{2cdf}', 11486), + ('\u{2ce1}', 11488), ('\u{2ce3}', 11490), ('\u{2cec}', 11499), ('\u{2cee}', 11501), + ('\u{2cf3}', 11506), ('\u{2d00}', 4256), ('\u{2d01}', 4257), ('\u{2d02}', 4258), + ('\u{2d03}', 4259), ('\u{2d04}', 4260), ('\u{2d05}', 4261), ('\u{2d06}', 4262), + ('\u{2d07}', 4263), ('\u{2d08}', 4264), ('\u{2d09}', 4265), ('\u{2d0a}', 4266), + ('\u{2d0b}', 4267), ('\u{2d0c}', 4268), ('\u{2d0d}', 4269), ('\u{2d0e}', 4270), + ('\u{2d0f}', 4271), ('\u{2d10}', 4272), ('\u{2d11}', 4273), ('\u{2d12}', 4274), + ('\u{2d13}', 4275), ('\u{2d14}', 4276), ('\u{2d15}', 4277), ('\u{2d16}', 4278), + ('\u{2d17}', 4279), ('\u{2d18}', 4280), ('\u{2d19}', 4281), ('\u{2d1a}', 4282), + ('\u{2d1b}', 4283), ('\u{2d1c}', 4284), ('\u{2d1d}', 4285), ('\u{2d1e}', 4286), + ('\u{2d1f}', 4287), ('\u{2d20}', 4288), ('\u{2d21}', 4289), ('\u{2d22}', 4290), + ('\u{2d23}', 4291), ('\u{2d24}', 4292), ('\u{2d25}', 4293), ('\u{2d27}', 4295), + ('\u{2d2d}', 4301), ('\u{a641}', 42560), ('\u{a643}', 42562), ('\u{a645}', 42564), + ('\u{a647}', 42566), ('\u{a649}', 42568), ('\u{a64b}', 42570), ('\u{a64d}', 42572), + ('\u{a64f}', 42574), ('\u{a651}', 42576), ('\u{a653}', 42578), ('\u{a655}', 42580), + ('\u{a657}', 42582), ('\u{a659}', 42584), ('\u{a65b}', 42586), ('\u{a65d}', 42588), + ('\u{a65f}', 42590), ('\u{a661}', 42592), ('\u{a663}', 42594), ('\u{a665}', 42596), + ('\u{a667}', 42598), ('\u{a669}', 42600), ('\u{a66b}', 42602), ('\u{a66d}', 42604), + ('\u{a681}', 42624), ('\u{a683}', 42626), ('\u{a685}', 42628), ('\u{a687}', 42630), + ('\u{a689}', 42632), ('\u{a68b}', 42634), ('\u{a68d}', 42636), ('\u{a68f}', 42638), + ('\u{a691}', 42640), ('\u{a693}', 42642), ('\u{a695}', 42644), ('\u{a697}', 42646), + ('\u{a699}', 42648), ('\u{a69b}', 42650), ('\u{a723}', 42786), ('\u{a725}', 42788), + ('\u{a727}', 42790), ('\u{a729}', 42792), ('\u{a72b}', 42794), ('\u{a72d}', 42796), + ('\u{a72f}', 42798), ('\u{a733}', 42802), ('\u{a735}', 42804), ('\u{a737}', 42806), + ('\u{a739}', 42808), ('\u{a73b}', 42810), ('\u{a73d}', 42812), ('\u{a73f}', 42814), + ('\u{a741}', 42816), ('\u{a743}', 42818), ('\u{a745}', 42820), ('\u{a747}', 42822), + ('\u{a749}', 42824), ('\u{a74b}', 42826), ('\u{a74d}', 42828), ('\u{a74f}', 42830), + ('\u{a751}', 42832), ('\u{a753}', 42834), ('\u{a755}', 42836), ('\u{a757}', 42838), + ('\u{a759}', 42840), ('\u{a75b}', 42842), ('\u{a75d}', 42844), ('\u{a75f}', 42846), + ('\u{a761}', 42848), ('\u{a763}', 42850), ('\u{a765}', 42852), ('\u{a767}', 42854), + ('\u{a769}', 42856), ('\u{a76b}', 42858), ('\u{a76d}', 42860), ('\u{a76f}', 42862), + ('\u{a77a}', 42873), ('\u{a77c}', 42875), ('\u{a77f}', 42878), ('\u{a781}', 42880), + ('\u{a783}', 42882), ('\u{a785}', 42884), ('\u{a787}', 42886), ('\u{a78c}', 42891), + ('\u{a791}', 42896), ('\u{a793}', 42898), ('\u{a794}', 42948), ('\u{a797}', 42902), + ('\u{a799}', 42904), ('\u{a79b}', 42906), ('\u{a79d}', 42908), ('\u{a79f}', 42910), + ('\u{a7a1}', 42912), ('\u{a7a3}', 42914), ('\u{a7a5}', 42916), ('\u{a7a7}', 42918), + ('\u{a7a9}', 42920), ('\u{a7b5}', 42932), ('\u{a7b7}', 42934), ('\u{a7b9}', 42936), + ('\u{a7bb}', 42938), ('\u{a7bd}', 42940), ('\u{a7bf}', 42942), ('\u{a7c1}', 42944), + ('\u{a7c3}', 42946), ('\u{a7c8}', 42951), ('\u{a7ca}', 42953), ('\u{a7d1}', 42960), + ('\u{a7d7}', 42966), ('\u{a7d9}', 42968), ('\u{a7f6}', 42997), ('\u{ab53}', 42931), + ('\u{ab70}', 5024), ('\u{ab71}', 5025), ('\u{ab72}', 5026), ('\u{ab73}', 5027), + ('\u{ab74}', 5028), ('\u{ab75}', 5029), ('\u{ab76}', 5030), ('\u{ab77}', 5031), + ('\u{ab78}', 5032), ('\u{ab79}', 5033), ('\u{ab7a}', 5034), ('\u{ab7b}', 5035), + ('\u{ab7c}', 5036), ('\u{ab7d}', 5037), ('\u{ab7e}', 5038), ('\u{ab7f}', 5039), + ('\u{ab80}', 5040), ('\u{ab81}', 5041), ('\u{ab82}', 5042), ('\u{ab83}', 5043), + ('\u{ab84}', 5044), ('\u{ab85}', 5045), ('\u{ab86}', 5046), ('\u{ab87}', 5047), + ('\u{ab88}', 5048), ('\u{ab89}', 5049), ('\u{ab8a}', 5050), ('\u{ab8b}', 5051), + ('\u{ab8c}', 5052), ('\u{ab8d}', 5053), ('\u{ab8e}', 5054), ('\u{ab8f}', 5055), + ('\u{ab90}', 5056), ('\u{ab91}', 5057), ('\u{ab92}', 5058), ('\u{ab93}', 5059), + ('\u{ab94}', 5060), ('\u{ab95}', 5061), ('\u{ab96}', 5062), ('\u{ab97}', 5063), + ('\u{ab98}', 5064), ('\u{ab99}', 5065), ('\u{ab9a}', 5066), ('\u{ab9b}', 5067), + ('\u{ab9c}', 5068), ('\u{ab9d}', 5069), ('\u{ab9e}', 5070), ('\u{ab9f}', 5071), + ('\u{aba0}', 5072), ('\u{aba1}', 5073), ('\u{aba2}', 5074), ('\u{aba3}', 5075), + ('\u{aba4}', 5076), ('\u{aba5}', 5077), ('\u{aba6}', 5078), ('\u{aba7}', 5079), + ('\u{aba8}', 5080), ('\u{aba9}', 5081), ('\u{abaa}', 5082), ('\u{abab}', 5083), + ('\u{abac}', 5084), ('\u{abad}', 5085), ('\u{abae}', 5086), ('\u{abaf}', 5087), + ('\u{abb0}', 5088), ('\u{abb1}', 5089), ('\u{abb2}', 5090), ('\u{abb3}', 5091), + ('\u{abb4}', 5092), ('\u{abb5}', 5093), ('\u{abb6}', 5094), ('\u{abb7}', 5095), + ('\u{abb8}', 5096), ('\u{abb9}', 5097), ('\u{abba}', 5098), ('\u{abbb}', 5099), + ('\u{abbc}', 5100), ('\u{abbd}', 5101), ('\u{abbe}', 5102), ('\u{abbf}', 5103), + ('\u{fb00}', 4194394), ('\u{fb01}', 4194395), ('\u{fb02}', 4194396), ('\u{fb03}', 4194397), + ('\u{fb04}', 4194398), ('\u{fb05}', 4194399), ('\u{fb06}', 4194400), ('\u{fb13}', 4194401), + ('\u{fb14}', 4194402), ('\u{fb15}', 4194403), ('\u{fb16}', 4194404), ('\u{fb17}', 4194405), + ('\u{ff41}', 65313), ('\u{ff42}', 65314), ('\u{ff43}', 65315), ('\u{ff44}', 65316), + ('\u{ff45}', 65317), ('\u{ff46}', 65318), ('\u{ff47}', 65319), ('\u{ff48}', 65320), + ('\u{ff49}', 65321), ('\u{ff4a}', 65322), ('\u{ff4b}', 65323), ('\u{ff4c}', 65324), + ('\u{ff4d}', 65325), ('\u{ff4e}', 65326), ('\u{ff4f}', 65327), ('\u{ff50}', 65328), + ('\u{ff51}', 65329), ('\u{ff52}', 65330), ('\u{ff53}', 65331), ('\u{ff54}', 65332), + ('\u{ff55}', 65333), ('\u{ff56}', 65334), ('\u{ff57}', 65335), ('\u{ff58}', 65336), + ('\u{ff59}', 65337), ('\u{ff5a}', 65338), ('\u{10428}', 66560), ('\u{10429}', 66561), + ('\u{1042a}', 66562), ('\u{1042b}', 66563), ('\u{1042c}', 66564), ('\u{1042d}', 66565), + ('\u{1042e}', 66566), ('\u{1042f}', 66567), ('\u{10430}', 66568), ('\u{10431}', 66569), + ('\u{10432}', 66570), ('\u{10433}', 66571), ('\u{10434}', 66572), ('\u{10435}', 66573), + ('\u{10436}', 66574), ('\u{10437}', 66575), ('\u{10438}', 66576), ('\u{10439}', 66577), + ('\u{1043a}', 66578), ('\u{1043b}', 66579), ('\u{1043c}', 66580), ('\u{1043d}', 66581), + ('\u{1043e}', 66582), ('\u{1043f}', 66583), ('\u{10440}', 66584), ('\u{10441}', 66585), + ('\u{10442}', 66586), ('\u{10443}', 66587), ('\u{10444}', 66588), ('\u{10445}', 66589), + ('\u{10446}', 66590), ('\u{10447}', 66591), ('\u{10448}', 66592), ('\u{10449}', 66593), + ('\u{1044a}', 66594), ('\u{1044b}', 66595), ('\u{1044c}', 66596), ('\u{1044d}', 66597), + ('\u{1044e}', 66598), ('\u{1044f}', 66599), ('\u{104d8}', 66736), ('\u{104d9}', 66737), + ('\u{104da}', 66738), ('\u{104db}', 66739), ('\u{104dc}', 66740), ('\u{104dd}', 66741), + ('\u{104de}', 66742), ('\u{104df}', 66743), ('\u{104e0}', 66744), ('\u{104e1}', 66745), + ('\u{104e2}', 66746), ('\u{104e3}', 66747), ('\u{104e4}', 66748), ('\u{104e5}', 66749), + ('\u{104e6}', 66750), ('\u{104e7}', 66751), ('\u{104e8}', 66752), ('\u{104e9}', 66753), + ('\u{104ea}', 66754), ('\u{104eb}', 66755), ('\u{104ec}', 66756), ('\u{104ed}', 66757), + ('\u{104ee}', 66758), ('\u{104ef}', 66759), ('\u{104f0}', 66760), ('\u{104f1}', 66761), + ('\u{104f2}', 66762), ('\u{104f3}', 66763), ('\u{104f4}', 66764), ('\u{104f5}', 66765), + ('\u{104f6}', 66766), ('\u{104f7}', 66767), ('\u{104f8}', 66768), ('\u{104f9}', 66769), + ('\u{104fa}', 66770), ('\u{104fb}', 66771), ('\u{10597}', 66928), ('\u{10598}', 66929), + ('\u{10599}', 66930), ('\u{1059a}', 66931), ('\u{1059b}', 66932), ('\u{1059c}', 66933), + ('\u{1059d}', 66934), ('\u{1059e}', 66935), ('\u{1059f}', 66936), ('\u{105a0}', 66937), + ('\u{105a1}', 66938), ('\u{105a3}', 66940), ('\u{105a4}', 66941), ('\u{105a5}', 66942), + ('\u{105a6}', 66943), ('\u{105a7}', 66944), ('\u{105a8}', 66945), ('\u{105a9}', 66946), + ('\u{105aa}', 66947), ('\u{105ab}', 66948), ('\u{105ac}', 66949), ('\u{105ad}', 66950), + ('\u{105ae}', 66951), ('\u{105af}', 66952), ('\u{105b0}', 66953), ('\u{105b1}', 66954), + ('\u{105b3}', 66956), ('\u{105b4}', 66957), ('\u{105b5}', 66958), ('\u{105b6}', 66959), + ('\u{105b7}', 66960), ('\u{105b8}', 66961), ('\u{105b9}', 66962), ('\u{105bb}', 66964), + ('\u{105bc}', 66965), ('\u{10cc0}', 68736), ('\u{10cc1}', 68737), ('\u{10cc2}', 68738), + ('\u{10cc3}', 68739), ('\u{10cc4}', 68740), ('\u{10cc5}', 68741), ('\u{10cc6}', 68742), + ('\u{10cc7}', 68743), ('\u{10cc8}', 68744), ('\u{10cc9}', 68745), ('\u{10cca}', 68746), + ('\u{10ccb}', 68747), ('\u{10ccc}', 68748), ('\u{10ccd}', 68749), ('\u{10cce}', 68750), + ('\u{10ccf}', 68751), ('\u{10cd0}', 68752), ('\u{10cd1}', 68753), ('\u{10cd2}', 68754), + ('\u{10cd3}', 68755), ('\u{10cd4}', 68756), ('\u{10cd5}', 68757), ('\u{10cd6}', 68758), + ('\u{10cd7}', 68759), ('\u{10cd8}', 68760), ('\u{10cd9}', 68761), ('\u{10cda}', 68762), + ('\u{10cdb}', 68763), ('\u{10cdc}', 68764), ('\u{10cdd}', 68765), ('\u{10cde}', 68766), + ('\u{10cdf}', 68767), ('\u{10ce0}', 68768), ('\u{10ce1}', 68769), ('\u{10ce2}', 68770), + ('\u{10ce3}', 68771), ('\u{10ce4}', 68772), ('\u{10ce5}', 68773), ('\u{10ce6}', 68774), + ('\u{10ce7}', 68775), ('\u{10ce8}', 68776), ('\u{10ce9}', 68777), ('\u{10cea}', 68778), + ('\u{10ceb}', 68779), ('\u{10cec}', 68780), ('\u{10ced}', 68781), ('\u{10cee}', 68782), + ('\u{10cef}', 68783), ('\u{10cf0}', 68784), ('\u{10cf1}', 68785), ('\u{10cf2}', 68786), + ('\u{118c0}', 71840), ('\u{118c1}', 71841), ('\u{118c2}', 71842), ('\u{118c3}', 71843), + ('\u{118c4}', 71844), ('\u{118c5}', 71845), ('\u{118c6}', 71846), ('\u{118c7}', 71847), + ('\u{118c8}', 71848), ('\u{118c9}', 71849), ('\u{118ca}', 71850), ('\u{118cb}', 71851), + ('\u{118cc}', 71852), ('\u{118cd}', 71853), ('\u{118ce}', 71854), ('\u{118cf}', 71855), + ('\u{118d0}', 71856), ('\u{118d1}', 71857), ('\u{118d2}', 71858), ('\u{118d3}', 71859), + ('\u{118d4}', 71860), ('\u{118d5}', 71861), ('\u{118d6}', 71862), ('\u{118d7}', 71863), + ('\u{118d8}', 71864), ('\u{118d9}', 71865), ('\u{118da}', 71866), ('\u{118db}', 71867), + ('\u{118dc}', 71868), ('\u{118dd}', 71869), ('\u{118de}', 71870), ('\u{118df}', 71871), + ('\u{16e60}', 93760), ('\u{16e61}', 93761), ('\u{16e62}', 93762), ('\u{16e63}', 93763), + ('\u{16e64}', 93764), ('\u{16e65}', 93765), ('\u{16e66}', 93766), ('\u{16e67}', 93767), + ('\u{16e68}', 93768), ('\u{16e69}', 93769), ('\u{16e6a}', 93770), ('\u{16e6b}', 93771), + ('\u{16e6c}', 93772), ('\u{16e6d}', 93773), ('\u{16e6e}', 93774), ('\u{16e6f}', 93775), + ('\u{16e70}', 93776), ('\u{16e71}', 93777), ('\u{16e72}', 93778), ('\u{16e73}', 93779), + ('\u{16e74}', 93780), ('\u{16e75}', 93781), ('\u{16e76}', 93782), ('\u{16e77}', 93783), + ('\u{16e78}', 93784), ('\u{16e79}', 93785), ('\u{16e7a}', 93786), ('\u{16e7b}', 93787), + ('\u{16e7c}', 93788), ('\u{16e7d}', 93789), ('\u{16e7e}', 93790), ('\u{16e7f}', 93791), + ('\u{1e922}', 125184), ('\u{1e923}', 125185), ('\u{1e924}', 125186), ('\u{1e925}', 125187), + ('\u{1e926}', 125188), ('\u{1e927}', 125189), ('\u{1e928}', 125190), ('\u{1e929}', 125191), + ('\u{1e92a}', 125192), ('\u{1e92b}', 125193), ('\u{1e92c}', 125194), ('\u{1e92d}', 125195), + ('\u{1e92e}', 125196), ('\u{1e92f}', 125197), ('\u{1e930}', 125198), ('\u{1e931}', 125199), + ('\u{1e932}', 125200), ('\u{1e933}', 125201), ('\u{1e934}', 125202), ('\u{1e935}', 125203), + ('\u{1e936}', 125204), ('\u{1e937}', 125205), ('\u{1e938}', 125206), ('\u{1e939}', 125207), + ('\u{1e93a}', 125208), ('\u{1e93b}', 125209), ('\u{1e93c}', 125210), ('\u{1e93d}', 125211), + ('\u{1e93e}', 125212), ('\u{1e93f}', 125213), ('\u{1e940}', 125214), ('\u{1e941}', 125215), + ('\u{1e942}', 125216), ('\u{1e943}', 125217), ]; - static UPPERCASE_TABLE_MULTI: &[(char, [char; 3])] = &[ - ('\u{df}', ['S', 'S', '\u{0}']), ('\u{149}', ['\u{2bc}', 'N', '\u{0}']), - ('\u{1f0}', ['J', '\u{30c}', '\u{0}']), ('\u{390}', ['\u{399}', '\u{308}', '\u{301}']), - ('\u{3b0}', ['\u{3a5}', '\u{308}', '\u{301}']), - ('\u{587}', ['\u{535}', '\u{552}', '\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{1f50}', ['\u{3a5}', '\u{313}', '\u{0}']), - ('\u{1f52}', ['\u{3a5}', '\u{313}', '\u{300}']), - ('\u{1f54}', ['\u{3a5}', '\u{313}', '\u{301}']), - ('\u{1f56}', ['\u{3a5}', '\u{313}', '\u{342}']), - ('\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{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{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{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{1fe2}', ['\u{3a5}', '\u{308}', '\u{300}']), - ('\u{1fe3}', ['\u{3a5}', '\u{308}', '\u{301}']), - ('\u{1fe4}', ['\u{3a1}', '\u{313}', '\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{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}']), + static UPPERCASE_TABLE_MULTI: &[[char; 3]] = &[ + ['S', 'S', '\u{0}'], ['\u{2bc}', 'N', '\u{0}'], ['J', '\u{30c}', '\u{0}'], + ['\u{399}', '\u{308}', '\u{301}'], ['\u{3a5}', '\u{308}', '\u{301}'], + ['\u{535}', '\u{552}', '\u{0}'], ['H', '\u{331}', '\u{0}'], ['T', '\u{308}', '\u{0}'], + ['W', '\u{30a}', '\u{0}'], ['Y', '\u{30a}', '\u{0}'], ['A', '\u{2be}', '\u{0}'], + ['\u{3a5}', '\u{313}', '\u{0}'], ['\u{3a5}', '\u{313}', '\u{300}'], + ['\u{3a5}', '\u{313}', '\u{301}'], ['\u{3a5}', '\u{313}', '\u{342}'], + ['\u{1f08}', '\u{399}', '\u{0}'], ['\u{1f09}', '\u{399}', '\u{0}'], + ['\u{1f0a}', '\u{399}', '\u{0}'], ['\u{1f0b}', '\u{399}', '\u{0}'], + ['\u{1f0c}', '\u{399}', '\u{0}'], ['\u{1f0d}', '\u{399}', '\u{0}'], + ['\u{1f0e}', '\u{399}', '\u{0}'], ['\u{1f0f}', '\u{399}', '\u{0}'], + ['\u{1f08}', '\u{399}', '\u{0}'], ['\u{1f09}', '\u{399}', '\u{0}'], + ['\u{1f0a}', '\u{399}', '\u{0}'], ['\u{1f0b}', '\u{399}', '\u{0}'], + ['\u{1f0c}', '\u{399}', '\u{0}'], ['\u{1f0d}', '\u{399}', '\u{0}'], + ['\u{1f0e}', '\u{399}', '\u{0}'], ['\u{1f0f}', '\u{399}', '\u{0}'], + ['\u{1f28}', '\u{399}', '\u{0}'], ['\u{1f29}', '\u{399}', '\u{0}'], + ['\u{1f2a}', '\u{399}', '\u{0}'], ['\u{1f2b}', '\u{399}', '\u{0}'], + ['\u{1f2c}', '\u{399}', '\u{0}'], ['\u{1f2d}', '\u{399}', '\u{0}'], + ['\u{1f2e}', '\u{399}', '\u{0}'], ['\u{1f2f}', '\u{399}', '\u{0}'], + ['\u{1f28}', '\u{399}', '\u{0}'], ['\u{1f29}', '\u{399}', '\u{0}'], + ['\u{1f2a}', '\u{399}', '\u{0}'], ['\u{1f2b}', '\u{399}', '\u{0}'], + ['\u{1f2c}', '\u{399}', '\u{0}'], ['\u{1f2d}', '\u{399}', '\u{0}'], + ['\u{1f2e}', '\u{399}', '\u{0}'], ['\u{1f2f}', '\u{399}', '\u{0}'], + ['\u{1f68}', '\u{399}', '\u{0}'], ['\u{1f69}', '\u{399}', '\u{0}'], + ['\u{1f6a}', '\u{399}', '\u{0}'], ['\u{1f6b}', '\u{399}', '\u{0}'], + ['\u{1f6c}', '\u{399}', '\u{0}'], ['\u{1f6d}', '\u{399}', '\u{0}'], + ['\u{1f6e}', '\u{399}', '\u{0}'], ['\u{1f6f}', '\u{399}', '\u{0}'], + ['\u{1f68}', '\u{399}', '\u{0}'], ['\u{1f69}', '\u{399}', '\u{0}'], + ['\u{1f6a}', '\u{399}', '\u{0}'], ['\u{1f6b}', '\u{399}', '\u{0}'], + ['\u{1f6c}', '\u{399}', '\u{0}'], ['\u{1f6d}', '\u{399}', '\u{0}'], + ['\u{1f6e}', '\u{399}', '\u{0}'], ['\u{1f6f}', '\u{399}', '\u{0}'], + ['\u{1fba}', '\u{399}', '\u{0}'], ['\u{391}', '\u{399}', '\u{0}'], + ['\u{386}', '\u{399}', '\u{0}'], ['\u{391}', '\u{342}', '\u{0}'], + ['\u{391}', '\u{342}', '\u{399}'], ['\u{391}', '\u{399}', '\u{0}'], + ['\u{1fca}', '\u{399}', '\u{0}'], ['\u{397}', '\u{399}', '\u{0}'], + ['\u{389}', '\u{399}', '\u{0}'], ['\u{397}', '\u{342}', '\u{0}'], + ['\u{397}', '\u{342}', '\u{399}'], ['\u{397}', '\u{399}', '\u{0}'], + ['\u{399}', '\u{308}', '\u{300}'], ['\u{399}', '\u{308}', '\u{301}'], + ['\u{399}', '\u{342}', '\u{0}'], ['\u{399}', '\u{308}', '\u{342}'], + ['\u{3a5}', '\u{308}', '\u{300}'], ['\u{3a5}', '\u{308}', '\u{301}'], + ['\u{3a1}', '\u{313}', '\u{0}'], ['\u{3a5}', '\u{342}', '\u{0}'], + ['\u{3a5}', '\u{308}', '\u{342}'], ['\u{1ffa}', '\u{399}', '\u{0}'], + ['\u{3a9}', '\u{399}', '\u{0}'], ['\u{38f}', '\u{399}', '\u{0}'], + ['\u{3a9}', '\u{342}', '\u{0}'], ['\u{3a9}', '\u{342}', '\u{399}'], + ['\u{3a9}', '\u{399}', '\u{0}'], ['F', 'F', '\u{0}'], ['F', 'I', '\u{0}'], + ['F', 'L', '\u{0}'], ['F', 'F', 'I'], ['F', 'F', 'L'], ['S', 'T', '\u{0}'], + ['S', 'T', '\u{0}'], ['\u{544}', '\u{546}', '\u{0}'], ['\u{544}', '\u{535}', '\u{0}'], + ['\u{544}', '\u{53b}', '\u{0}'], ['\u{54e}', '\u{546}', '\u{0}'], + ['\u{544}', '\u{53d}', '\u{0}'], ]; } diff --git a/src/tools/unicode-table-generator/src/case_mapping.rs b/src/tools/unicode-table-generator/src/case_mapping.rs index 23ad93925ba..58d9959ca7b 100644 --- a/src/tools/unicode-table-generator/src/case_mapping.rs +++ b/src/tools/unicode-table-generator/src/case_mapping.rs @@ -1,13 +1,19 @@ use crate::{fmt_list, UnicodeData}; use std::{ + char, collections::BTreeMap, fmt::{self, Write}, }; +const INDEX_MASK: u32 = 1 << 22; + pub(crate) fn generate_case_mapping(data: &UnicodeData) -> String { let mut file = String::new(); + write!(file, "const INDEX_MASK: u32 = {};", INDEX_MASK).unwrap(); + file.push_str("\n\n"); file.push_str(HEADER.trim_start()); + file.push('\n'); file.push_str(&generate_tables("LOWER", &data.to_lower)); file.push_str("\n\n"); file.push_str(&generate_tables("UPPER", &data.to_upper)); @@ -15,46 +21,44 @@ pub(crate) fn generate_case_mapping(data: &UnicodeData) -> String { } fn generate_tables(case: &str, data: &BTreeMap) -> String { - let (single, multi): (Vec<_>, Vec<_>) = data - .iter() - .map(to_mapping) - .filter(|(k, _)| !k.0.is_ascii()) - .partition(|(_, [_, s, t])| s.0 == '\0' && t.0 == '\0'); + let mut mappings = Vec::with_capacity(data.len()); + let mut multis = Vec::new(); + + for (&key, &(a, b, c)) in data.iter() { + let key = char::from_u32(key).unwrap(); + + if key.is_ascii() { + continue; + } + + let value = if b == 0 && c == 0 { + a + } else { + multis.push([ + CharEscape(char::from_u32(a).unwrap()), + CharEscape(char::from_u32(b).unwrap()), + CharEscape(char::from_u32(c).unwrap()), + ]); + + INDEX_MASK | (u32::try_from(multis.len()).unwrap() - 1) + }; + + mappings.push((CharEscape(key), value)); + } let mut tables = String::new(); - write!( - tables, - "static {}CASE_TABLE_SINGLE: &[(char, char)] = &[{}];", - case, - fmt_list(single.into_iter().map(|(k, [v, _, _])| (k, v))) - ) - .unwrap(); + write!(tables, "static {}CASE_TABLE: &[(char, u32)] = &[{}];", case, fmt_list(mappings)) + .unwrap(); tables.push_str("\n\n"); - write!( - tables, - "static {}CASE_TABLE_MULTI: &[(char, [char; 3])] = &[{}];", - case, - fmt_list(multi) - ) - .unwrap(); + write!(tables, "static {}CASE_TABLE_MULTI: &[[char; 3]] = &[{}];", case, fmt_list(multis)) + .unwrap(); tables } -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 { @@ -68,10 +72,16 @@ pub fn to_lower(c: char) -> [char; 3] { if c.is_ascii() { [(c as u8).to_ascii_lowercase() as char, '\0', '\0'] } else { - match bsearch_case_tables(c, LOWERCASE_TABLE_SINGLE, LOWERCASE_TABLE_MULTI) { - Some(replacement) => replacement, - None => [c, '\0', '\0'], - } + LOWERCASE_TABLE + .binary_search_by(|&(key, _)| key.cmp(&c)) + .map(|i| { + let u = LOWERCASE_TABLE[i].1; + char::from_u32(u).map(|c| [c, '\0', '\0']).unwrap_or_else(|| { + // SAFETY: Index comes from statically generated table + unsafe { *LOWERCASE_TABLE_MULTI.get_unchecked((u & (INDEX_MASK - 1)) as usize) } + }) + }) + .unwrap_or([c, '\0', '\0']) } } @@ -79,21 +89,16 @@ pub fn to_upper(c: char) -> [char; 3] { if c.is_ascii() { [(c as u8).to_ascii_uppercase() as char, '\0', '\0'] } else { - match bsearch_case_tables(c, UPPERCASE_TABLE_SINGLE, UPPERCASE_TABLE_MULTI) { - Some(replacement) => replacement, - None => [c, '\0', '\0'], - } - } -} - -fn bsearch_case_tables( - c: char, - single: &[(char, char)], - multi: &[(char, [char; 3])], -) -> Option<[char; 3]> { - match single.binary_search_by(|&(key, _)| key.cmp(&c)) { - Ok(i) => Some([single[i].1, '\0', '\0']), - Err(_) => multi.binary_search_by(|&(key, _)| key.cmp(&c)).map(|i| multi[i].1).ok(), + UPPERCASE_TABLE + .binary_search_by(|&(key, _)| key.cmp(&c)) + .map(|i| { + let u = UPPERCASE_TABLE[i].1; + char::from_u32(u).map(|c| [c, '\0', '\0']).unwrap_or_else(|| { + // SAFETY: Index comes from statically generated table + unsafe { *UPPERCASE_TABLE_MULTI.get_unchecked((u & (INDEX_MASK - 1)) as usize) } + }) + }) + .unwrap_or([c, '\0', '\0']) } } "; From ce2d52841b30616b3258685439ab13b03520ae10 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Fri, 17 Mar 2023 12:26:04 +0000 Subject: [PATCH 060/346] Drop subslices of arrays --- .../rustc_mir_dataflow/src/elaborate_drops.rs | 72 ++++++++++++++----- tests/ui/mir/issue-109004-drop-large-array.rs | 16 +++++ 2 files changed, 70 insertions(+), 18 deletions(-) create mode 100644 tests/ui/mir/issue-109004-drop-large-array.rs diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index 486275570bd..be6eab107a4 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -729,23 +729,59 @@ where let tcx = self.tcx(); if let Some(size) = opt_size { - let fields: Vec<(Place<'tcx>, Option)> = (0..size) - .map(|i| { - ( - tcx.mk_place_elem( - self.place, - ProjectionElem::ConstantIndex { - offset: i, - min_length: size, - from_end: false, - }, - ), - self.elaborator.array_subpath(self.path, i, size), - ) - }) - .collect(); - - if fields.iter().any(|(_, path)| path.is_some()) { + enum ProjectionKind { + Drop(std::ops::Range), + Keep(u64, Path), + } + // Previously, we'd make a projection for every element in the array and create a drop + // ladder if any `array_subpath` was `Some`, i.e. moving out with an array pattern. + // This caused huge memory usage when generating the drops for large arrays, so we instead + // record the *subslices* which are dropped and the *indexes* which are kept + let mut drop_ranges = vec![]; + let mut dropping = true; + let mut start = 0; + for i in 0..size { + let path = self.elaborator.array_subpath(self.path, i, size); + if dropping && path.is_some() { + drop_ranges.push(ProjectionKind::Drop(start..i)); + dropping = false; + } else if !dropping && path.is_none() { + dropping = true; + start = i; + } + if let Some(path) = path { + drop_ranges.push(ProjectionKind::Keep(i, path)); + } + } + if !drop_ranges.is_empty() { + if dropping { + drop_ranges.push(ProjectionKind::Drop(start..size)); + } + let fields = drop_ranges + .iter() + .rev() + .map(|p| { + let (project, path) = match p { + ProjectionKind::Drop(r) => ( + ProjectionElem::Subslice { + from: r.start, + to: r.end, + from_end: false, + }, + None, + ), + &ProjectionKind::Keep(offset, path) => ( + ProjectionElem::ConstantIndex { + offset, + min_length: size, + from_end: false, + }, + Some(path), + ), + }; + (tcx.mk_place_elem(self.place, project), path) + }) + .collect::>(); let (succ, unwind) = self.drop_ladder_bottom(); return self.drop_ladder(fields, succ, unwind).0; } @@ -824,7 +860,7 @@ where let size = size.try_eval_target_usize(self.tcx(), self.elaborator.param_env()); self.open_drop_for_array(*ety, size) } - ty::Slice(ety) => self.open_drop_for_array(*ety, None), + ty::Slice(ety) => self.drop_loop_pair(*ety), _ => span_bug!(self.source_info.span, "open drop from non-ADT `{:?}`", ty), } diff --git a/tests/ui/mir/issue-109004-drop-large-array.rs b/tests/ui/mir/issue-109004-drop-large-array.rs new file mode 100644 index 00000000000..5e3361cef6e --- /dev/null +++ b/tests/ui/mir/issue-109004-drop-large-array.rs @@ -0,0 +1,16 @@ +// check-pass + +const SZ: usize = 64_000_000; +type BigDrop = [String; SZ]; + +fn f(_dropme: BigDrop) {} + +fn f2(_moveme: BigDrop) -> String { + let [a, ..] = _moveme; + a +} + +fn main() { + f(std::array::from_fn(|_| String::new())); + f2(std::array::from_fn(|_| String::new())); +} From 41eda69516dd3ee217ae07c0efa369d31f630405 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Fri, 24 Feb 2023 16:32:10 -0500 Subject: [PATCH 061/346] Remove duplicate unreachable blocks --- compiler/rustc_mir_transform/src/simplify.rs | 44 ++++++++++++++++++- ...await.b-{closure#0}.generator_resume.0.mir | 38 +++++++--------- ...witch.too_complex.SeparateConstSwitch.diff | 12 ++--- ...yCfg-after-uninhabited-enum-branching.diff | 25 +++++++++++ .../simplify_duplicate_unreachable_blocks.rs | 30 +++++++++++++ .../try_identity_e2e.new.PreCodegen.after.mir | 22 +++++----- ...after-uninhabited-enum-branching.after.mir | 12 ++--- ...anching.main.UninhabitedEnumBranching.diff | 12 ++--- ...after-uninhabited-enum-branching.after.mir | 12 ++--- ...nching2.main.UninhabitedEnumBranching.diff | 22 ++++------ 10 files changed, 151 insertions(+), 78 deletions(-) create mode 100644 tests/mir-opt/simplify_duplicate_unreachable_blocks.assert_nonzero_nonmax.SimplifyCfg-after-uninhabited-enum-branching.diff create mode 100644 tests/mir-opt/simplify_duplicate_unreachable_blocks.rs diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs index 929d229dcdf..c8474a455b5 100644 --- a/compiler/rustc_mir_transform/src/simplify.rs +++ b/compiler/rustc_mir_transform/src/simplify.rs @@ -28,7 +28,7 @@ //! return. use crate::MirPass; -use rustc_data_structures::fx::FxHashSet; +use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_index::vec::{Idx, IndexVec}; use rustc_middle::mir::coverage::*; use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor}; @@ -48,6 +48,7 @@ impl SimplifyCfg { pub fn simplify_cfg<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { CfgSimplifier::new(body).simplify(); + remove_duplicate_unreachable_blocks(tcx, body); remove_dead_blocks(tcx, body); // FIXME: Should probably be moved into some kind of pass manager @@ -259,6 +260,47 @@ impl<'a, 'tcx> CfgSimplifier<'a, 'tcx> { } } +pub fn remove_duplicate_unreachable_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + struct OptApplier<'tcx> { + tcx: TyCtxt<'tcx>, + duplicates: FxIndexSet, + } + + impl<'tcx> MutVisitor<'tcx> for OptApplier<'tcx> { + fn tcx(&self) -> TyCtxt<'tcx> { + self.tcx + } + + fn visit_terminator(&mut self, terminator: &mut Terminator<'tcx>, location: Location) { + for target in terminator.successors_mut() { + if self.duplicates.contains(target) { + *target = self.duplicates[0]; + } + } + + self.super_terminator(terminator, location); + } + } + + let unreachable_blocks = body + .basic_blocks + .iter_enumerated() + .filter(|(_, bb)| { + // CfgSimplifier::simplify leaves behind some unreachable basic blocks without a + // terminator. Those blocks will be deleted by remove_dead_blocks, but we run just + // before then so we need to handle missing terminators. + // We also need to prevent confusing cleanup and non-cleanup blocks. In practice we + // don't emit empty unreachable cleanup blocks, so this simple check suffices. + bb.terminator.is_some() && bb.is_empty_unreachable() && !bb.is_cleanup + }) + .map(|(block, _)| block) + .collect::>(); + + if unreachable_blocks.len() > 1 { + OptApplier { tcx, duplicates: unreachable_blocks }.visit_body(body); + } +} + pub fn remove_dead_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let reachable = traversal::reachable_as_bitset(body); let num_blocks = body.basic_blocks.len(); diff --git a/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir b/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir index 9ad8a70a2ce..fd6485de863 100644 --- a/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir +++ b/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir @@ -90,7 +90,7 @@ fn b::{closure#0}(_1: Pin<&mut [async fn body@$DIR/async_await.rs:14:18: 17:2]>, bb0: { _39 = discriminant((*(_1.0: &mut [async fn body@$DIR/async_await.rs:14:18: 17:2]))); // scope 0 at $DIR/async_await.rs:+0:18: +3:2 - switchInt(move _39) -> [0: bb1, 1: bb29, 3: bb27, 4: bb28, otherwise: bb30]; // scope 0 at $DIR/async_await.rs:+0:18: +3:2 + switchInt(move _39) -> [0: bb1, 1: bb28, 3: bb26, 4: bb27, otherwise: bb29]; // scope 0 at $DIR/async_await.rs:+0:18: +3:2 } bb1: { @@ -263,7 +263,7 @@ fn b::{closure#0}(_1: Pin<&mut [async fn body@$DIR/async_await.rs:14:18: 17:2]>, StorageDead(_29); // scope 5 at $DIR/async_await.rs:+2:13: +2:14 StorageDead(_26); // scope 5 at $DIR/async_await.rs:+2:13: +2:14 _32 = discriminant(_25); // scope 4 at $DIR/async_await.rs:+2:8: +2:14 - switchInt(move _32) -> [0: bb22, 1: bb20, otherwise: bb21]; // scope 4 at $DIR/async_await.rs:+2:8: +2:14 + switchInt(move _32) -> [0: bb21, 1: bb20, otherwise: bb9]; // scope 4 at $DIR/async_await.rs:+2:8: +2:14 } bb20: { @@ -281,10 +281,6 @@ fn b::{closure#0}(_1: Pin<&mut [async fn body@$DIR/async_await.rs:14:18: 17:2]>, } bb21: { - unreachable; // scope 4 at $DIR/async_await.rs:+2:8: +2:14 - } - - bb22: { StorageLive(_33); // scope 4 at $DIR/async_await.rs:+2:5: +2:14 _33 = ((_25 as Ready).0: ()); // scope 4 at $DIR/async_await.rs:+2:5: +2:14 _37 = _33; // scope 6 at $DIR/async_await.rs:+2:5: +2:14 @@ -293,10 +289,10 @@ fn b::{closure#0}(_1: Pin<&mut [async fn body@$DIR/async_await.rs:14:18: 17:2]>, StorageDead(_28); // scope 4 at $DIR/async_await.rs:+2:13: +2:14 StorageDead(_25); // scope 4 at $DIR/async_await.rs:+2:13: +2:14 StorageDead(_24); // scope 4 at $DIR/async_await.rs:+2:13: +2:14 - goto -> bb24; // scope 0 at $DIR/async_await.rs:+2:13: +2:14 + goto -> bb23; // scope 0 at $DIR/async_await.rs:+2:13: +2:14 } - bb23: { + bb22: { StorageDead(_36); // scope 4 at $DIR/async_await.rs:+2:13: +2:14 _38 = move _35; // scope 4 at $DIR/async_await.rs:+2:8: +2:14 StorageDead(_35); // scope 4 at $DIR/async_await.rs:+2:13: +2:14 @@ -304,23 +300,23 @@ fn b::{closure#0}(_1: Pin<&mut [async fn body@$DIR/async_await.rs:14:18: 17:2]>, goto -> bb16; // scope 4 at $DIR/async_await.rs:+2:8: +2:14 } - bb24: { + bb23: { nop; // scope 0 at $DIR/async_await.rs:+2:13: +2:14 + goto -> bb24; // scope 0 at $DIR/async_await.rs:+3:1: +3:2 + } + + bb24: { + StorageDead(_21); // scope 0 at $DIR/async_await.rs:+3:1: +3:2 goto -> bb25; // scope 0 at $DIR/async_await.rs:+3:1: +3:2 } bb25: { - StorageDead(_21); // scope 0 at $DIR/async_await.rs:+3:1: +3:2 - goto -> bb26; // scope 0 at $DIR/async_await.rs:+3:1: +3:2 - } - - bb26: { _0 = Poll::<()>::Ready(move _37); // scope 0 at $DIR/async_await.rs:+3:2: +3:2 discriminant((*(_1.0: &mut [async fn body@$DIR/async_await.rs:14:18: 17:2]))) = 1; // scope 0 at $DIR/async_await.rs:+3:2: +3:2 return; // scope 0 at $DIR/async_await.rs:+3:2: +3:2 } - bb27: { + bb26: { StorageLive(_3); // scope 0 at $DIR/async_await.rs:+0:18: +3:2 StorageLive(_4); // scope 0 at $DIR/async_await.rs:+0:18: +3:2 StorageLive(_19); // scope 0 at $DIR/async_await.rs:+0:18: +3:2 @@ -329,19 +325,19 @@ fn b::{closure#0}(_1: Pin<&mut [async fn body@$DIR/async_await.rs:14:18: 17:2]>, goto -> bb11; // scope 0 at $DIR/async_await.rs:+0:18: +3:2 } - bb28: { + bb27: { StorageLive(_21); // scope 0 at $DIR/async_await.rs:+0:18: +3:2 StorageLive(_35); // scope 0 at $DIR/async_await.rs:+0:18: +3:2 StorageLive(_36); // scope 0 at $DIR/async_await.rs:+0:18: +3:2 _35 = move _2; // scope 0 at $DIR/async_await.rs:+0:18: +3:2 - goto -> bb23; // scope 0 at $DIR/async_await.rs:+0:18: +3:2 + goto -> bb22; // scope 0 at $DIR/async_await.rs:+0:18: +3:2 + } + + bb28: { + assert(const false, "`async fn` resumed after completion") -> bb28; // scope 0 at $DIR/async_await.rs:+0:18: +3:2 } bb29: { - assert(const false, "`async fn` resumed after completion") -> bb29; // scope 0 at $DIR/async_await.rs:+0:18: +3:2 - } - - bb30: { unreachable; // scope 0 at $DIR/async_await.rs:+0:18: +3:2 } } diff --git a/tests/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff b/tests/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff index 3c7e9dc6131..b5e0a66d83f 100644 --- a/tests/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff +++ b/tests/mir-opt/separate_const_switch.too_complex.SeparateConstSwitch.diff @@ -61,7 +61,7 @@ bb4: { _8 = discriminant(_2); // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 - switchInt(move _8) -> [0: bb7, 1: bb5, otherwise: bb6]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6 + switchInt(move _8) -> [0: bb6, 1: bb5, otherwise: bb2]; // scope 0 at $DIR/separate_const_switch.rs:+5:5: +10:6 } bb5: { @@ -69,14 +69,10 @@ _11 = ((_2 as Break).0: usize); // scope 0 at $DIR/separate_const_switch.rs:+12:28: +12:29 _0 = Option::::None; // scope 4 at $DIR/separate_const_switch.rs:+12:34: +12:38 StorageDead(_11); // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38 - goto -> bb8; // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38 + goto -> bb7; // scope 0 at $DIR/separate_const_switch.rs:+12:37: +12:38 } bb6: { - unreachable; // scope 0 at $DIR/separate_const_switch.rs:+5:11: +10:6 - } - - bb7: { StorageLive(_9); // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32 _9 = ((_2 as Continue).0: i32); // scope 0 at $DIR/separate_const_switch.rs:+11:31: +11:32 StorageLive(_10); // scope 3 at $DIR/separate_const_switch.rs:+11:42: +11:43 @@ -84,10 +80,10 @@ _0 = Option::::Some(move _10); // scope 3 at $DIR/separate_const_switch.rs:+11:37: +11:44 StorageDead(_10); // scope 3 at $DIR/separate_const_switch.rs:+11:43: +11:44 StorageDead(_9); // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44 - goto -> bb8; // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44 + goto -> bb7; // scope 0 at $DIR/separate_const_switch.rs:+11:43: +11:44 } - bb8: { + bb7: { StorageDead(_2); // scope 0 at $DIR/separate_const_switch.rs:+14:1: +14:2 return; // scope 0 at $DIR/separate_const_switch.rs:+14:2: +14:2 } diff --git a/tests/mir-opt/simplify_duplicate_unreachable_blocks.assert_nonzero_nonmax.SimplifyCfg-after-uninhabited-enum-branching.diff b/tests/mir-opt/simplify_duplicate_unreachable_blocks.assert_nonzero_nonmax.SimplifyCfg-after-uninhabited-enum-branching.diff new file mode 100644 index 00000000000..f7f50206af2 --- /dev/null +++ b/tests/mir-opt/simplify_duplicate_unreachable_blocks.assert_nonzero_nonmax.SimplifyCfg-after-uninhabited-enum-branching.diff @@ -0,0 +1,25 @@ +- // MIR for `assert_nonzero_nonmax` before SimplifyCfg-after-uninhabited-enum-branching ++ // MIR for `assert_nonzero_nonmax` after SimplifyCfg-after-uninhabited-enum-branching + + fn assert_nonzero_nonmax(_1: u8) -> u8 { + let mut _0: u8; // return place in scope 0 at $DIR/simplify_duplicate_unreachable_blocks.rs:+0:47: +0:49 + + bb0: { +- switchInt(_1) -> [0: bb1, 255: bb2, otherwise: bb3]; // scope 0 at $DIR/simplify_duplicate_unreachable_blocks.rs:+3:13: +7:14 ++ switchInt(_1) -> [0: bb1, 255: bb1, otherwise: bb2]; // scope 0 at $DIR/simplify_duplicate_unreachable_blocks.rs:+3:13: +7:14 + } + + bb1: { + unreachable; // scope 0 at $DIR/simplify_duplicate_unreachable_blocks.rs:+10:13: +10:26 + } + + bb2: { +- unreachable; // scope 0 at $DIR/simplify_duplicate_unreachable_blocks.rs:+13:13: +13:26 +- } +- +- bb3: { + _0 = _1; // scope 0 at $DIR/simplify_duplicate_unreachable_blocks.rs:+16:13: +16:20 + return; // scope 0 at $DIR/simplify_duplicate_unreachable_blocks.rs:+17:13: +17:21 + } + } + diff --git a/tests/mir-opt/simplify_duplicate_unreachable_blocks.rs b/tests/mir-opt/simplify_duplicate_unreachable_blocks.rs new file mode 100644 index 00000000000..e2578407fea --- /dev/null +++ b/tests/mir-opt/simplify_duplicate_unreachable_blocks.rs @@ -0,0 +1,30 @@ +#![feature(custom_mir, core_intrinsics)] +#![crate_type = "lib"] + +use std::intrinsics::mir::*; + +// unit-test: SimplifyCfg-after-uninhabited-enum-branching + +// EMIT_MIR simplify_duplicate_unreachable_blocks.assert_nonzero_nonmax.SimplifyCfg-after-uninhabited-enum-branching.diff +#[custom_mir(dialect = "runtime", phase = "post-cleanup")] +pub unsafe fn assert_nonzero_nonmax(x: u8) -> u8 { + mir!( + { + match x { + 0 => unreachable1, + u8::MAX => unreachable2, + _ => retblock, + } + } + unreachable1 = { + Unreachable() + } + unreachable2 = { + Unreachable() + } + retblock = { + RET = x; + Return() + } + ) +} diff --git a/tests/mir-opt/try_identity_e2e.new.PreCodegen.after.mir b/tests/mir-opt/try_identity_e2e.new.PreCodegen.after.mir index b9cc1057513..935dbb28b0f 100644 --- a/tests/mir-opt/try_identity_e2e.new.PreCodegen.after.mir +++ b/tests/mir-opt/try_identity_e2e.new.PreCodegen.after.mir @@ -26,37 +26,37 @@ fn new(_1: Result) -> Result { bb0: { StorageLive(_2); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10 _3 = discriminant(_1); // scope 0 at $DIR/try_identity_e2e.rs:+3:19: +3:20 - switchInt(move _3) -> [0: bb2, 1: bb1, otherwise: bb5]; // scope 0 at $DIR/try_identity_e2e.rs:+3:13: +3:20 + switchInt(move _3) -> [0: bb3, 1: bb1, otherwise: bb2]; // scope 0 at $DIR/try_identity_e2e.rs:+3:13: +3:20 } bb1: { _5 = move ((_1 as Err).0: E); // scope 0 at $DIR/try_identity_e2e.rs:+5:21: +5:22 _2 = ControlFlow::::Break(move _5); // scope 2 at $DIR/try_identity_e2e.rs:+5:27: +5:48 - goto -> bb3; // scope 0 at $DIR/try_identity_e2e.rs:+5:47: +5:48 + goto -> bb4; // scope 0 at $DIR/try_identity_e2e.rs:+5:47: +5:48 } bb2: { - _4 = move ((_1 as Ok).0: T); // scope 0 at $DIR/try_identity_e2e.rs:+4:20: +4:21 - _2 = ControlFlow::::Continue(move _4); // scope 1 at $DIR/try_identity_e2e.rs:+4:26: +4:50 - goto -> bb3; // scope 0 at $DIR/try_identity_e2e.rs:+4:49: +4:50 + unreachable; // scope 0 at $DIR/try_identity_e2e.rs:+3:19: +3:20 } bb3: { - _6 = discriminant(_2); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10 - switchInt(move _6) -> [0: bb6, 1: bb4, otherwise: bb5]; // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +7:10 + _4 = move ((_1 as Ok).0: T); // scope 0 at $DIR/try_identity_e2e.rs:+4:20: +4:21 + _2 = ControlFlow::::Continue(move _4); // scope 1 at $DIR/try_identity_e2e.rs:+4:26: +4:50 + goto -> bb4; // scope 0 at $DIR/try_identity_e2e.rs:+4:49: +4:50 } bb4: { + _6 = discriminant(_2); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10 + switchInt(move _6) -> [0: bb6, 1: bb5, otherwise: bb2]; // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +7:10 + } + + bb5: { _8 = move ((_2 as Break).0: E); // scope 0 at $DIR/try_identity_e2e.rs:+9:32: +9:33 _0 = Result::::Err(move _8); // scope 4 at $DIR/try_identity_e2e.rs:+9:45: +9:51 StorageDead(_2); // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2 return; // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2 } - bb5: { - unreachable; // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10 - } - bb6: { _7 = move ((_2 as Continue).0: T); // scope 0 at $DIR/try_identity_e2e.rs:+8:35: +8:36 _0 = Result::::Ok(move _7); // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +11:6 diff --git a/tests/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir b/tests/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir index 03f37b14b28..a0b55664075 100644 --- a/tests/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir +++ b/tests/mir-opt/uninhabited_enum_branching.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir @@ -34,7 +34,7 @@ fn main() -> () { StorageLive(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19 _7 = Test2::D; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19 _8 = discriminant(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19 - switchInt(move _8) -> [4: bb5, 5: bb3, otherwise: bb4]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:5: +7:19 + switchInt(move _8) -> [4: bb4, 5: bb3, otherwise: bb2]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:5: +7:19 } bb2: { @@ -49,22 +49,18 @@ fn main() -> () { // + literal: Const { ty: &str, val: Value(Slice(..)) } _6 = &(*_9); // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:21: +9:24 StorageDead(_9); // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:23: +9:24 - goto -> bb6; // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:23: +9:24 + goto -> bb5; // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:23: +9:24 } bb4: { - unreachable; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19 - } - - bb5: { _6 = const "D"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+8:21: +8:24 // mir::Constant // + span: $DIR/uninhabited_enum_branching.rs:27:21: 27:24 // + literal: Const { ty: &str, val: Value(Slice(..)) } - goto -> bb6; // scope 0 at $DIR/uninhabited_enum_branching.rs:+8:21: +8:24 + goto -> bb5; // scope 0 at $DIR/uninhabited_enum_branching.rs:+8:21: +8:24 } - bb6: { + bb5: { StorageDead(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+10:6: +10:7 StorageDead(_6); // scope 0 at $DIR/uninhabited_enum_branching.rs:+10:6: +10:7 _0 = const (); // scope 0 at $DIR/uninhabited_enum_branching.rs:+0:11: +11:2 diff --git a/tests/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff b/tests/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff index 671e116226b..58d6e42812f 100644 --- a/tests/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff +++ b/tests/mir-opt/uninhabited_enum_branching.main.UninhabitedEnumBranching.diff @@ -63,7 +63,7 @@ StorageLive(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19 _7 = Test2::D; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19 _8 = discriminant(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19 - switchInt(move _8) -> [4: bb8, 5: bb6, otherwise: bb7]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:5: +7:19 + switchInt(move _8) -> [4: bb7, 5: bb6, otherwise: bb2]; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:5: +7:19 } bb6: { @@ -74,22 +74,18 @@ // + literal: Const { ty: &str, val: Value(Slice(..)) } _6 = &(*_9); // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:21: +9:24 StorageDead(_9); // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:23: +9:24 - goto -> bb9; // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:23: +9:24 + goto -> bb8; // scope 0 at $DIR/uninhabited_enum_branching.rs:+9:23: +9:24 } bb7: { - unreachable; // scope 0 at $DIR/uninhabited_enum_branching.rs:+7:11: +7:19 - } - - bb8: { _6 = const "D"; // scope 0 at $DIR/uninhabited_enum_branching.rs:+8:21: +8:24 // mir::Constant // + span: $DIR/uninhabited_enum_branching.rs:27:21: 27:24 // + literal: Const { ty: &str, val: Value(Slice(..)) } - goto -> bb9; // scope 0 at $DIR/uninhabited_enum_branching.rs:+8:21: +8:24 + goto -> bb8; // scope 0 at $DIR/uninhabited_enum_branching.rs:+8:21: +8:24 } - bb9: { + bb8: { StorageDead(_7); // scope 0 at $DIR/uninhabited_enum_branching.rs:+10:6: +10:7 StorageDead(_6); // scope 0 at $DIR/uninhabited_enum_branching.rs:+10:6: +10:7 _0 = const (); // scope 0 at $DIR/uninhabited_enum_branching.rs:+0:11: +11:2 diff --git a/tests/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir b/tests/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir index eb2a76ed1d5..0368b5f18c9 100644 --- a/tests/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir +++ b/tests/mir-opt/uninhabited_enum_branching2.main.SimplifyCfg-after-uninhabited-enum-branching.after.mir @@ -63,7 +63,7 @@ fn main() -> () { StorageDead(_3); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+8:6: +8:7 StorageLive(_9); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +15:6 _10 = discriminant((_1.1: Test1)); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:11: +10:21 - switchInt(move _10) -> [2: bb7, 3: bb5, otherwise: bb6]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +10:21 + switchInt(move _10) -> [2: bb6, 3: bb5, otherwise: bb2]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +10:21 } bb5: { @@ -74,14 +74,10 @@ fn main() -> () { // + literal: Const { ty: &str, val: Value(Slice(..)) } _9 = &(*_13); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:21: +14:24 StorageDead(_13); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:23: +14:24 - goto -> bb8; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:23: +14:24 + goto -> bb7; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:23: +14:24 } bb6: { - unreachable; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:11: +10:21 - } - - bb7: { StorageLive(_12); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:21: +13:24 _12 = const "C"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:21: +13:24 // mir::Constant @@ -89,10 +85,10 @@ fn main() -> () { // + literal: Const { ty: &str, val: Value(Slice(..)) } _9 = &(*_12); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:21: +13:24 StorageDead(_12); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:23: +13:24 - goto -> bb8; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:23: +13:24 + goto -> bb7; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:23: +13:24 } - bb8: { + bb7: { StorageDead(_9); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+15:6: +15:7 _0 = const (); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+0:11: +16:2 StorageDead(_1); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+16:1: +16:2 diff --git a/tests/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff b/tests/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff index 4e797774dba..73353941fae 100644 --- a/tests/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff +++ b/tests/mir-opt/uninhabited_enum_branching2.main.UninhabitedEnumBranching.diff @@ -84,8 +84,8 @@ StorageDead(_3); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+8:6: +8:7 StorageLive(_9); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +15:6 _10 = discriminant((_1.1: Test1)); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:11: +10:21 -- switchInt(move _10) -> [0: bb9, 1: bb10, 2: bb11, 3: bb7, otherwise: bb8]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +10:21 -+ switchInt(move _10) -> [2: bb11, 3: bb7, otherwise: bb8]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +10:21 +- switchInt(move _10) -> [0: bb8, 1: bb9, 2: bb10, 3: bb7, otherwise: bb2]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +10:21 ++ switchInt(move _10) -> [2: bb10, 3: bb7, otherwise: bb2]; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:5: +10:21 } bb7: { @@ -96,22 +96,18 @@ // + literal: Const { ty: &str, val: Value(Slice(..)) } _9 = &(*_13); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:21: +14:24 StorageDead(_13); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:23: +14:24 - goto -> bb12; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:23: +14:24 + goto -> bb11; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+14:23: +14:24 } bb8: { - unreachable; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+10:11: +10:21 - } - - bb9: { _9 = const "A(Empty)"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+11:24: +11:34 // mir::Constant // + span: $DIR/uninhabited_enum_branching2.rs:29:24: 29:34 // + literal: Const { ty: &str, val: Value(Slice(..)) } - goto -> bb12; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+11:24: +11:34 + goto -> bb11; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+11:24: +11:34 } - bb10: { + bb9: { StorageLive(_11); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+12:24: +12:34 _11 = const "B(Empty)"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+12:24: +12:34 // mir::Constant @@ -119,10 +115,10 @@ // + literal: Const { ty: &str, val: Value(Slice(..)) } _9 = &(*_11); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+12:24: +12:34 StorageDead(_11); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+12:33: +12:34 - goto -> bb12; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+12:33: +12:34 + goto -> bb11; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+12:33: +12:34 } - bb11: { + bb10: { StorageLive(_12); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:21: +13:24 _12 = const "C"; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:21: +13:24 // mir::Constant @@ -130,10 +126,10 @@ // + literal: Const { ty: &str, val: Value(Slice(..)) } _9 = &(*_12); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:21: +13:24 StorageDead(_12); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:23: +13:24 - goto -> bb12; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:23: +13:24 + goto -> bb11; // scope 1 at $DIR/uninhabited_enum_branching2.rs:+13:23: +13:24 } - bb12: { + bb11: { StorageDead(_9); // scope 1 at $DIR/uninhabited_enum_branching2.rs:+15:6: +15:7 _0 = const (); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+0:11: +16:2 StorageDead(_1); // scope 0 at $DIR/uninhabited_enum_branching2.rs:+16:1: +16:2 From 2a628bd99c39b69e88b24c622e3d246dd5573353 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Fri, 24 Feb 2023 16:32:59 -0500 Subject: [PATCH 062/346] Remove duplicate switch targets --- .../rustc_mir_transform/src/instcombine.rs | 16 ++++++++++- ...witch_targets.assert_zero.InstCombine.diff | 21 +++++++++++++++ .../instcombine_duplicate_switch_targets.rs | 27 +++++++++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 tests/mir-opt/instcombine_duplicate_switch_targets.assert_zero.InstCombine.diff create mode 100644 tests/mir-opt/instcombine_duplicate_switch_targets.rs diff --git a/compiler/rustc_mir_transform/src/instcombine.rs b/compiler/rustc_mir_transform/src/instcombine.rs index 4182da1957e..c926390aa2b 100644 --- a/compiler/rustc_mir_transform/src/instcombine.rs +++ b/compiler/rustc_mir_transform/src/instcombine.rs @@ -4,7 +4,7 @@ use crate::MirPass; use rustc_hir::Mutability; use rustc_middle::mir::{ BinOp, Body, Constant, ConstantKind, LocalDecls, Operand, Place, ProjectionElem, Rvalue, - SourceInfo, Statement, StatementKind, Terminator, TerminatorKind, UnOp, + SourceInfo, Statement, StatementKind, SwitchTargets, Terminator, TerminatorKind, UnOp, }; use rustc_middle::ty::layout::ValidityRequirement; use rustc_middle::ty::{self, ParamEnv, SubstsRef, Ty, TyCtxt}; @@ -44,6 +44,7 @@ impl<'tcx> MirPass<'tcx> for InstCombine { &mut block.terminator.as_mut().unwrap(), &mut block.statements, ); + ctx.combine_duplicate_switch_targets(&mut block.terminator.as_mut().unwrap()); } } } @@ -217,6 +218,19 @@ impl<'tcx> InstCombineContext<'tcx, '_> { terminator.kind = TerminatorKind::Goto { target: destination_block }; } + fn combine_duplicate_switch_targets(&self, terminator: &mut Terminator<'tcx>) { + let TerminatorKind::SwitchInt { targets, .. } = &mut terminator.kind + else { return }; + + let otherwise = targets.otherwise(); + if targets.iter().any(|t| t.1 == otherwise) { + *targets = SwitchTargets::new( + targets.iter().filter(|t| t.1 != otherwise), + targets.otherwise(), + ); + } + } + fn combine_intrinsic_assert( &self, terminator: &mut Terminator<'tcx>, diff --git a/tests/mir-opt/instcombine_duplicate_switch_targets.assert_zero.InstCombine.diff b/tests/mir-opt/instcombine_duplicate_switch_targets.assert_zero.InstCombine.diff new file mode 100644 index 00000000000..e04079453d2 --- /dev/null +++ b/tests/mir-opt/instcombine_duplicate_switch_targets.assert_zero.InstCombine.diff @@ -0,0 +1,21 @@ +- // MIR for `assert_zero` before InstCombine ++ // MIR for `assert_zero` after InstCombine + + fn assert_zero(_1: u8) -> u8 { + let mut _0: u8; // return place in scope 0 at $DIR/instcombine_duplicate_switch_targets.rs:+0:37: +0:39 + + bb0: { +- switchInt(_1) -> [0: bb2, 1: bb1, otherwise: bb1]; // scope 0 at $DIR/instcombine_duplicate_switch_targets.rs:+3:13: +7:14 ++ switchInt(_1) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/instcombine_duplicate_switch_targets.rs:+3:13: +7:14 + } + + bb1: { + unreachable; // scope 0 at $DIR/instcombine_duplicate_switch_targets.rs:+10:13: +10:26 + } + + bb2: { + _0 = _1; // scope 0 at $DIR/instcombine_duplicate_switch_targets.rs:+13:13: +13:20 + return; // scope 0 at $DIR/instcombine_duplicate_switch_targets.rs:+14:13: +14:21 + } + } + diff --git a/tests/mir-opt/instcombine_duplicate_switch_targets.rs b/tests/mir-opt/instcombine_duplicate_switch_targets.rs new file mode 100644 index 00000000000..ef3b487afa3 --- /dev/null +++ b/tests/mir-opt/instcombine_duplicate_switch_targets.rs @@ -0,0 +1,27 @@ +#![feature(custom_mir, core_intrinsics)] +#![crate_type = "lib"] + +use std::intrinsics::mir::*; + +// unit-test: InstCombine + +// EMIT_MIR instcombine_duplicate_switch_targets.assert_zero.InstCombine.diff +#[custom_mir(dialect = "runtime", phase = "post-cleanup")] +pub unsafe fn assert_zero(x: u8) -> u8 { + mir!( + { + match x { + 0 => retblock, + 1 => unreachable, + _ => unreachable, + } + } + unreachable = { + Unreachable() + } + retblock = { + RET = x; + Return() + } + ) +} From a98ddb6de1723a30777c68983c74bcb45ec52580 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Fri, 24 Feb 2023 16:33:22 -0500 Subject: [PATCH 063/346] Enable inlining of diverging functions --- compiler/rustc_mir_transform/src/inline.rs | 7 -- tests/mir-opt/inline/unchecked_shifts.rs | 17 +++ ...unchecked_shl_unsigned_smaller.Inline.diff | 115 ++++++++++++++++++ ..._shl_unsigned_smaller.PreCodegen.after.mir | 102 ++++++++++++++++ ...s.unchecked_shr_signed_smaller.Inline.diff | 115 ++++++++++++++++++ ...ed_shr_signed_smaller.PreCodegen.after.mir | 102 ++++++++++++++++ tests/mir-opt/inline/unwrap_unchecked.rs | 10 ++ ...rap_unchecked.unwrap_unchecked.Inline.diff | 55 +++++++++ ...cked.unwrap_unchecked.PreCodegen.after.mir | 41 +++++++ 9 files changed, 557 insertions(+), 7 deletions(-) create mode 100644 tests/mir-opt/inline/unchecked_shifts.rs create mode 100644 tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff create mode 100644 tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir create mode 100644 tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff create mode 100644 tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir create mode 100644 tests/mir-opt/inline/unwrap_unchecked.rs create mode 100644 tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.diff create mode 100644 tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.mir diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 9cba8870f23..27fad8a655e 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -424,13 +424,6 @@ impl<'tcx> Inliner<'tcx> { debug!(" final inline threshold = {}", threshold); // FIXME: Give a bonus to functions with only a single caller - let diverges = matches!( - callee_body.basic_blocks[START_BLOCK].terminator().kind, - TerminatorKind::Unreachable | TerminatorKind::Call { target: None, .. } - ); - if diverges && !matches!(callee_attrs.inline, InlineAttr::Always) { - return Err("callee diverges unconditionally"); - } let mut checker = CostChecker { tcx: self.tcx, diff --git a/tests/mir-opt/inline/unchecked_shifts.rs b/tests/mir-opt/inline/unchecked_shifts.rs new file mode 100644 index 00000000000..e55fa745abc --- /dev/null +++ b/tests/mir-opt/inline/unchecked_shifts.rs @@ -0,0 +1,17 @@ +#![crate_type = "lib"] +#![feature(unchecked_math)] + +// ignore-debug: the debug assertions prevent the inlining we are testing for +// compile-flags: -Zmir-opt-level=2 -Zinline-mir + +// EMIT_MIR unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff +// EMIT_MIR unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir +pub unsafe fn unchecked_shl_unsigned_smaller(a: u16, b: u32) -> u16 { + a.unchecked_shl(b) +} + +// EMIT_MIR unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff +// EMIT_MIR unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir +pub unsafe fn unchecked_shr_signed_smaller(a: i16, b: u32) -> i16 { + a.unchecked_shr(b) +} diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff new file mode 100644 index 00000000000..5fd918b3aa5 --- /dev/null +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.diff @@ -0,0 +1,115 @@ +- // MIR for `unchecked_shl_unsigned_smaller` before Inline ++ // MIR for `unchecked_shl_unsigned_smaller` after Inline + + fn unchecked_shl_unsigned_smaller(_1: u16, _2: u32) -> u16 { + debug a => _1; // in scope 0 at $DIR/unchecked_shifts.rs:+0:46: +0:47 + debug b => _2; // in scope 0 at $DIR/unchecked_shifts.rs:+0:54: +0:55 + let mut _0: u16; // return place in scope 0 at $DIR/unchecked_shifts.rs:+0:65: +0:68 + let mut _3: u16; // in scope 0 at $DIR/unchecked_shifts.rs:+1:5: +1:6 + let mut _4: u32; // in scope 0 at $DIR/unchecked_shifts.rs:+1:21: +1:22 ++ scope 1 (inlined core::num::::unchecked_shl) { // at $DIR/unchecked_shifts.rs:10:7: 10:23 ++ debug self => _3; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL ++ debug rhs => _4; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL ++ let mut _5: u16; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL ++ let mut _6: std::option::Option; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL ++ let mut _7: std::result::Result; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL ++ scope 2 { ++ scope 3 (inlined Result::::ok) { // at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL ++ debug self => _7; // in scope 3 at $SRC_DIR/core/src/result.rs:LL:COL ++ let mut _8: isize; // in scope 3 at $SRC_DIR/core/src/result.rs:LL:COL ++ let _9: u16; // in scope 3 at $SRC_DIR/core/src/result.rs:LL:COL ++ scope 4 { ++ debug x => _9; // in scope 4 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ scope 5 { ++ scope 6 { ++ debug x => const TryFromIntError(()); // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ } ++ } ++ scope 7 (inlined #[track_caller] Option::::unwrap_unchecked) { // at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL ++ debug self => _6; // in scope 7 at $SRC_DIR/core/src/option.rs:LL:COL ++ let mut _10: &std::option::Option; // in scope 7 at $SRC_DIR/core/src/option.rs:LL:COL ++ let mut _11: isize; // in scope 7 at $SRC_DIR/core/src/option.rs:LL:COL ++ scope 8 { ++ debug val => _5; // in scope 8 at $SRC_DIR/core/src/option.rs:LL:COL ++ } ++ scope 9 { ++ scope 11 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL ++ scope 12 { ++ scope 13 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL ++ } ++ } ++ } ++ } ++ scope 10 (inlined Option::::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL ++ debug self => _10; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL ++ } ++ } ++ } ++ } + + bb0: { + StorageLive(_3); // scope 0 at $DIR/unchecked_shifts.rs:+1:5: +1:6 + _3 = _1; // scope 0 at $DIR/unchecked_shifts.rs:+1:5: +1:6 + StorageLive(_4); // scope 0 at $DIR/unchecked_shifts.rs:+1:21: +1:22 + _4 = _2; // scope 0 at $DIR/unchecked_shifts.rs:+1:21: +1:22 +- _0 = core::num::::unchecked_shl(move _3, move _4) -> bb1; // scope 0 at $DIR/unchecked_shifts.rs:+1:5: +1:23 ++ StorageLive(_5); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL ++ StorageLive(_6); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL ++ StorageLive(_7); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL ++ _7 = >::try_into(_4) -> bb1; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + // mir::Constant +- // + span: $DIR/unchecked_shifts.rs:10:7: 10:20 +- // + literal: Const { ty: unsafe fn(u16, u32) -> u16 {core::num::::unchecked_shl}, val: Value() } ++ // + span: $SRC_DIR/core/src/num/uint_macros.rs:LL:COL ++ // + literal: Const { ty: fn(u32) -> Result>::Error> {>::try_into}, val: Value() } + } + + bb1: { ++ StorageLive(_9); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL ++ _8 = discriminant(_7); // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL ++ switchInt(move _8) -> [0: bb6, 1: bb4, otherwise: bb5]; // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ ++ bb2: { ++ StorageDead(_9); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL ++ StorageDead(_7); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL ++ StorageLive(_10); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL ++ _11 = discriminant(_6); // scope 7 at $SRC_DIR/core/src/option.rs:LL:COL ++ switchInt(move _11) -> [1: bb7, otherwise: bb5]; // scope 7 at $SRC_DIR/core/src/option.rs:LL:COL ++ } ++ ++ bb3: { ++ StorageDead(_5); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + StorageDead(_4); // scope 0 at $DIR/unchecked_shifts.rs:+1:22: +1:23 + StorageDead(_3); // scope 0 at $DIR/unchecked_shifts.rs:+1:22: +1:23 + return; // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2 ++ } ++ ++ bb4: { ++ _6 = Option::::None; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL ++ goto -> bb2; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ ++ bb5: { ++ unreachable; // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ ++ bb6: { ++ _9 = move ((_7 as Ok).0: u16); // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL ++ _6 = Option::::Some(move _9); // scope 4 at $SRC_DIR/core/src/result.rs:LL:COL ++ goto -> bb2; // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ ++ bb7: { ++ _5 = move ((_6 as Some).0: u16); // scope 7 at $SRC_DIR/core/src/option.rs:LL:COL ++ StorageDead(_10); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL ++ StorageDead(_6); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL ++ _0 = unchecked_shl::(_3, move _5) -> bb3; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL ++ // mir::Constant ++ // + span: $SRC_DIR/core/src/num/uint_macros.rs:LL:COL ++ // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u16, u16) -> u16 {unchecked_shl::}, val: Value() } + } + } + diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir new file mode 100644 index 00000000000..c5501cef743 --- /dev/null +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.mir @@ -0,0 +1,102 @@ +// MIR for `unchecked_shl_unsigned_smaller` after PreCodegen + +fn unchecked_shl_unsigned_smaller(_1: u16, _2: u32) -> u16 { + debug a => _1; // in scope 0 at $DIR/unchecked_shifts.rs:+0:46: +0:47 + debug b => _2; // in scope 0 at $DIR/unchecked_shifts.rs:+0:54: +0:55 + let mut _0: u16; // return place in scope 0 at $DIR/unchecked_shifts.rs:+0:65: +0:68 + scope 1 (inlined core::num::::unchecked_shl) { // at $DIR/unchecked_shifts.rs:10:7: 10:23 + debug self => _1; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + debug rhs => _2; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + let mut _3: u16; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + let mut _4: std::option::Option; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + let mut _5: std::result::Result; // in scope 1 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + scope 2 { + scope 3 (inlined Result::::ok) { // at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + debug self => _5; // in scope 3 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _6: isize; // in scope 3 at $SRC_DIR/core/src/result.rs:LL:COL + let _7: u16; // in scope 3 at $SRC_DIR/core/src/result.rs:LL:COL + scope 4 { + debug x => _7; // in scope 4 at $SRC_DIR/core/src/result.rs:LL:COL + } + scope 5 { + scope 6 { + debug x => const TryFromIntError(()); // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL + } + } + } + scope 7 (inlined #[track_caller] Option::::unwrap_unchecked) { // at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + debug self => _4; // in scope 7 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _8: &std::option::Option; // in scope 7 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _9: isize; // in scope 7 at $SRC_DIR/core/src/option.rs:LL:COL + scope 8 { + debug val => _3; // in scope 8 at $SRC_DIR/core/src/option.rs:LL:COL + } + scope 9 { + scope 11 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL + scope 12 { + scope 13 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + } + } + } + scope 10 (inlined Option::::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL + debug self => _8; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL + } + } + } + } + + bb0: { + StorageLive(_3); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + StorageLive(_4); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + StorageLive(_5); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + _5 = >::try_into(_2) -> bb1; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + // + literal: Const { ty: fn(u32) -> Result>::Error> {>::try_into}, val: Value() } + } + + bb1: { + StorageLive(_7); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + _6 = discriminant(_5); // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL + switchInt(move _6) -> [0: bb6, 1: bb4, otherwise: bb5]; // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb2: { + StorageDead(_7); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + StorageDead(_5); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + StorageLive(_8); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + _9 = discriminant(_4); // scope 7 at $SRC_DIR/core/src/option.rs:LL:COL + switchInt(move _9) -> [1: bb7, otherwise: bb5]; // scope 7 at $SRC_DIR/core/src/option.rs:LL:COL + } + + bb3: { + StorageDead(_3); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + return; // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2 + } + + bb4: { + _4 = Option::::None; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL + goto -> bb2; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb5: { + unreachable; // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb6: { + _7 = move ((_5 as Ok).0: u16); // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL + _4 = Option::::Some(move _7); // scope 4 at $SRC_DIR/core/src/result.rs:LL:COL + goto -> bb2; // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb7: { + _3 = move ((_4 as Some).0: u16); // scope 7 at $SRC_DIR/core/src/option.rs:LL:COL + StorageDead(_8); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + StorageDead(_4); // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + _0 = unchecked_shl::(_1, move _3) -> bb3; // scope 2 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/num/uint_macros.rs:LL:COL + // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u16, u16) -> u16 {unchecked_shl::}, val: Value() } + } +} diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff new file mode 100644 index 00000000000..68d3b21fc2a --- /dev/null +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.Inline.diff @@ -0,0 +1,115 @@ +- // MIR for `unchecked_shr_signed_smaller` before Inline ++ // MIR for `unchecked_shr_signed_smaller` after Inline + + fn unchecked_shr_signed_smaller(_1: i16, _2: u32) -> i16 { + debug a => _1; // in scope 0 at $DIR/unchecked_shifts.rs:+0:44: +0:45 + debug b => _2; // in scope 0 at $DIR/unchecked_shifts.rs:+0:52: +0:53 + let mut _0: i16; // return place in scope 0 at $DIR/unchecked_shifts.rs:+0:63: +0:66 + let mut _3: i16; // in scope 0 at $DIR/unchecked_shifts.rs:+1:5: +1:6 + let mut _4: u32; // in scope 0 at $DIR/unchecked_shifts.rs:+1:21: +1:22 ++ scope 1 (inlined core::num::::unchecked_shr) { // at $DIR/unchecked_shifts.rs:16:7: 16:23 ++ debug self => _3; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL ++ debug rhs => _4; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL ++ let mut _5: i16; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL ++ let mut _6: std::option::Option; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL ++ let mut _7: std::result::Result; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL ++ scope 2 { ++ scope 3 (inlined Result::::ok) { // at $SRC_DIR/core/src/num/int_macros.rs:LL:COL ++ debug self => _7; // in scope 3 at $SRC_DIR/core/src/result.rs:LL:COL ++ let mut _8: isize; // in scope 3 at $SRC_DIR/core/src/result.rs:LL:COL ++ let _9: i16; // in scope 3 at $SRC_DIR/core/src/result.rs:LL:COL ++ scope 4 { ++ debug x => _9; // in scope 4 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ scope 5 { ++ scope 6 { ++ debug x => const TryFromIntError(()); // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ } ++ } ++ scope 7 (inlined #[track_caller] Option::::unwrap_unchecked) { // at $SRC_DIR/core/src/num/int_macros.rs:LL:COL ++ debug self => _6; // in scope 7 at $SRC_DIR/core/src/option.rs:LL:COL ++ let mut _10: &std::option::Option; // in scope 7 at $SRC_DIR/core/src/option.rs:LL:COL ++ let mut _11: isize; // in scope 7 at $SRC_DIR/core/src/option.rs:LL:COL ++ scope 8 { ++ debug val => _5; // in scope 8 at $SRC_DIR/core/src/option.rs:LL:COL ++ } ++ scope 9 { ++ scope 11 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL ++ scope 12 { ++ scope 13 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL ++ } ++ } ++ } ++ } ++ scope 10 (inlined Option::::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL ++ debug self => _10; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL ++ } ++ } ++ } ++ } + + bb0: { + StorageLive(_3); // scope 0 at $DIR/unchecked_shifts.rs:+1:5: +1:6 + _3 = _1; // scope 0 at $DIR/unchecked_shifts.rs:+1:5: +1:6 + StorageLive(_4); // scope 0 at $DIR/unchecked_shifts.rs:+1:21: +1:22 + _4 = _2; // scope 0 at $DIR/unchecked_shifts.rs:+1:21: +1:22 +- _0 = core::num::::unchecked_shr(move _3, move _4) -> bb1; // scope 0 at $DIR/unchecked_shifts.rs:+1:5: +1:23 ++ StorageLive(_5); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL ++ StorageLive(_6); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL ++ StorageLive(_7); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL ++ _7 = >::try_into(_4) -> bb1; // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + // mir::Constant +- // + span: $DIR/unchecked_shifts.rs:16:7: 16:20 +- // + literal: Const { ty: unsafe fn(i16, u32) -> i16 {core::num::::unchecked_shr}, val: Value() } ++ // + span: $SRC_DIR/core/src/num/int_macros.rs:LL:COL ++ // + literal: Const { ty: fn(u32) -> Result>::Error> {>::try_into}, val: Value() } + } + + bb1: { ++ StorageLive(_9); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL ++ _8 = discriminant(_7); // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL ++ switchInt(move _8) -> [0: bb6, 1: bb4, otherwise: bb5]; // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ ++ bb2: { ++ StorageDead(_9); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL ++ StorageDead(_7); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL ++ StorageLive(_10); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL ++ _11 = discriminant(_6); // scope 7 at $SRC_DIR/core/src/option.rs:LL:COL ++ switchInt(move _11) -> [1: bb7, otherwise: bb5]; // scope 7 at $SRC_DIR/core/src/option.rs:LL:COL ++ } ++ ++ bb3: { ++ StorageDead(_5); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + StorageDead(_4); // scope 0 at $DIR/unchecked_shifts.rs:+1:22: +1:23 + StorageDead(_3); // scope 0 at $DIR/unchecked_shifts.rs:+1:22: +1:23 + return; // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2 ++ } ++ ++ bb4: { ++ _6 = Option::::None; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL ++ goto -> bb2; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ ++ bb5: { ++ unreachable; // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ ++ bb6: { ++ _9 = move ((_7 as Ok).0: i16); // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL ++ _6 = Option::::Some(move _9); // scope 4 at $SRC_DIR/core/src/result.rs:LL:COL ++ goto -> bb2; // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL ++ } ++ ++ bb7: { ++ _5 = move ((_6 as Some).0: i16); // scope 7 at $SRC_DIR/core/src/option.rs:LL:COL ++ StorageDead(_10); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL ++ StorageDead(_6); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL ++ _0 = unchecked_shr::(_3, move _5) -> bb3; // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL ++ // mir::Constant ++ // + span: $SRC_DIR/core/src/num/int_macros.rs:LL:COL ++ // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(i16, i16) -> i16 {unchecked_shr::}, val: Value() } + } + } + diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir new file mode 100644 index 00000000000..ed3a89ceace --- /dev/null +++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_smaller.PreCodegen.after.mir @@ -0,0 +1,102 @@ +// MIR for `unchecked_shr_signed_smaller` after PreCodegen + +fn unchecked_shr_signed_smaller(_1: i16, _2: u32) -> i16 { + debug a => _1; // in scope 0 at $DIR/unchecked_shifts.rs:+0:44: +0:45 + debug b => _2; // in scope 0 at $DIR/unchecked_shifts.rs:+0:52: +0:53 + let mut _0: i16; // return place in scope 0 at $DIR/unchecked_shifts.rs:+0:63: +0:66 + scope 1 (inlined core::num::::unchecked_shr) { // at $DIR/unchecked_shifts.rs:16:7: 16:23 + debug self => _1; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + debug rhs => _2; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + let mut _3: i16; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + let mut _4: std::option::Option; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + let mut _5: std::result::Result; // in scope 1 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + scope 2 { + scope 3 (inlined Result::::ok) { // at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + debug self => _5; // in scope 3 at $SRC_DIR/core/src/result.rs:LL:COL + let mut _6: isize; // in scope 3 at $SRC_DIR/core/src/result.rs:LL:COL + let _7: i16; // in scope 3 at $SRC_DIR/core/src/result.rs:LL:COL + scope 4 { + debug x => _7; // in scope 4 at $SRC_DIR/core/src/result.rs:LL:COL + } + scope 5 { + scope 6 { + debug x => const TryFromIntError(()); // in scope 6 at $SRC_DIR/core/src/result.rs:LL:COL + } + } + } + scope 7 (inlined #[track_caller] Option::::unwrap_unchecked) { // at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + debug self => _4; // in scope 7 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _8: &std::option::Option; // in scope 7 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _9: isize; // in scope 7 at $SRC_DIR/core/src/option.rs:LL:COL + scope 8 { + debug val => _3; // in scope 8 at $SRC_DIR/core/src/option.rs:LL:COL + } + scope 9 { + scope 11 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL + scope 12 { + scope 13 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + } + } + } + scope 10 (inlined Option::::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL + debug self => _8; // in scope 10 at $SRC_DIR/core/src/option.rs:LL:COL + } + } + } + } + + bb0: { + StorageLive(_3); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + StorageLive(_4); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + StorageLive(_5); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + _5 = >::try_into(_2) -> bb1; // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/num/int_macros.rs:LL:COL + // + literal: Const { ty: fn(u32) -> Result>::Error> {>::try_into}, val: Value() } + } + + bb1: { + StorageLive(_7); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + _6 = discriminant(_5); // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL + switchInt(move _6) -> [0: bb6, 1: bb4, otherwise: bb5]; // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb2: { + StorageDead(_7); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + StorageDead(_5); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + StorageLive(_8); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + _9 = discriminant(_4); // scope 7 at $SRC_DIR/core/src/option.rs:LL:COL + switchInt(move _9) -> [1: bb7, otherwise: bb5]; // scope 7 at $SRC_DIR/core/src/option.rs:LL:COL + } + + bb3: { + StorageDead(_3); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + return; // scope 0 at $DIR/unchecked_shifts.rs:+2:2: +2:2 + } + + bb4: { + _4 = Option::::None; // scope 6 at $SRC_DIR/core/src/result.rs:LL:COL + goto -> bb2; // scope 5 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb5: { + unreachable; // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb6: { + _7 = move ((_5 as Ok).0: i16); // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL + _4 = Option::::Some(move _7); // scope 4 at $SRC_DIR/core/src/result.rs:LL:COL + goto -> bb2; // scope 3 at $SRC_DIR/core/src/result.rs:LL:COL + } + + bb7: { + _3 = move ((_4 as Some).0: i16); // scope 7 at $SRC_DIR/core/src/option.rs:LL:COL + StorageDead(_8); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + StorageDead(_4); // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + _0 = unchecked_shr::(_1, move _3) -> bb3; // scope 2 at $SRC_DIR/core/src/num/int_macros.rs:LL:COL + // mir::Constant + // + span: $SRC_DIR/core/src/num/int_macros.rs:LL:COL + // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(i16, i16) -> i16 {unchecked_shr::}, val: Value() } + } +} diff --git a/tests/mir-opt/inline/unwrap_unchecked.rs b/tests/mir-opt/inline/unwrap_unchecked.rs new file mode 100644 index 00000000000..c3581093f66 --- /dev/null +++ b/tests/mir-opt/inline/unwrap_unchecked.rs @@ -0,0 +1,10 @@ +#![crate_type = "lib"] + +// ignore-debug: the debug assertions prevent the inlining we are testing for +// compile-flags: -Zmir-opt-level=2 -Zinline-mir + +// EMIT_MIR unwrap_unchecked.unwrap_unchecked.Inline.diff +// EMIT_MIR unwrap_unchecked.unwrap_unchecked.PreCodegen.after.mir +pub unsafe fn unwrap_unchecked(slf: Option) -> T { + slf.unwrap_unchecked() +} diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.diff b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.diff new file mode 100644 index 00000000000..7f73306a825 --- /dev/null +++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.diff @@ -0,0 +1,55 @@ +- // MIR for `unwrap_unchecked` before Inline ++ // MIR for `unwrap_unchecked` after Inline + + fn unwrap_unchecked(_1: Option) -> T { + debug slf => _1; // in scope 0 at $DIR/unwrap_unchecked.rs:+0:35: +0:38 + let mut _0: T; // return place in scope 0 at $DIR/unwrap_unchecked.rs:+0:54: +0:55 + let mut _2: std::option::Option; // in scope 0 at $DIR/unwrap_unchecked.rs:+1:5: +1:8 ++ scope 1 (inlined #[track_caller] Option::::unwrap_unchecked) { // at $DIR/unwrap_unchecked.rs:9:9: 9:27 ++ debug self => _2; // in scope 1 at $SRC_DIR/core/src/option.rs:LL:COL ++ let mut _3: &std::option::Option; // in scope 1 at $SRC_DIR/core/src/option.rs:LL:COL ++ let mut _4: isize; // in scope 1 at $SRC_DIR/core/src/option.rs:LL:COL ++ scope 2 { ++ debug val => _0; // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL ++ } ++ scope 3 { ++ scope 5 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL ++ scope 6 { ++ scope 7 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL ++ } ++ } ++ } ++ } ++ scope 4 (inlined Option::::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL ++ debug self => _3; // in scope 4 at $SRC_DIR/core/src/option.rs:LL:COL ++ } ++ } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/unwrap_unchecked.rs:+1:5: +1:8 + _2 = move _1; // scope 0 at $DIR/unwrap_unchecked.rs:+1:5: +1:8 +- _0 = Option::::unwrap_unchecked(move _2) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/unwrap_unchecked.rs:+1:5: +1:27 +- // mir::Constant +- // + span: $DIR/unwrap_unchecked.rs:9:9: 9:25 +- // + literal: Const { ty: unsafe fn(Option) -> T {Option::::unwrap_unchecked}, val: Value() } ++ StorageLive(_3); // scope 0 at $DIR/unwrap_unchecked.rs:+1:9: +1:27 ++ _4 = discriminant(_2); // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL ++ switchInt(move _4) -> [0: bb1, 1: bb2, otherwise: bb1]; // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL + } + + bb1: { +- StorageDead(_2); // scope 0 at $DIR/unwrap_unchecked.rs:+1:26: +1:27 +- return; // scope 0 at $DIR/unwrap_unchecked.rs:+2:2: +2:2 ++ unreachable; // scope 6 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + +- bb2 (cleanup): { +- resume; // scope 0 at $DIR/unwrap_unchecked.rs:+0:1: +2:2 ++ bb2: { ++ _0 = move ((_2 as Some).0: T); // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL ++ StorageDead(_3); // scope 0 at $DIR/unwrap_unchecked.rs:+1:9: +1:27 ++ StorageDead(_2); // scope 0 at $DIR/unwrap_unchecked.rs:+1:26: +1:27 ++ return; // scope 0 at $DIR/unwrap_unchecked.rs:+2:2: +2:2 + } + } + diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.mir b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.mir new file mode 100644 index 00000000000..33cd3785336 --- /dev/null +++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.mir @@ -0,0 +1,41 @@ +// MIR for `unwrap_unchecked` after PreCodegen + +fn unwrap_unchecked(_1: Option) -> T { + debug slf => _1; // in scope 0 at $DIR/unwrap_unchecked.rs:+0:35: +0:38 + let mut _0: T; // return place in scope 0 at $DIR/unwrap_unchecked.rs:+0:54: +0:55 + scope 1 (inlined #[track_caller] Option::::unwrap_unchecked) { // at $DIR/unwrap_unchecked.rs:9:9: 9:27 + debug self => _1; // in scope 1 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _2: &std::option::Option; // in scope 1 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _3: isize; // in scope 1 at $SRC_DIR/core/src/option.rs:LL:COL + scope 2 { + debug val => _0; // in scope 2 at $SRC_DIR/core/src/option.rs:LL:COL + } + scope 3 { + scope 5 (inlined unreachable_unchecked) { // at $SRC_DIR/core/src/option.rs:LL:COL + scope 6 { + scope 7 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + } + } + } + scope 4 (inlined Option::::is_some) { // at $SRC_DIR/core/src/option.rs:LL:COL + debug self => _2; // in scope 4 at $SRC_DIR/core/src/option.rs:LL:COL + } + } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/unwrap_unchecked.rs:+1:9: +1:27 + _3 = discriminant(_1); // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL + switchInt(move _3) -> [1: bb2, otherwise: bb1]; // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL + } + + bb1: { + unreachable; // scope 6 at $SRC_DIR/core/src/intrinsics.rs:LL:COL + } + + bb2: { + _0 = move ((_1 as Some).0: T); // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL + StorageDead(_2); // scope 0 at $DIR/unwrap_unchecked.rs:+1:9: +1:27 + return; // scope 0 at $DIR/unwrap_unchecked.rs:+2:2: +2:2 + } +} From 06e674313b0feb4287bc330bd8841af0acffc94a Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Sat, 11 Mar 2023 21:11:04 -0500 Subject: [PATCH 064/346] Always enable MIR inlining when building std --- src/bootstrap/builder.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index bb07ca1908e..287e00c644f 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1933,6 +1933,12 @@ impl<'a> Builder<'a> { rustflags.arg("-Zvalidate-mir"); rustflags.arg(&format!("-Zmir-opt-level={}", mir_opt_level)); } + // Always enable inlining MIR when building the standard library. + // Without this flag, MIR inlining is disabled when incremental compilation is enabled. + // That causes some mir-opt tests which inline functions from the standard library to + // break when incremental compilation is enabled. So this overrides the "no inlining + // during incremental builds" heuristic for the standard library. + rustflags.arg("-Zinline-mir"); } Cargo { command: cargo, rustflags, rustdocflags, allow_features } From dec6ef8a74db38ff80669255911ce7fc541d4c44 Mon Sep 17 00:00:00 2001 From: xFrednet Date: Sun, 19 Mar 2023 13:42:12 +0100 Subject: [PATCH 065/346] Correct active members link in `CONTRIBUTING.md` --- CONTRIBUTING.md | 2 +- triagebot.toml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3158080d2b3..3df13280369 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -50,7 +50,7 @@ a [developer guide] and is a good place to start your journey. All issues on Clippy are mentored, if you want help simply ask someone from the Clippy team directly by mentioning them in the issue or over on [Zulip]. All currently active team members can be found -[here](https://github.com/rust-lang/highfive/blob/master/highfive/configs/rust-lang/rust-clippy.json#L3) +[here](https://github.com/rust-lang/rust-clippy/blob/master/triagebot.toml#L18) Some issues are easier than others. The [`good-first-issue`] label can be used to find the easy issues. You can use `@rustbot claim` to assign the issue to yourself. diff --git a/triagebot.toml b/triagebot.toml index 6f50ef932e1..3f8f6a7b98c 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -17,6 +17,7 @@ contributing_url = "https://github.com/rust-lang/rust-clippy/blob/master/CONTRIB [assign.owners] "/.github" = ["@flip1995"] +"/util/gh-pages" = ["@xFrednet"] "*" = [ "@flip1995", "@Manishearth", From d3352def96f9bd8e32fddfc1d8cdfb56c47040f2 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Sat, 18 Mar 2023 13:25:47 -0400 Subject: [PATCH 066/346] Add #[inline] to as_deref --- library/core/src/option.rs | 2 ++ library/core/src/result.rs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 0f2475a8bde..aab3bf1bc12 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -1310,6 +1310,7 @@ impl Option { /// let x: Option = None; /// assert_eq!(x.as_deref(), None); /// ``` + #[inline] #[stable(feature = "option_deref", since = "1.40.0")] #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] pub const fn as_deref(&self) -> Option<&T::Target> @@ -1336,6 +1337,7 @@ impl Option { /// x /// }), Some("HEY".to_owned().as_mut_str())); /// ``` + #[inline] #[stable(feature = "option_deref", since = "1.40.0")] #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")] pub const fn as_deref_mut(&mut self) -> Option<&mut T::Target> diff --git a/library/core/src/result.rs b/library/core/src/result.rs index 208b220c24a..c8168c3f358 100644 --- a/library/core/src/result.rs +++ b/library/core/src/result.rs @@ -908,6 +908,7 @@ impl Result { /// let y: Result<&str, &u32> = Err(&42); /// assert_eq!(x.as_deref(), y); /// ``` + #[inline] #[stable(feature = "inner_deref", since = "1.47.0")] pub fn as_deref(&self) -> Result<&T::Target, &E> where @@ -934,6 +935,7 @@ impl Result { /// let y: Result<&mut str, &mut u32> = Err(&mut i); /// assert_eq!(x.as_deref_mut().map(|x| { x.make_ascii_uppercase(); x }), y); /// ``` + #[inline] #[stable(feature = "inner_deref", since = "1.47.0")] pub fn as_deref_mut(&mut self) -> Result<&mut T::Target, &mut E> where From 4d55affc12da448e4a99bf538ccfd66e7ffae5cb Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 20 Mar 2023 19:36:36 +0400 Subject: [PATCH 067/346] rustdoc: Optimize impl sorting during rendering --- src/librustdoc/html/render/print_item.rs | 27 ++++++++++++++++++------ 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 7eb9c0b7cf5..579b5a9c723 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -880,8 +880,8 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean: let (mut synthetic, mut concrete): (Vec<&&Impl>, Vec<&&Impl>) = local.iter().partition(|i| i.inner_impl().kind.is_auto()); - synthetic.sort_by(|a, b| compare_impl(a, b, cx)); - concrete.sort_by(|a, b| compare_impl(a, b, cx)); + synthetic.sort_by_cached_key(|i| ImplString::new(i, cx)); + concrete.sort_by_cached_key(|i| ImplString::new(i, cx)); if !foreign.is_empty() { write_small_section_header(w, "foreign-impls", "Implementations on Foreign Types", ""); @@ -1597,12 +1597,25 @@ where w.write_str(""); } -fn compare_impl<'a, 'b>(lhs: &'a &&Impl, rhs: &'b &&Impl, cx: &Context<'_>) -> Ordering { - let lhss = format!("{}", lhs.inner_impl().print(false, cx)); - let rhss = format!("{}", rhs.inner_impl().print(false, cx)); +#[derive(PartialEq, Eq)] +struct ImplString(String); - // lhs and rhs are formatted as HTML, which may be unnecessary - compare_names(&lhss, &rhss) +impl ImplString { + fn new(i: &Impl, cx: &Context<'_>) -> ImplString { + ImplString(format!("{}", i.inner_impl().print(false, cx))) + } +} + +impl PartialOrd for ImplString { + fn partial_cmp(&self, other: &Self) -> Option { + Some(Ord::cmp(self, other)) + } +} + +impl Ord for ImplString { + fn cmp(&self, other: &Self) -> Ordering { + compare_names(&self.0, &other.0) + } } fn render_implementor( From c513c3b9a5deffac243b7bed3d339bd4e380dc1d Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Mon, 20 Mar 2023 17:42:04 +0000 Subject: [PATCH 068/346] Remove outdated comments --- library/alloc/src/collections/btree/mod.rs | 1 - library/alloc/src/collections/btree/set.rs | 5 ----- library/std/src/collections/hash/set.rs | 7 ------- 3 files changed, 13 deletions(-) diff --git a/library/alloc/src/collections/btree/mod.rs b/library/alloc/src/collections/btree/mod.rs index 7552f2fc04c..c7d0144de30 100644 --- a/library/alloc/src/collections/btree/mod.rs +++ b/library/alloc/src/collections/btree/mod.rs @@ -13,7 +13,6 @@ pub mod set; mod set_val; mod split; -#[doc(hidden)] trait Recover { type Key; diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index 4ddb2119252..4de30d40825 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -1,6 +1,3 @@ -// This is pretty much entirely stolen from TreeSet, since BTreeMap has an identical interface -// to TreeMap - use crate::vec::Vec; use core::borrow::Borrow; use core::cmp::Ordering::{self, Equal, Greater, Less}; @@ -18,8 +15,6 @@ use super::Recover; use crate::alloc::{Allocator, Global}; -// FIXME(conventions): implement bounded iterators - /// An ordered set based on a B-Tree. /// /// See [`BTreeMap`]'s documentation for a detailed discussion of this collection's performance diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs index b59f89d321c..837a18bff60 100644 --- a/library/std/src/collections/hash/set.rs +++ b/library/std/src/collections/hash/set.rs @@ -12,13 +12,6 @@ use crate::ops::{BitAnd, BitOr, BitXor, Sub}; use super::map::{map_try_reserve_error, RandomState}; -// Future Optimization (FIXME!) -// ============================ -// -// Iteration over zero sized values is a noop. There is no need -// for `bucket.val` in the case of HashSet. I suppose we would need HKT -// to get rid of it properly. - /// A [hash set] implemented as a `HashMap` where the value is `()`. /// /// As with the [`HashMap`] type, a `HashSet` requires that the elements From ced33ad289abc621472fb0cdca9d5f09cafdadf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Mon, 13 Mar 2023 20:52:25 +0100 Subject: [PATCH 069/346] Refactor `try_execute_query` --- compiler/rustc_query_system/src/query/job.rs | 2 - .../rustc_query_system/src/query/plumbing.rs | 272 +++++++++--------- 2 files changed, 137 insertions(+), 137 deletions(-) diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs index a5a2f0093ce..c9bc2240c21 100644 --- a/compiler/rustc_query_system/src/query/job.rs +++ b/compiler/rustc_query_system/src/query/job.rs @@ -124,8 +124,6 @@ impl QueryJob { } impl QueryJobId { - #[cold] - #[inline(never)] #[cfg(not(parallel_compiler))] pub(super) fn find_cycle_in_stack( &self, diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index ba2f859ff0f..ac9933582b4 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -6,18 +6,18 @@ use crate::dep_graph::{DepContext, DepKind, DepNode, DepNodeIndex, DepNodeParams use crate::dep_graph::{DepGraphData, HasDepContext}; use crate::ich::StableHashingContext; use crate::query::caches::QueryCache; +#[cfg(parallel_compiler)] +use crate::query::job::QueryLatch; use crate::query::job::{report_cycle, QueryInfo, QueryJob, QueryJobId, QueryJobInfo}; use crate::query::{QueryContext, QueryMap, QuerySideEffects, QueryStackFrame}; use crate::values::Value; use crate::HandleCycleError; use rustc_data_structures::fingerprint::Fingerprint; use rustc_data_structures::fx::FxHashMap; -#[cfg(parallel_compiler)] -use rustc_data_structures::profiling::TimingGuard; -#[cfg(parallel_compiler)] -use rustc_data_structures::sharded::Sharded; use rustc_data_structures::stack::ensure_sufficient_stack; -use rustc_data_structures::sync::{Lock, LockGuard}; +use rustc_data_structures::sync::Lock; +#[cfg(parallel_compiler)] +use rustc_data_structures::{cold_path, sharded::Sharded}; use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed, FatalError}; use rustc_session::Session; use rustc_span::{Span, DUMMY_SP}; @@ -116,7 +116,6 @@ where { state: &'tcx QueryState, key: K, - id: QueryJobId, } #[cold] @@ -166,81 +165,6 @@ impl<'tcx, K, D: DepKind> JobOwner<'tcx, K, D> where K: Eq + Hash + Copy, { - /// Either gets a `JobOwner` corresponding the query, allowing us to - /// start executing the query, or returns with the result of the query. - /// This function assumes that `try_get_cached` is already called and returned `lookup`. - /// If the query is executing elsewhere, this will wait for it and return the result. - /// If the query panicked, this will silently panic. - /// - /// This function is inlined because that results in a noticeable speed-up - /// for some compile-time benchmarks. - #[inline(always)] - fn try_start<'b, Qcx>( - qcx: &'b Qcx, - state: &'b QueryState, - mut state_lock: LockGuard<'b, FxHashMap>>, - span: Span, - key: K, - ) -> TryGetJob<'b, K, D> - where - Qcx: QueryContext + HasDepContext, - { - let lock = &mut *state_lock; - let current_job_id = qcx.current_query_job(); - - match lock.entry(key) { - Entry::Vacant(entry) => { - let id = qcx.next_job_id(); - let job = QueryJob::new(id, span, current_job_id); - - let key = *entry.key(); - entry.insert(QueryResult::Started(job)); - - let owner = JobOwner { state, id, key }; - return TryGetJob::NotYetStarted(owner); - } - Entry::Occupied(mut entry) => { - match entry.get_mut() { - #[cfg(not(parallel_compiler))] - QueryResult::Started(job) => { - let id = job.id; - drop(state_lock); - - // If we are single-threaded we know that we have cycle error, - // so we just return the error. - return TryGetJob::Cycle(id.find_cycle_in_stack( - qcx.try_collect_active_jobs().unwrap(), - ¤t_job_id, - span, - )); - } - #[cfg(parallel_compiler)] - QueryResult::Started(job) => { - // For parallel queries, we'll block and wait until the query running - // in another thread has completed. Record how long we wait in the - // self-profiler. - let query_blocked_prof_timer = qcx.dep_context().profiler().query_blocked(); - - // Get the latch out - let latch = job.latch(); - - drop(state_lock); - - // With parallel queries we might just have to wait on some other - // thread. - let result = latch.wait_on(current_job_id, span); - - match result { - Ok(()) => TryGetJob::JobCompleted(query_blocked_prof_timer), - Err(cycle) => TryGetJob::Cycle(cycle), - } - } - QueryResult::Poisoned => FatalError.raise(), - } - } - } - } - /// Completes the query by updating the query cache with the `result`, /// signals the waiter and forgets the JobOwner, so it won't poison the query fn complete(self, cache: &C, result: C::Value, dep_node_index: DepNodeIndex) @@ -307,25 +231,6 @@ pub(crate) struct CycleError { pub cycle: Vec>, } -/// The result of `try_start`. -enum TryGetJob<'tcx, K, D> -where - K: Eq + Hash + Copy, - D: DepKind, -{ - /// The query is not yet started. Contains a guard to the cache eventually used to start it. - NotYetStarted(JobOwner<'tcx, K, D>), - - /// The query was already completed. - /// Returns the result of the query and its dep-node index - /// if it succeeded or a cycle error if it failed. - #[cfg(parallel_compiler)] - JobCompleted(TimingGuard<'tcx>), - - /// Trying to execute the query resulted in a cycle. - Cycle(CycleError), -} - /// Checks if the query is already computed and in the cache. /// It returns the shard index and a lock guard to the shard, /// which will be used if the query is not in the cache and we need @@ -346,6 +251,65 @@ where } } +#[cold] +#[inline(never)] +#[cfg(not(parallel_compiler))] +fn cycle_error( + query: Q, + qcx: Qcx, + try_execute: QueryJobId, + span: Span, +) -> (Q::Value, Option) +where + Q: QueryConfig, + Qcx: QueryContext, +{ + let error = try_execute.find_cycle_in_stack( + qcx.try_collect_active_jobs().unwrap(), + &qcx.current_query_job(), + span, + ); + (mk_cycle(qcx, error, query.handle_cycle_error()), None) +} + +#[inline(always)] +#[cfg(parallel_compiler)] +fn wait_for_query( + query: Q, + qcx: Qcx, + span: Span, + key: Q::Key, + latch: QueryLatch, + current: Option, +) -> (Q::Value, Option) +where + Q: QueryConfig, + Qcx: QueryContext, +{ + // For parallel queries, we'll block and wait until the query running + // in another thread has completed. Record how long we wait in the + // self-profiler. + let query_blocked_prof_timer = qcx.dep_context().profiler().query_blocked(); + + // With parallel queries we might just have to wait on some other + // thread. + let result = latch.wait_on(current, span); + + match result { + Ok(()) => { + let Some((v, index)) = query.query_cache(qcx).lookup(&key) else { + cold_path(|| panic!("value must be in cache after waiting")) + }; + + qcx.dep_context().profiler().query_cache_hit(index.into()); + query_blocked_prof_timer.finish_with_query_invocation_id(index.into()); + + (v, Some(index)) + } + Err(cycle) => (mk_cycle(qcx, cycle, query.handle_cycle_error()), None), + } +} + #[inline(never)] fn try_execute_query( query: Q, @@ -360,9 +324,9 @@ where { let state = query.query_state(qcx); #[cfg(parallel_compiler)] - let state_lock = state.active.get_shard_by_value(&key).lock(); + let mut state_lock = state.active.get_shard_by_value(&key).lock(); #[cfg(not(parallel_compiler))] - let state_lock = state.active.lock(); + let mut state_lock = state.active.lock(); // For the parallel compiler we need to check both the query cache and query state structures // while holding the state lock to ensure that 1) the query has not yet completed and 2) the @@ -377,46 +341,84 @@ where } } - match JobOwner::<'_, Q::Key, Qcx::DepKind>::try_start(&qcx, state, state_lock, span, key) { - TryGetJob::NotYetStarted(job) => { - let (result, dep_node_index) = match qcx.dep_context().dep_graph().data() { - None => execute_job_non_incr(query, qcx, key, job.id), - Some(data) => execute_job_incr(query, qcx, data, key, dep_node, job.id), - }; + let current_job_id = qcx.current_query_job(); - let cache = query.query_cache(qcx); - if query.feedable() { - // We should not compute queries that also got a value via feeding. - // This can't happen, as query feeding adds the very dependencies to the fed query - // as its feeding query had. So if the fed query is red, so is its feeder, which will - // get evaluated first, and re-feed the query. - if let Some((cached_result, _)) = cache.lookup(&key) { - panic!( - "fed query later has its value computed. The already cached value: {cached_result:?}" - ); + match state_lock.entry(key) { + Entry::Vacant(entry) => { + // Nothing has computed or is computing the query, so we start a new job and insert it in the + // state map. + let id = qcx.next_job_id(); + let job = QueryJob::new(id, span, current_job_id); + entry.insert(QueryResult::Started(job)); + + // Drop the lock before we start executing the query + drop(state_lock); + + execute_job(query, qcx, state, key, id, dep_node) + } + Entry::Occupied(mut entry) => { + match entry.get_mut() { + #[cfg(not(parallel_compiler))] + QueryResult::Started(job) => { + let id = job.id; + drop(state_lock); + + // If we are single-threaded we know that we have cycle error, + // so we just return the error. + cycle_error(query, qcx, id, span) } + #[cfg(parallel_compiler)] + QueryResult::Started(job) => { + // Get the latch out + let latch = job.latch(); + drop(state_lock); + + wait_for_query(query, qcx, span, key, latch, current_job_id) + } + QueryResult::Poisoned => FatalError.raise(), } - job.complete(cache, result, dep_node_index); - (result, Some(dep_node_index)) - } - TryGetJob::Cycle(error) => { - let result = mk_cycle(qcx, error, query.handle_cycle_error()); - (result, None) - } - #[cfg(parallel_compiler)] - TryGetJob::JobCompleted(query_blocked_prof_timer) => { - let Some((v, index)) = query.query_cache(qcx).lookup(&key) else { - panic!("value must be in cache after waiting") - }; - - qcx.dep_context().profiler().query_cache_hit(index.into()); - query_blocked_prof_timer.finish_with_query_invocation_id(index.into()); - - (v, Some(index)) } } } +#[inline(always)] +fn execute_job( + query: Q, + qcx: Qcx, + state: &QueryState, + key: Q::Key, + id: QueryJobId, + dep_node: Option>, +) -> (Q::Value, Option) +where + Q: QueryConfig, + Qcx: QueryContext, +{ + // Use `JobOwner` so the query will be poisoned if executing it panics. + let job_owner = JobOwner { state, key }; + + let (result, dep_node_index) = match qcx.dep_context().dep_graph().data() { + None => execute_job_non_incr(query, qcx, key, id), + Some(data) => execute_job_incr(query, qcx, data, key, dep_node, id), + }; + + let cache = query.query_cache(qcx); + if query.feedable() { + // We should not compute queries that also got a value via feeding. + // This can't happen, as query feeding adds the very dependencies to the fed query + // as its feeding query had. So if the fed query is red, so is its feeder, which will + // get evaluated first, and re-feed the query. + if let Some((cached_result, _)) = cache.lookup(&key) { + panic!( + "fed query later has its value computed. The already cached value: {cached_result:?}" + ); + } + } + job_owner.complete(cache, result, dep_node_index); + + (result, Some(dep_node_index)) +} + // Fast path for when incr. comp. is off. #[inline(always)] fn execute_job_non_incr( From 8126ccb77d5d7edd242a9f9566364b70f0a7b0a6 Mon Sep 17 00:00:00 2001 From: yukang Date: Tue, 21 Mar 2023 15:27:08 +0800 Subject: [PATCH 070/346] Return equal for two identical projections --- compiler/rustc_hir_typeck/src/upvar.rs | 6 ++---- tests/ui/closures/issue-109188.rs | 22 ++++++++++++++++++++++ tests/ui/closures/issue-109188.stderr | 19 +++++++++++++++++++ 3 files changed, 43 insertions(+), 4 deletions(-) create mode 100644 tests/ui/closures/issue-109188.rs create mode 100644 tests/ui/closures/issue-109188.stderr diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 4a432328c4d..90947912a19 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -712,10 +712,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - unreachable!( - "we captured two identical projections: capture1 = {:?}, capture2 = {:?}", - capture1, capture2 - ); + // return Equal for two identical projections + std::cmp::Ordering::Equal }); } diff --git a/tests/ui/closures/issue-109188.rs b/tests/ui/closures/issue-109188.rs new file mode 100644 index 00000000000..cae1ced9958 --- /dev/null +++ b/tests/ui/closures/issue-109188.rs @@ -0,0 +1,22 @@ +enum Either { + One(X), + Two(X), +} + +struct X(Y); + +struct Y; + +fn consume_fnmut(f: &dyn FnMut()) { + f(); +} + +fn move_into_fnmut() { + let x = move_into_fnmut(); + consume_fnmut(&|| { + let Either::One(_t) = x; //~ ERROR mismatched types + let Either::Two(_t) = x; //~ ERROR mismatched types + }); +} + +fn main() { } diff --git a/tests/ui/closures/issue-109188.stderr b/tests/ui/closures/issue-109188.stderr new file mode 100644 index 00000000000..d52b516294f --- /dev/null +++ b/tests/ui/closures/issue-109188.stderr @@ -0,0 +1,19 @@ +error[E0308]: mismatched types + --> $DIR/issue-109188.rs:17:13 + | +LL | let Either::One(_t) = x; + | ^^^^^^^^^^^^^^^ - this expression has type `()` + | | + | expected `()`, found `Either` + +error[E0308]: mismatched types + --> $DIR/issue-109188.rs:18:13 + | +LL | let Either::Two(_t) = x; + | ^^^^^^^^^^^^^^^ - this expression has type `()` + | | + | expected `()`, found `Either` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. From 5810f1fe3c74e62bbbc32a31b90f7ec48f14bc27 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 14 Mar 2023 14:19:06 +0100 Subject: [PATCH 071/346] remove some trait solver helpers they add more complexity then they are worth. It's confusing which of these helpers should be used in which context. --- clippy_lints/src/future_not_send.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/clippy_lints/src/future_not_send.rs b/clippy_lints/src/future_not_send.rs index 9fb73a371b8..ed0bd58c770 100644 --- a/clippy_lints/src/future_not_send.rs +++ b/clippy_lints/src/future_not_send.rs @@ -9,7 +9,7 @@ use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::def_id::LocalDefId; use rustc_span::{sym, Span}; use rustc_trait_selection::traits::error_reporting::suggestions::TypeErrCtxtExt; -use rustc_trait_selection::traits::{self, FulfillmentError}; +use rustc_trait_selection::traits::{self, FulfillmentError, ObligationCtxt}; declare_clippy_lint! { /// ### What it does @@ -79,8 +79,10 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend { let send_trait = cx.tcx.get_diagnostic_item(sym::Send).unwrap(); let span = decl.output.span(); let infcx = cx.tcx.infer_ctxt().build(); + let ocx = ObligationCtxt::new(&infcx); let cause = traits::ObligationCause::misc(span, fn_def_id); - let send_errors = traits::fully_solve_bound(&infcx, cause, cx.param_env, ret_ty, send_trait); + ocx.register_bound(cause, cx.param_env, ret_ty, send_trait); + let send_errors = ocx.select_all_or_error(); if !send_errors.is_empty() { span_lint_and_then( cx, From 54f55efb9a147e8a7b5073d24c0cc67f0aad5a13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gammels=C3=A6ter?= Date: Tue, 21 Mar 2023 09:59:47 +0100 Subject: [PATCH 072/346] Use hex literal for INDEX_MASK --- library/core/src/unicode/unicode_data.rs | 2 +- src/tools/unicode-table-generator/src/case_mapping.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/unicode/unicode_data.rs b/library/core/src/unicode/unicode_data.rs index 091259e4d38..b25e9df2868 100644 --- a/library/core/src/unicode/unicode_data.rs +++ b/library/core/src/unicode/unicode_data.rs @@ -580,7 +580,7 @@ pub mod white_space { #[rustfmt::skip] pub mod conversions { - const INDEX_MASK: u32 = 4194304; + const INDEX_MASK: u32 = 0x400000; pub fn to_lower(c: char) -> [char; 3] { if c.is_ascii() { diff --git a/src/tools/unicode-table-generator/src/case_mapping.rs b/src/tools/unicode-table-generator/src/case_mapping.rs index 58d9959ca7b..7a978db62b4 100644 --- a/src/tools/unicode-table-generator/src/case_mapping.rs +++ b/src/tools/unicode-table-generator/src/case_mapping.rs @@ -10,7 +10,7 @@ const INDEX_MASK: u32 = 1 << 22; pub(crate) fn generate_case_mapping(data: &UnicodeData) -> String { let mut file = String::new(); - write!(file, "const INDEX_MASK: u32 = {};", INDEX_MASK).unwrap(); + write!(file, "const INDEX_MASK: u32 = 0x{:x};", INDEX_MASK).unwrap(); file.push_str("\n\n"); file.push_str(HEADER.trim_start()); file.push('\n'); From 7bffe945af456df6ad3294bdf82a67d727880adc Mon Sep 17 00:00:00 2001 From: yukang Date: Tue, 21 Mar 2023 20:05:34 +0800 Subject: [PATCH 073/346] add delay_span_bug --- compiler/rustc_hir_typeck/src/upvar.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 90947912a19..4847bddc38d 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -712,7 +712,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - // return Equal for two identical projections + self.tcx.sess.delay_span_bug( + closure_span, + &format!( + "two identical projections: ({:?}, {:?})", + capture1.place.projections, capture2.place.projections + ), + ); std::cmp::Ordering::Equal }); } From 6f62887968779b050d44d4029254187d8936cd3c Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 13 Mar 2023 18:54:05 +0000 Subject: [PATCH 074/346] Use local key in providers --- clippy_lints/src/cognitive_complexity.rs | 2 +- clippy_lints/src/derivable_impls.rs | 2 +- clippy_lints/src/derive.rs | 2 +- clippy_lints/src/functions/must_use.rs | 6 +++--- clippy_lints/src/partialeq_ne_impl.rs | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/clippy_lints/src/cognitive_complexity.rs b/clippy_lints/src/cognitive_complexity.rs index e8531157e0f..a8926b29ac8 100644 --- a/clippy_lints/src/cognitive_complexity.rs +++ b/clippy_lints/src/cognitive_complexity.rs @@ -143,7 +143,7 @@ impl<'tcx> LateLintPass<'tcx> for CognitiveComplexity { span: Span, def_id: LocalDefId, ) { - if !cx.tcx.has_attr(def_id.to_def_id(), sym::test) { + if !cx.tcx.has_attr(def_id, sym::test) { let expr = if is_async_fn(kind) { match get_async_fn_body(cx.tcx, body) { Some(b) => b, diff --git a/clippy_lints/src/derivable_impls.rs b/clippy_lints/src/derivable_impls.rs index 8a5a28c6b3d..8f68f90a2a1 100644 --- a/clippy_lints/src/derivable_impls.rs +++ b/clippy_lints/src/derivable_impls.rs @@ -181,7 +181,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls { self_ty, .. }) = item.kind; - if !cx.tcx.has_attr(item.owner_id.to_def_id(), sym::automatically_derived); + if !cx.tcx.has_attr(item.owner_id, sym::automatically_derived); if !item.span.from_expansion(); if let Some(def_id) = trait_ref.trait_def_id(); if cx.tcx.is_diagnostic_item(sym::Default, def_id); diff --git a/clippy_lints/src/derive.rs b/clippy_lints/src/derive.rs index b8428d66a5d..715348e869e 100644 --- a/clippy_lints/src/derive.rs +++ b/clippy_lints/src/derive.rs @@ -212,7 +212,7 @@ impl<'tcx> LateLintPass<'tcx> for Derive { }) = item.kind { let ty = cx.tcx.type_of(item.owner_id).subst_identity(); - let is_automatically_derived = cx.tcx.has_attr(item.owner_id.to_def_id(), sym::automatically_derived); + let is_automatically_derived = cx.tcx.has_attr(item.owner_id, sym::automatically_derived); check_hash_peq(cx, item.span, trait_ref, ty, is_automatically_derived); check_ord_partial_ord(cx, item.span, trait_ref, ty, is_automatically_derived); diff --git a/clippy_lints/src/functions/must_use.rs b/clippy_lints/src/functions/must_use.rs index 29bdc46b647..eacbf6c6ec9 100644 --- a/clippy_lints/src/functions/must_use.rs +++ b/clippy_lints/src/functions/must_use.rs @@ -22,7 +22,7 @@ use super::{DOUBLE_MUST_USE, MUST_USE_CANDIDATE, MUST_USE_UNIT}; pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_>) { let attrs = cx.tcx.hir().attrs(item.hir_id()); - let attr = cx.tcx.get_attr(item.owner_id.to_def_id(), sym::must_use); + let attr = cx.tcx.get_attr(item.owner_id, sym::must_use); if let hir::ItemKind::Fn(ref sig, _generics, ref body_id) = item.kind { let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id); let fn_header_span = item.span.with_hi(sig.decl.output.span().hi()); @@ -47,7 +47,7 @@ pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Imp let is_public = cx.effective_visibilities.is_exported(item.owner_id.def_id); let fn_header_span = item.span.with_hi(sig.decl.output.span().hi()); let attrs = cx.tcx.hir().attrs(item.hir_id()); - let attr = cx.tcx.get_attr(item.owner_id.to_def_id(), sym::must_use); + let attr = cx.tcx.get_attr(item.owner_id, sym::must_use); if let Some(attr) = attr { check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr); } else if is_public @@ -73,7 +73,7 @@ pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Tr let fn_header_span = item.span.with_hi(sig.decl.output.span().hi()); let attrs = cx.tcx.hir().attrs(item.hir_id()); - let attr = cx.tcx.get_attr(item.owner_id.to_def_id(), sym::must_use); + let attr = cx.tcx.get_attr(item.owner_id, sym::must_use); if let Some(attr) = attr { check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr); } else if let hir::TraitFn::Provided(eid) = *eid { diff --git a/clippy_lints/src/partialeq_ne_impl.rs b/clippy_lints/src/partialeq_ne_impl.rs index 5aa3c6f2f93..a8c4823fe53 100644 --- a/clippy_lints/src/partialeq_ne_impl.rs +++ b/clippy_lints/src/partialeq_ne_impl.rs @@ -36,7 +36,7 @@ impl<'tcx> LateLintPass<'tcx> for PartialEqNeImpl { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) { if_chain! { if let ItemKind::Impl(Impl { of_trait: Some(ref trait_ref), items: impl_items, .. }) = item.kind; - if !cx.tcx.has_attr(item.owner_id.to_def_id(), sym::automatically_derived); + if !cx.tcx.has_attr(item.owner_id, sym::automatically_derived); if let Some(eq_trait) = cx.tcx.lang_items().eq_trait(); if trait_ref.path.res.def_id() == eq_trait; then { From 84b6049eb9502cd9ba2f1518c26b6525b2fb2752 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Sat, 18 Mar 2023 23:22:04 +0100 Subject: [PATCH 075/346] Use uninit checking from rustc rustc has proper heuristics for actually checking whether a type allows being left uninitialized (by asking CTFE). We can now use this for our helper instead of rolling our own bad version with false positives. --- clippy_utils/src/ty.rs | 19 +++++++++---------- tests/ui/uninit.rs | 23 +++++++++++++++++++---- tests/ui/uninit.stderr | 16 ++++++++-------- tests/ui/uninit_vec.rs | 27 +++++++++++++++++++++++++++ tests/ui/uninit_vec.stderr | 33 ++++++++++++++++++++++----------- 5 files changed, 85 insertions(+), 33 deletions(-) diff --git a/clippy_utils/src/ty.rs b/clippy_utils/src/ty.rs index f1c6f1dddd8..0b47234647f 100644 --- a/clippy_utils/src/ty.rs +++ b/clippy_utils/src/ty.rs @@ -16,9 +16,9 @@ use rustc_infer::infer::{ use rustc_lint::LateContext; use rustc_middle::mir::interpret::{ConstValue, Scalar}; use rustc_middle::ty::{ - self, AdtDef, AliasTy, AssocKind, Binder, BoundRegion, FnSig, IntTy, List, ParamEnv, Predicate, PredicateKind, - Region, RegionKind, SubstsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, - UintTy, VariantDef, VariantDiscr, + self, layout::ValidityRequirement, AdtDef, AliasTy, AssocKind, Binder, BoundRegion, FnSig, IntTy, List, ParamEnv, + Predicate, PredicateKind, Region, RegionKind, SubstsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, + TypeVisitableExt, TypeVisitor, UintTy, VariantDef, VariantDiscr, }; use rustc_middle::ty::{GenericArg, GenericArgKind}; use rustc_span::symbol::Ident; @@ -538,13 +538,12 @@ pub fn same_type_and_consts<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool { } /// Checks if a given type looks safe to be uninitialized. -pub fn is_uninit_value_valid_for_ty(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { - match *ty.kind() { - ty::Array(component, _) => is_uninit_value_valid_for_ty(cx, component), - ty::Tuple(types) => types.iter().all(|ty| is_uninit_value_valid_for_ty(cx, ty)), - ty::Adt(adt, _) => cx.tcx.lang_items().maybe_uninit() == Some(adt.did()), - _ => false, - } +pub fn is_uninit_value_valid_for_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { + cx.tcx + .check_validity_requirement((ValidityRequirement::Uninit, cx.param_env.and(ty))) + // For types containing generic parameters we cannot get a layout to check. + // Therefore, we are conservative and assume that they don't allow uninit. + .unwrap_or(false) } /// Gets an iterator over all predicates which apply to the given item. diff --git a/tests/ui/uninit.rs b/tests/ui/uninit.rs index 21131731708..412b36b4ee8 100644 --- a/tests/ui/uninit.rs +++ b/tests/ui/uninit.rs @@ -3,13 +3,15 @@ use std::mem::{self, MaybeUninit}; +union MyOwnMaybeUninit { + value: u8, + uninit: (), +} + fn main() { let _: usize = unsafe { MaybeUninit::uninit().assume_init() }; - // edge case: For now we lint on empty arrays - let _: [u8; 0] = unsafe { MaybeUninit::uninit().assume_init() }; - - // edge case: For now we accept unit tuples + // This is OK, because ZSTs do not contain data. let _: () = unsafe { MaybeUninit::uninit().assume_init() }; // This is OK, because `MaybeUninit` allows uninitialized data. @@ -21,6 +23,19 @@ fn main() { // This is OK, because all constitutent types are uninit-compatible. let _: (MaybeUninit, [MaybeUninit; 2]) = unsafe { MaybeUninit::uninit().assume_init() }; + // This is OK, because our own MaybeUninit is just as fine as the one from core. + let _: MyOwnMaybeUninit = unsafe { MaybeUninit::uninit().assume_init() }; + + // This is OK, because empty arrays don't contain data. + let _: [u8; 0] = unsafe { MaybeUninit::uninit().assume_init() }; + // Was a false negative. let _: usize = unsafe { mem::MaybeUninit::uninit().assume_init() }; + + polymorphic::<()>(); + + fn polymorphic() { + // We are conservative around polymorphic types. + let _: T = unsafe { mem::MaybeUninit::uninit().assume_init() }; + } } diff --git a/tests/ui/uninit.stderr b/tests/ui/uninit.stderr index 15ef2349489..9e01b9a4aa8 100644 --- a/tests/ui/uninit.stderr +++ b/tests/ui/uninit.stderr @@ -1,5 +1,5 @@ error: this call for this type may be undefined behavior - --> $DIR/uninit.rs:7:29 + --> $DIR/uninit.rs:12:29 | LL | let _: usize = unsafe { MaybeUninit::uninit().assume_init() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -7,16 +7,16 @@ LL | let _: usize = unsafe { MaybeUninit::uninit().assume_init() }; = note: `#[deny(clippy::uninit_assumed_init)]` on by default error: this call for this type may be undefined behavior - --> $DIR/uninit.rs:10:31 - | -LL | let _: [u8; 0] = unsafe { MaybeUninit::uninit().assume_init() }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: this call for this type may be undefined behavior - --> $DIR/uninit.rs:25:29 + --> $DIR/uninit.rs:33:29 | LL | let _: usize = unsafe { mem::MaybeUninit::uninit().assume_init() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +error: this call for this type may be undefined behavior + --> $DIR/uninit.rs:39:29 + | +LL | let _: T = unsafe { mem::MaybeUninit::uninit().assume_init() }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: aborting due to 3 previous errors diff --git a/tests/ui/uninit_vec.rs b/tests/ui/uninit_vec.rs index 194e4fc157e..59ec64a7ab1 100644 --- a/tests/ui/uninit_vec.rs +++ b/tests/ui/uninit_vec.rs @@ -7,6 +7,11 @@ struct MyVec { vec: Vec, } +union MyOwnMaybeUninit { + value: u8, + uninit: (), +} + fn main() { // with_capacity() -> set_len() should be detected let mut vec: Vec = Vec::with_capacity(1000); @@ -97,4 +102,26 @@ fn main() { unsafe { vec.set_len(0); } + + // ZSTs should not be detected + let mut vec: Vec<()> = Vec::with_capacity(1000); + unsafe { + vec.set_len(10); + } + + // unions should not be detected + let mut vec: Vec = Vec::with_capacity(1000); + unsafe { + vec.set_len(10); + } + + polymorphic::<()>(); + + fn polymorphic() { + // We are conservative around polymorphic types. + let mut vec: Vec = Vec::with_capacity(1000); + unsafe { + vec.set_len(10); + } + } } diff --git a/tests/ui/uninit_vec.stderr b/tests/ui/uninit_vec.stderr index 77fc689f076..9cdf0c95ad9 100644 --- a/tests/ui/uninit_vec.stderr +++ b/tests/ui/uninit_vec.stderr @@ -1,5 +1,5 @@ error: calling `set_len()` immediately after reserving a buffer creates uninitialized values - --> $DIR/uninit_vec.rs:12:5 + --> $DIR/uninit_vec.rs:17:5 | LL | let mut vec: Vec = Vec::with_capacity(1000); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -11,7 +11,7 @@ LL | vec.set_len(200); = note: `-D clippy::uninit-vec` implied by `-D warnings` error: calling `set_len()` immediately after reserving a buffer creates uninitialized values - --> $DIR/uninit_vec.rs:18:5 + --> $DIR/uninit_vec.rs:23:5 | LL | vec.reserve(1000); | ^^^^^^^^^^^^^^^^^^ @@ -22,7 +22,7 @@ LL | vec.set_len(200); = help: initialize the buffer or wrap the content in `MaybeUninit` error: calling `set_len()` on empty `Vec` creates out-of-bound values - --> $DIR/uninit_vec.rs:24:5 + --> $DIR/uninit_vec.rs:29:5 | LL | let mut vec: Vec = Vec::new(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -31,7 +31,7 @@ LL | vec.set_len(200); | ^^^^^^^^^^^^^^^^ error: calling `set_len()` on empty `Vec` creates out-of-bound values - --> $DIR/uninit_vec.rs:30:5 + --> $DIR/uninit_vec.rs:35:5 | LL | let mut vec: Vec = Default::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -40,7 +40,7 @@ LL | vec.set_len(200); | ^^^^^^^^^^^^^^^^ error: calling `set_len()` on empty `Vec` creates out-of-bound values - --> $DIR/uninit_vec.rs:35:5 + --> $DIR/uninit_vec.rs:40:5 | LL | let mut vec: Vec = Vec::default(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -49,7 +49,7 @@ LL | vec.set_len(200); | ^^^^^^^^^^^^^^^^ error: calling `set_len()` immediately after reserving a buffer creates uninitialized values - --> $DIR/uninit_vec.rs:49:5 + --> $DIR/uninit_vec.rs:54:5 | LL | let mut vec: Vec = Vec::with_capacity(1000); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -60,7 +60,7 @@ LL | vec.set_len(200); = help: initialize the buffer or wrap the content in `MaybeUninit` error: calling `set_len()` immediately after reserving a buffer creates uninitialized values - --> $DIR/uninit_vec.rs:58:5 + --> $DIR/uninit_vec.rs:63:5 | LL | my_vec.vec.reserve(1000); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -71,7 +71,7 @@ LL | my_vec.vec.set_len(200); = help: initialize the buffer or wrap the content in `MaybeUninit` error: calling `set_len()` immediately after reserving a buffer creates uninitialized values - --> $DIR/uninit_vec.rs:63:5 + --> $DIR/uninit_vec.rs:68:5 | LL | my_vec.vec = Vec::with_capacity(1000); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -82,7 +82,7 @@ LL | my_vec.vec.set_len(200); = help: initialize the buffer or wrap the content in `MaybeUninit` error: calling `set_len()` immediately after reserving a buffer creates uninitialized values - --> $DIR/uninit_vec.rs:42:9 + --> $DIR/uninit_vec.rs:47:9 | LL | let mut vec: Vec = Vec::with_capacity(1000); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -92,7 +92,7 @@ LL | vec.set_len(200); = help: initialize the buffer or wrap the content in `MaybeUninit` error: calling `set_len()` immediately after reserving a buffer creates uninitialized values - --> $DIR/uninit_vec.rs:45:9 + --> $DIR/uninit_vec.rs:50:9 | LL | vec.reserve(1000); | ^^^^^^^^^^^^^^^^^^ @@ -101,5 +101,16 @@ LL | vec.set_len(200); | = help: initialize the buffer or wrap the content in `MaybeUninit` -error: aborting due to 10 previous errors +error: calling `set_len()` immediately after reserving a buffer creates uninitialized values + --> $DIR/uninit_vec.rs:122:9 + | +LL | let mut vec: Vec = Vec::with_capacity(1000); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | unsafe { +LL | vec.set_len(10); + | ^^^^^^^^^^^^^^^ + | + = help: initialize the buffer or wrap the content in `MaybeUninit` + +error: aborting due to 11 previous errors From 728ee6f8cdddd9bc7deda8271419c7cedfdf518a Mon Sep 17 00:00:00 2001 From: "Samuel \"Sam\" Tardieu" Date: Tue, 21 Mar 2023 20:18:47 +0100 Subject: [PATCH 076/346] Really dogfood clippy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The dogfood success condition was inverted in `tests/dogfood.rs`: ```rust assert!(!failed_packages.is_empty(), …); ``` while instead the `failed_packages` collection must be empty: ```rust assert!(failed_packages.is_empty(), …); ``` And indeed, several clippy lint source files were not clean and had to be fixed in the process. --- clippy_lints/src/let_with_type_underscore.rs | 2 +- clippy_lints/src/manual_async_fn.rs | 7 ++++--- clippy_lints/src/manual_main_separator_str.rs | 4 +++- clippy_lints/src/redundant_async_block.rs | 2 +- clippy_lints/src/swap.rs | 4 ++-- clippy_lints/src/wildcard_imports.rs | 8 +++----- tests/dogfood.rs | 4 ++-- 7 files changed, 16 insertions(+), 15 deletions(-) diff --git a/clippy_lints/src/let_with_type_underscore.rs b/clippy_lints/src/let_with_type_underscore.rs index ba51973f2f9..c01e3882d52 100644 --- a/clippy_lints/src/let_with_type_underscore.rs +++ b/clippy_lints/src/let_with_type_underscore.rs @@ -1,5 +1,5 @@ use clippy_utils::diagnostics::span_lint_and_help; -use rustc_hir::*; +use rustc_hir::{Local, TyKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::lint::in_external_macro; use rustc_session::{declare_lint_pass, declare_tool_lint}; diff --git a/clippy_lints/src/manual_async_fn.rs b/clippy_lints/src/manual_async_fn.rs index af52090d8a4..c7254b32d0b 100644 --- a/clippy_lints/src/manual_async_fn.rs +++ b/clippy_lints/src/manual_async_fn.rs @@ -77,11 +77,12 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn { if let Some(ret_pos) = position_before_rarrow(&header_snip); if let Some((ret_sugg, ret_snip)) = suggested_ret(cx, output); then { - let header_snip = if !vis_snip.is_empty() { - format!("{} async {}", vis_snip, &header_snip[vis_snip.len() + 1..ret_pos]) - } else { + let header_snip = if vis_snip.is_empty() { format!("async {}", &header_snip[..ret_pos]) + } else { + format!("{} async {}", vis_snip, &header_snip[vis_snip.len() + 1..ret_pos]) }; + let help = format!("make the function `async` and {ret_sugg}"); diag.span_suggestion( header_span, diff --git a/clippy_lints/src/manual_main_separator_str.rs b/clippy_lints/src/manual_main_separator_str.rs index a6d318f952c..c292bbe4e93 100644 --- a/clippy_lints/src/manual_main_separator_str.rs +++ b/clippy_lints/src/manual_main_separator_str.rs @@ -3,7 +3,7 @@ use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::{is_trait_method, match_def_path, paths, peel_hir_expr_refs}; use rustc_errors::Applicability; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::*; +use rustc_hir::{Expr, ExprKind, Mutability, QPath}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty; use rustc_session::{declare_tool_lint, impl_lint_pass}; @@ -69,4 +69,6 @@ impl LateLintPass<'_> for ManualMainSeparatorStr { ); } } + + extract_msrv_attr!(LateContext); } diff --git a/clippy_lints/src/redundant_async_block.rs b/clippy_lints/src/redundant_async_block.rs index 27ad4308637..b2adbcead00 100644 --- a/clippy_lints/src/redundant_async_block.rs +++ b/clippy_lints/src/redundant_async_block.rs @@ -1,5 +1,5 @@ use clippy_utils::{diagnostics::span_lint_and_sugg, source::snippet}; -use rustc_ast::ast::*; +use rustc_ast::ast::{Expr, ExprKind, Stmt, StmtKind}; use rustc_ast::visit::Visitor as AstVisitor; use rustc_errors::Applicability; use rustc_lint::{EarlyContext, EarlyLintPass}; diff --git a/clippy_lints/src/swap.rs b/clippy_lints/src/swap.rs index 50298898d03..f7eef03d1d4 100644 --- a/clippy_lints/src/swap.rs +++ b/clippy_lints/src/swap.rs @@ -189,7 +189,7 @@ fn check_suspicious_swap(cx: &LateContext<'_>, block: &Block<'_>) { if let Some((lhs0, rhs0)) = parse(first) && let Some((lhs1, rhs1)) = parse(second) && first.span.eq_ctxt(second.span) - && !in_external_macro(&cx.sess(), first.span) + && !in_external_macro(cx.sess(), first.span) && is_same(cx, lhs0, rhs1) && is_same(cx, lhs1, rhs0) && !is_same(cx, lhs1, rhs1) // Ignore a = b; a = a (#10421) @@ -260,8 +260,8 @@ fn parse<'a, 'hir>(stmt: &'a Stmt<'hir>) -> Option<(ExprOrIdent<'hir>, &'a Expr< /// Implementation of the xor case for `MANUAL_SWAP` lint. fn check_xor_swap(cx: &LateContext<'_>, block: &Block<'_>) { for [s1, s2, s3] in block.stmts.array_windows::<3>() { + let ctxt = s1.span.ctxt(); if_chain! { - let ctxt = s1.span.ctxt(); if let Some((lhs0, rhs0)) = extract_sides_of_xor_assign(s1, ctxt); if let Some((lhs1, rhs1)) = extract_sides_of_xor_assign(s2, ctxt); if let Some((lhs2, rhs2)) = extract_sides_of_xor_assign(s3, ctxt); diff --git a/clippy_lints/src/wildcard_imports.rs b/clippy_lints/src/wildcard_imports.rs index e105452e1c5..36f910c983f 100644 --- a/clippy_lints/src/wildcard_imports.rs +++ b/clippy_lints/src/wildcard_imports.rs @@ -158,12 +158,10 @@ impl LateLintPass<'_> for WildcardImports { let mut imports = used_imports.items().map(ToString::to_string).into_sorted_stable_ord(false); let imports_string = if imports.len() == 1 { imports.pop().unwrap() + } else if braced_glob { + imports.join(", ") } else { - if braced_glob { - imports.join(", ") - } else { - format!("{{{}}}", imports.join(", ")) - } + format!("{{{}}}", imports.join(", ")) }; let sugg = if braced_glob { diff --git a/tests/dogfood.rs b/tests/dogfood.rs index 9643c2c9707..3a5d478fa31 100644 --- a/tests/dogfood.rs +++ b/tests/dogfood.rs @@ -37,10 +37,10 @@ fn dogfood_clippy() { } assert!( - !failed_packages.is_empty(), + failed_packages.is_empty(), "Dogfood failed for packages `{}`", failed_packages.iter().format(", "), - ) + ); } #[test] From 29c11327c703f59ad39d5840768864106b7c27b7 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Tue, 21 Mar 2023 22:17:15 +0100 Subject: [PATCH 077/346] Use `SmallVec` in bitsets This doesn't increase their size and means that we don't have to heap allocate for small sets. --- compiler/rustc_index/src/bit_set.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs index cbf169afb18..eba5b3ed882 100644 --- a/compiler/rustc_index/src/bit_set.rs +++ b/compiler/rustc_index/src/bit_set.rs @@ -1,5 +1,6 @@ use crate::vec::{Idx, IndexVec}; use arrayvec::ArrayVec; +use smallvec::{smallvec, SmallVec}; use std::fmt; use std::iter; use std::marker::PhantomData; @@ -111,7 +112,7 @@ macro_rules! bit_relations_inherent_impls { #[derive(Eq, PartialEq, Hash, Decodable, Encodable)] pub struct BitSet { domain_size: usize, - words: Vec, + words: SmallVec<[Word; 2]>, marker: PhantomData, } @@ -127,14 +128,15 @@ impl BitSet { #[inline] pub fn new_empty(domain_size: usize) -> BitSet { let num_words = num_words(domain_size); - BitSet { domain_size, words: vec![0; num_words], marker: PhantomData } + BitSet { domain_size, words: smallvec![0; num_words], marker: PhantomData } } /// Creates a new, filled bitset with a given `domain_size`. #[inline] pub fn new_filled(domain_size: usize) -> BitSet { let num_words = num_words(domain_size); - let mut result = BitSet { domain_size, words: vec![!0; num_words], marker: PhantomData }; + let mut result = + BitSet { domain_size, words: smallvec![!0; num_words], marker: PhantomData }; result.clear_excess_bits(); result } @@ -1571,7 +1573,7 @@ impl From> for GrowableBitSet { pub struct BitMatrix { num_rows: usize, num_columns: usize, - words: Vec, + words: SmallVec<[Word; 2]>, marker: PhantomData<(R, C)>, } @@ -1584,7 +1586,7 @@ impl BitMatrix { BitMatrix { num_rows, num_columns, - words: vec![0; num_rows * words_per_row], + words: smallvec![0; num_rows * words_per_row], marker: PhantomData, } } From 349708655ea924bb34861025e3ee6d99d58e3f8d Mon Sep 17 00:00:00 2001 From: "Samuel \"Sam\" Tardieu" Date: Sun, 12 Mar 2023 14:06:13 +0100 Subject: [PATCH 078/346] Do not propose to remove `async move` if variables are captured by ref --- clippy_lints/src/redundant_async_block.rs | 37 +++++++++++++++++- tests/ui/redundant_async_block.fixed | 47 +++++++++++++++++++++++ tests/ui/redundant_async_block.rs | 47 +++++++++++++++++++++++ tests/ui/redundant_async_block.stderr | 22 ++++++++--- 4 files changed, 147 insertions(+), 6 deletions(-) diff --git a/clippy_lints/src/redundant_async_block.rs b/clippy_lints/src/redundant_async_block.rs index 27ad4308637..24dcd52b93e 100644 --- a/clippy_lints/src/redundant_async_block.rs +++ b/clippy_lints/src/redundant_async_block.rs @@ -32,7 +32,7 @@ declare_clippy_lint! { /// ``` #[clippy::version = "1.69.0"] pub REDUNDANT_ASYNC_BLOCK, - complexity, + nursery, "`async { future.await }` can be replaced by `future`" } declare_lint_pass!(RedundantAsyncBlock => [REDUNDANT_ASYNC_BLOCK]); @@ -48,6 +48,11 @@ impl EarlyLintPass for RedundantAsyncBlock { !future.span.from_expansion() && !await_in_expr(future) { + if captures_value(last) { + // If the async block captures variables then there is no equivalence. + return; + } + span_lint_and_sugg( cx, REDUNDANT_ASYNC_BLOCK, @@ -82,3 +87,33 @@ impl<'ast> AstVisitor<'ast> for AwaitDetector { } } } + +/// Check whether an expression may have captured a local variable. +/// This is done by looking for paths with only one segment, except as +/// a prefix of `.await` since this would be captured by value. +/// +/// This function will sometimes return `true` even tough there are no +/// captures happening: at the AST level, it is impossible to +/// dinstinguish a function call from a call to a closure which comes +/// from the local environment. +fn captures_value(expr: &Expr) -> bool { + let mut detector = CaptureDetector::default(); + detector.visit_expr(expr); + detector.capture_found +} + +#[derive(Default)] +struct CaptureDetector { + capture_found: bool, +} + +impl<'ast> AstVisitor<'ast> for CaptureDetector { + fn visit_expr(&mut self, ex: &'ast Expr) { + match (&ex.kind, self.capture_found) { + (ExprKind::Await(fut), _) if matches!(fut.kind, ExprKind::Path(..)) => (), + (ExprKind::Path(_, path), _) if path.segments.len() == 1 => self.capture_found = true, + (_, false) => rustc_ast::visit::walk_expr(self, ex), + _ => (), + } + } +} diff --git a/tests/ui/redundant_async_block.fixed b/tests/ui/redundant_async_block.fixed index 5f9931df45e..d26b7a332cb 100644 --- a/tests/ui/redundant_async_block.fixed +++ b/tests/ui/redundant_async_block.fixed @@ -3,6 +3,8 @@ #![allow(unused)] #![warn(clippy::redundant_async_block)] +use std::future::Future; + async fn func1(n: usize) -> usize { n + 1 } @@ -62,3 +64,48 @@ fn main() { let fut = async_await_parameter_in_macro!(func2()); let fut = async_await_in_macro!(std::convert::identity); } + +#[allow(clippy::let_and_return)] +fn capture_local() -> impl Future { + // Lint + let fut = async { 17 }; + fut +} + +fn capture_local_closure(s: &str) -> impl Future { + let f = move || std::future::ready(s); + // Do not lint: `f` would not live long enough + async move { f().await } +} + +#[allow(clippy::let_and_return)] +fn capture_arg(s: &str) -> impl Future { + // Lint + let fut = async move { s }; + fut +} + +#[derive(Debug, Clone)] +struct F {} + +impl F { + async fn run(&self) {} +} + +pub async fn run() { + let f = F {}; + let c = f.clone(); + // Do not lint: `c` would not live long enough + spawn(async move { c.run().await }); + let _f = f; +} + +fn spawn(_: F) {} + +async fn work(_: &str) {} + +fn capture() { + let val = "Hello World".to_owned(); + // Do not lint: `val` would not live long enough + spawn(async { work(&{ val }).await }); +} diff --git a/tests/ui/redundant_async_block.rs b/tests/ui/redundant_async_block.rs index de3c9970c65..04726e62805 100644 --- a/tests/ui/redundant_async_block.rs +++ b/tests/ui/redundant_async_block.rs @@ -3,6 +3,8 @@ #![allow(unused)] #![warn(clippy::redundant_async_block)] +use std::future::Future; + async fn func1(n: usize) -> usize { n + 1 } @@ -62,3 +64,48 @@ fn main() { let fut = async_await_parameter_in_macro!(func2()); let fut = async_await_in_macro!(std::convert::identity); } + +#[allow(clippy::let_and_return)] +fn capture_local() -> impl Future { + // Lint + let fut = async { 17 }; + async move { fut.await } +} + +fn capture_local_closure(s: &str) -> impl Future { + let f = move || std::future::ready(s); + // Do not lint: `f` would not live long enough + async move { f().await } +} + +#[allow(clippy::let_and_return)] +fn capture_arg(s: &str) -> impl Future { + // Lint + let fut = async move { s }; + async move { fut.await } +} + +#[derive(Debug, Clone)] +struct F {} + +impl F { + async fn run(&self) {} +} + +pub async fn run() { + let f = F {}; + let c = f.clone(); + // Do not lint: `c` would not live long enough + spawn(async move { c.run().await }); + let _f = f; +} + +fn spawn(_: F) {} + +async fn work(_: &str) {} + +fn capture() { + let val = "Hello World".to_owned(); + // Do not lint: `val` would not live long enough + spawn(async { work(&{ val }).await }); +} diff --git a/tests/ui/redundant_async_block.stderr b/tests/ui/redundant_async_block.stderr index b16d96dce84..1a1c1603e08 100644 --- a/tests/ui/redundant_async_block.stderr +++ b/tests/ui/redundant_async_block.stderr @@ -1,5 +1,5 @@ error: this async expression only awaits a single future - --> $DIR/redundant_async_block.rs:13:13 + --> $DIR/redundant_async_block.rs:15:13 | LL | let x = async { f.await }; | ^^^^^^^^^^^^^^^^^ help: you can reduce it to: `f` @@ -7,22 +7,34 @@ LL | let x = async { f.await }; = note: `-D clippy::redundant-async-block` implied by `-D warnings` error: this async expression only awaits a single future - --> $DIR/redundant_async_block.rs:46:16 + --> $DIR/redundant_async_block.rs:48:16 | LL | let fut2 = async { fut1.await }; | ^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `fut1` error: this async expression only awaits a single future - --> $DIR/redundant_async_block.rs:49:16 + --> $DIR/redundant_async_block.rs:51:16 | LL | let fut2 = async move { fut1.await }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `fut1` error: this async expression only awaits a single future - --> $DIR/redundant_async_block.rs:51:15 + --> $DIR/redundant_async_block.rs:53:15 | LL | let fut = async { async { 42 }.await }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `async { 42 }` -error: aborting due to 4 previous errors +error: this async expression only awaits a single future + --> $DIR/redundant_async_block.rs:72:5 + | +LL | async move { fut.await } + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `fut` + +error: this async expression only awaits a single future + --> $DIR/redundant_async_block.rs:85:5 + | +LL | async move { fut.await } + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: you can reduce it to: `fut` + +error: aborting due to 6 previous errors From b138bb587bfc2c0e5a3a55820848cc9b2f26149b Mon Sep 17 00:00:00 2001 From: "Samuel \"Sam\" Tardieu" Date: Wed, 22 Mar 2023 00:34:35 +0100 Subject: [PATCH 079/346] Do not propose to simplify a not expression coming from a macro --- clippy_lints/src/booleans.rs | 25 +++++++++++++------------ tests/ui/nonminimal_bool.rs | 29 +++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/clippy_lints/src/booleans.rs b/clippy_lints/src/booleans.rs index e8106beec37..29fde9336c0 100644 --- a/clippy_lints/src/booleans.rs +++ b/clippy_lints/src/booleans.rs @@ -495,18 +495,19 @@ struct NotSimplificationVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor<'tcx> for NotSimplificationVisitor<'a, 'tcx> { fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { - if let ExprKind::Unary(UnOp::Not, inner) = &expr.kind { - if let Some(suggestion) = simplify_not(self.cx, inner) { - span_lint_and_sugg( - self.cx, - NONMINIMAL_BOOL, - expr.span, - "this boolean expression can be simplified", - "try", - suggestion, - Applicability::MachineApplicable, - ); - } + if let ExprKind::Unary(UnOp::Not, inner) = &expr.kind && + !inner.span.from_expansion() && + let Some(suggestion) = simplify_not(self.cx, inner) + { + span_lint_and_sugg( + self.cx, + NONMINIMAL_BOOL, + expr.span, + "this boolean expression can be simplified", + "try", + suggestion, + Applicability::MachineApplicable, + ); } walk_expr(self, expr); diff --git a/tests/ui/nonminimal_bool.rs b/tests/ui/nonminimal_bool.rs index e9b4367ca65..3b5a374b4a7 100644 --- a/tests/ui/nonminimal_bool.rs +++ b/tests/ui/nonminimal_bool.rs @@ -63,3 +63,32 @@ fn issue9428() { println!("foo"); } } + +fn issue_10523() { + macro_rules! a { + ($v:expr) => { + $v.is_some() + }; + } + let x: Option = None; + if !a!(x) {} +} + +fn issue_10523_1() { + macro_rules! a { + ($v:expr) => { + !$v.is_some() + }; + } + let x: Option = None; + if a!(x) {} +} + +fn issue_10523_2() { + macro_rules! a { + () => { + !None::.is_some() + }; + } + if a!() {} +} From 079a801d8bb55eb8e08fcc6bd04f6858cbc850b3 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 21 Mar 2023 19:02:08 +0100 Subject: [PATCH 080/346] Update dist-x86_64-linux to GCC 8.5 While we don't use GCC for the LLVM build, we do use its libstdc++, and there has been an std::optional ABI break in this version. This makes the libLLVM.so for LLVM 16 ABI-incompatible with newer libstdc++ versions, which we use on all other builders, and which download-ci-llvm users are likely to use. --- src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh index 9932b250566..41ca1385c75 100755 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh @@ -3,7 +3,7 @@ set -ex source shared.sh -GCC=7.5.0 +GCC=8.5.0 curl https://ftp.gnu.org/gnu/gcc/gcc-$GCC/gcc-$GCC.tar.xz | xzcat | tar xf - cd gcc-$GCC From 237f703a6dca8129f298739ecb030f7961a1921a Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 23 Jan 2023 11:33:33 +0100 Subject: [PATCH 081/346] Upgrade to LLVM 16 --- .gitmodules | 2 +- src/llvm-project | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitmodules b/.gitmodules index e79f2f089c1..0bbccb57130 100644 --- a/.gitmodules +++ b/.gitmodules @@ -25,7 +25,7 @@ [submodule "src/llvm-project"] path = src/llvm-project url = https://github.com/rust-lang/llvm-project.git - branch = rustc/15.0-2022-12-07 + branch = rustc/16.0-2023-03-06 [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 fd949f3034f..2b9c52f6681 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit fd949f3034f8a422ecfffa889c2823485dde4bdd +Subproject commit 2b9c52f66815bb8d6ea74a4b26df3410602be9b0 From 58ac25b453793662f92784dc94143ab19f1fd700 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 15 Mar 2023 17:20:56 +0100 Subject: [PATCH 082/346] Increase array size in array-map.rs Make sure that the loop is not fully unrolled (which allows eliminating the allocas) in LLVM 16 either. --- tests/codegen/array-map.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/codegen/array-map.rs b/tests/codegen/array-map.rs index 9298e89e397..7b8ab2c79a7 100644 --- a/tests/codegen/array-map.rs +++ b/tests/codegen/array-map.rs @@ -38,10 +38,10 @@ pub fn short_integer_zip_map(x: [u32; 8], y: [u32; 8]) -> [u32; 8] { // // CHECK-LABEL: @long_integer_map #[no_mangle] -pub fn long_integer_map(x: [u32; 64]) -> [u32; 64] { +pub fn long_integer_map(x: [u32; 512]) -> [u32; 512] { // CHECK: start: - // CHECK-NEXT: alloca [64 x i32] - // CHECK-NEXT: alloca %"core::mem::manually_drop::ManuallyDrop<[u32; 64]>" + // CHECK-NEXT: alloca [512 x i32] + // CHECK-NEXT: alloca %"core::mem::manually_drop::ManuallyDrop<[u32; 512]>" // CHECK-NOT: alloca // CHECK: mul <{{[0-9]+}} x i32> // CHECK: add <{{[0-9]+}} x i32> From cae7b877113652f96aee1361b9356bd9720bddd1 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 19 Mar 2023 21:32:34 +0400 Subject: [PATCH 083/346] rustc: Remove unused `Session` argument from some attribute functions --- clippy_lints/src/functions/must_use.rs | 6 +++--- clippy_utils/src/attrs.rs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/clippy_lints/src/functions/must_use.rs b/clippy_lints/src/functions/must_use.rs index eacbf6c6ec9..67877780c0e 100644 --- a/clippy_lints/src/functions/must_use.rs +++ b/clippy_lints/src/functions/must_use.rs @@ -28,7 +28,7 @@ pub(super) fn check_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Item<'_> let fn_header_span = item.span.with_hi(sig.decl.output.span().hi()); if let Some(attr) = attr { check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr); - } else if is_public && !is_proc_macro(cx.sess(), attrs) && !attrs.iter().any(|a| a.has_name(sym::no_mangle)) { + } else if is_public && !is_proc_macro(attrs) && !attrs.iter().any(|a| a.has_name(sym::no_mangle)) { check_must_use_candidate( cx, sig.decl, @@ -51,7 +51,7 @@ pub(super) fn check_impl_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Imp if let Some(attr) = attr { check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr); } else if is_public - && !is_proc_macro(cx.sess(), attrs) + && !is_proc_macro(attrs) && trait_ref_of_method(cx, item.owner_id.def_id).is_none() { check_must_use_candidate( @@ -78,7 +78,7 @@ pub(super) fn check_trait_item<'tcx>(cx: &LateContext<'tcx>, item: &'tcx hir::Tr check_needless_must_use(cx, sig.decl, item.owner_id, item.span, fn_header_span, attr); } else if let hir::TraitFn::Provided(eid) = *eid { let body = cx.tcx.hir().body(eid); - if attr.is_none() && is_public && !is_proc_macro(cx.sess(), attrs) { + if attr.is_none() && is_public && !is_proc_macro(attrs) { check_must_use_candidate( cx, sig.decl, diff --git a/clippy_utils/src/attrs.rs b/clippy_utils/src/attrs.rs index 7987a233bdc..bc3d774540a 100644 --- a/clippy_utils/src/attrs.rs +++ b/clippy_utils/src/attrs.rs @@ -145,8 +145,8 @@ pub fn get_unique_attr<'a>( /// Return true if the attributes contain any of `proc_macro`, /// `proc_macro_derive` or `proc_macro_attribute`, false otherwise -pub fn is_proc_macro(sess: &Session, attrs: &[ast::Attribute]) -> bool { - attrs.iter().any(|attr| sess.is_proc_macro_attr(attr)) +pub fn is_proc_macro(attrs: &[ast::Attribute]) -> bool { + attrs.iter().any(|attr| attr.is_proc_macro_attr()) } /// Return true if the attributes contain `#[doc(hidden)]` From 73c79cd80631bf4cb4a20914d02aa08d0f80ba7f Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 22 Mar 2023 11:37:57 +0100 Subject: [PATCH 084/346] stop special-casing `'static` in evaluate --- compiler/rustc_infer/src/infer/freshen.rs | 17 +- compiler/rustc_infer/src/infer/mod.rs | 7 +- .../src/traits/select/mod.rs | 164 +++++++++--------- ...erlap-marker-trait-with-static-lifetime.rs | 6 +- ...p-marker-trait-with-static-lifetime.stderr | 31 ++++ .../overlapping-impl-1-modulo-regions.rs | 14 +- .../overlapping-impl-1-modulo-regions.stderr | 14 ++ 7 files changed, 151 insertions(+), 102 deletions(-) create mode 100644 tests/ui/marker_trait_attr/overlap-marker-trait-with-static-lifetime.stderr create mode 100644 tests/ui/marker_trait_attr/overlapping-impl-1-modulo-regions.stderr diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs index f09f93abf45..d89f63e5c53 100644 --- a/compiler/rustc_infer/src/infer/freshen.rs +++ b/compiler/rustc_infer/src/infer/freshen.rs @@ -43,18 +43,16 @@ pub struct TypeFreshener<'a, 'tcx> { const_freshen_count: u32, ty_freshen_map: FxHashMap>, const_freshen_map: FxHashMap, ty::Const<'tcx>>, - keep_static: bool, } impl<'a, 'tcx> TypeFreshener<'a, 'tcx> { - pub fn new(infcx: &'a InferCtxt<'tcx>, keep_static: bool) -> TypeFreshener<'a, 'tcx> { + pub fn new(infcx: &'a InferCtxt<'tcx>) -> TypeFreshener<'a, 'tcx> { TypeFreshener { infcx, ty_freshen_count: 0, const_freshen_count: 0, ty_freshen_map: Default::default(), const_freshen_map: Default::default(), - keep_static, } } @@ -121,18 +119,9 @@ impl<'a, 'tcx> TypeFolder> for TypeFreshener<'a, 'tcx> { | ty::ReFree(_) | ty::ReVar(_) | ty::RePlaceholder(..) + | ty::ReStatic | ty::ReError(_) - | ty::ReErased => { - // replace all free regions with 'erased - self.interner().lifetimes.re_erased - } - ty::ReStatic => { - if self.keep_static { - r - } else { - self.interner().lifetimes.re_erased - } - } + | ty::ReErased => self.interner().lifetimes.re_erased, } } diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index aeb4ddb4212..0d4d7d2553e 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -706,12 +706,7 @@ impl<'tcx> InferCtxt<'tcx> { } pub fn freshener<'b>(&'b self) -> TypeFreshener<'b, 'tcx> { - freshen::TypeFreshener::new(self, false) - } - - /// Like `freshener`, but does not replace `'static` regions. - pub fn freshener_keep_static<'b>(&'b self) -> TypeFreshener<'b, 'tcx> { - freshen::TypeFreshener::new(self, true) + freshen::TypeFreshener::new(self) } pub fn unsolved_variables(&self) -> Vec> { diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index b8758ad9323..68e31d06921 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -211,7 +211,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { pub fn new(infcx: &'cx InferCtxt<'tcx>) -> SelectionContext<'cx, 'tcx> { SelectionContext { infcx, - freshener: infcx.freshener_keep_static(), + freshener: infcx.freshener(), intercrate_ambiguity_causes: None, query_mode: TraitQueryMode::Standard, } @@ -769,14 +769,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } ty::PredicateKind::Clause(ty::Clause::TypeOutlives(pred)) => { - // A global type with no late-bound regions can only - // contain the "'static" lifetime (any other lifetime - // would either be late-bound or local), so it is guaranteed - // to outlive any other lifetime - if pred.0.is_global() && !pred.0.has_late_bound_vars() { - Ok(EvaluatedToOk) - } else { + // A global type with no free lifetimes or generic parameters + // outlives anything. + if pred.0.has_free_regions() + || pred.0.has_late_bound_regions() + || pred.0.has_non_region_infer() + || pred.0.has_non_region_infer() + { Ok(EvaluatedToOkModuloRegions) + } else { + Ok(EvaluatedToOk) } } @@ -1824,6 +1826,12 @@ enum DropVictim { No, } +impl DropVictim { + fn drop_if(should_drop: bool) -> DropVictim { + if should_drop { DropVictim::Yes } else { DropVictim::No } + } +} + /// ## Winnowing /// /// Winnowing is the process of attempting to resolve ambiguity by @@ -1889,11 +1897,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> { // or the current one if tied (they should both evaluate to the same answer). This is // probably best characterized as a "hack", since we might prefer to just do our // best to *not* create essentially duplicate candidates in the first place. - if other.bound_vars().len() <= victim.bound_vars().len() { - DropVictim::Yes - } else { - DropVictim::No - } + DropVictim::drop_if(other.bound_vars().len() <= victim.bound_vars().len()) } else if other.skip_binder().trait_ref == victim.skip_binder().trait_ref && victim.skip_binder().constness == ty::BoundConstness::NotConst && other.skip_binder().polarity == victim.skip_binder().polarity @@ -1923,17 +1927,13 @@ impl<'tcx> SelectionContext<'_, 'tcx> { | ObjectCandidate(_) | ProjectionCandidate(..), ) => { - if is_global(other_cand) { - DropVictim::No - } else { - // We have a where clause so don't go around looking - // for impls. Arbitrarily give param candidates priority - // over projection and object candidates. - // - // Global bounds from the where clause should be ignored - // here (see issue #50825). - DropVictim::Yes - } + // We have a where clause so don't go around looking + // for impls. Arbitrarily give param candidates priority + // over projection and object candidates. + // + // Global bounds from the where clause should be ignored + // here (see issue #50825). + DropVictim::drop_if(!is_global(other_cand)) } (ObjectCandidate(_) | ProjectionCandidate(..), ParamCandidate(ref victim_cand)) => { // Prefer these to a global where-clause bound @@ -1955,18 +1955,16 @@ impl<'tcx> SelectionContext<'_, 'tcx> { ) => { // Prefer these to a global where-clause bound // (see issue #50825). - if is_global(victim_cand) && other.evaluation.must_apply_modulo_regions() { - DropVictim::Yes - } else { - DropVictim::No - } + DropVictim::drop_if( + is_global(victim_cand) && other.evaluation.must_apply_modulo_regions(), + ) } (ProjectionCandidate(i, _), ProjectionCandidate(j, _)) | (ObjectCandidate(i), ObjectCandidate(j)) => { // Arbitrarily pick the lower numbered candidate for backwards // compatibility reasons. Don't let this affect inference. - if i < j && !needs_infer { DropVictim::Yes } else { DropVictim::No } + DropVictim::drop_if(i < j && !needs_infer) } (ObjectCandidate(_), ProjectionCandidate(..)) | (ProjectionCandidate(..), ObjectCandidate(_)) => { @@ -2017,55 +2015,65 @@ impl<'tcx> SelectionContext<'_, 'tcx> { } } - if other.evaluation.must_apply_considering_regions() { - 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 - // constraining 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 constrain) - // 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. - if needs_infer { DropVictim::No } else { DropVictim::Yes } - } - Some(_) => DropVictim::Yes, - None => DropVictim::No, + match tcx.impls_are_allowed_to_overlap(other_def, victim_def) { + // For #33140 the impl headers must be exactly equal, the trait must not have + // any associated items and there are no where-clauses. + // + // We can just arbitrarily drop one of the impls. + Some(ty::ImplOverlapKind::Issue33140) => { + assert_eq!(other.evaluation, victim.evaluation); + DropVictim::Yes } - } else { - DropVictim::No + // For candidates which already reference errors it doesn't really + // matter what we do 🤷 + Some(ty::ImplOverlapKind::Permitted { marker: false }) => { + DropVictim::drop_if(other.evaluation.must_apply_considering_regions()) + } + 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 + // constraining 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 constrain) + // 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. + DropVictim::drop_if( + !needs_infer && other.evaluation.must_apply_considering_regions(), + ) + } + None => DropVictim::No, } } diff --git a/tests/ui/marker_trait_attr/overlap-marker-trait-with-static-lifetime.rs b/tests/ui/marker_trait_attr/overlap-marker-trait-with-static-lifetime.rs index 62aa22d41ed..b9f1de7ec13 100644 --- a/tests/ui/marker_trait_attr/overlap-marker-trait-with-static-lifetime.rs +++ b/tests/ui/marker_trait_attr/overlap-marker-trait-with-static-lifetime.rs @@ -1,4 +1,8 @@ -// check-pass +// known-bug: #89515 +// +// The trait solver cannot deal with ambiguous marker trait impls +// if there are lifetimes involved. As we must not special-case any +// regions this does not work, even with 'static #![feature(marker_trait_attr)] #[marker] diff --git a/tests/ui/marker_trait_attr/overlap-marker-trait-with-static-lifetime.stderr b/tests/ui/marker_trait_attr/overlap-marker-trait-with-static-lifetime.stderr new file mode 100644 index 00000000000..fe4de540b51 --- /dev/null +++ b/tests/ui/marker_trait_attr/overlap-marker-trait-with-static-lifetime.stderr @@ -0,0 +1,31 @@ +error[E0283]: type annotations needed: cannot satisfy `&'static (): Marker` + --> $DIR/overlap-marker-trait-with-static-lifetime.rs:11:17 + | +LL | impl Marker for &'static () {} + | ^^^^^^^^^^^ + | +note: multiple `impl`s satisfying `&'static (): Marker` found + --> $DIR/overlap-marker-trait-with-static-lifetime.rs:11:1 + | +LL | impl Marker for &'static () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | impl Marker for &'static () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0283]: type annotations needed: cannot satisfy `&'static (): Marker` + --> $DIR/overlap-marker-trait-with-static-lifetime.rs:12:17 + | +LL | impl Marker for &'static () {} + | ^^^^^^^^^^^ + | +note: multiple `impl`s satisfying `&'static (): Marker` found + --> $DIR/overlap-marker-trait-with-static-lifetime.rs:11:1 + | +LL | impl Marker for &'static () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | impl Marker for &'static () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0283`. diff --git a/tests/ui/marker_trait_attr/overlapping-impl-1-modulo-regions.rs b/tests/ui/marker_trait_attr/overlapping-impl-1-modulo-regions.rs index a8f3db5f5b2..97a814f51ee 100644 --- a/tests/ui/marker_trait_attr/overlapping-impl-1-modulo-regions.rs +++ b/tests/ui/marker_trait_attr/overlapping-impl-1-modulo-regions.rs @@ -1,9 +1,17 @@ -// check-pass +// known-bug: #109481 +// +// While the `T: Copy` is always applicable when checking +// that the impl `impl F for T {}` is well formed, +// the old trait solver can only approximate this by checking +// that there are no inference variables in the obligation and +// no region constraints in the evaluation result. +// +// Because of this we end up with ambiguity here. #![feature(marker_trait_attr)] #[marker] pub trait F {} -impl F for T where T: Copy {} -impl F for T where T: 'static {} +impl F for T {} +impl F for T {} fn main() {} diff --git a/tests/ui/marker_trait_attr/overlapping-impl-1-modulo-regions.stderr b/tests/ui/marker_trait_attr/overlapping-impl-1-modulo-regions.stderr new file mode 100644 index 00000000000..e713d1451cf --- /dev/null +++ b/tests/ui/marker_trait_attr/overlapping-impl-1-modulo-regions.stderr @@ -0,0 +1,14 @@ +error[E0310]: the parameter type `T` may not live long enough + --> $DIR/overlapping-impl-1-modulo-regions.rs:14:21 + | +LL | impl F for T {} + | ^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | impl F for T {} + | +++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0310`. From 0d1a0540e46b504597497c1db3e2a4d0d89ee550 Mon Sep 17 00:00:00 2001 From: Raoul Strackx Date: Wed, 22 Mar 2023 13:04:55 +0100 Subject: [PATCH 085/346] Bugfix: avoid panic on invalid json output from libtest --- src/bootstrap/render_tests.rs | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/bootstrap/render_tests.rs b/src/bootstrap/render_tests.rs index af2370d439e..19019ad2c08 100644 --- a/src/bootstrap/render_tests.rs +++ b/src/bootstrap/render_tests.rs @@ -100,18 +100,13 @@ impl<'a> Renderer<'a> { break; } - let trimmed = line.trim(); - if trimmed.starts_with("{") && trimmed.ends_with("}") { - self.render_message(match serde_json::from_str(&trimmed) { - Ok(parsed) => parsed, - Err(err) => { - panic!("failed to parse libtest json output; error: {err}, line: {line:?}"); - } - }); - } else { - // Handle non-JSON output, for example when --nocapture is passed. - print!("{line}"); - let _ = std::io::stdout().flush(); + match serde_json::from_str(&line) { + Ok(parsed) => self.render_message(parsed), + Err(_err) => { + // Handle non-JSON output, for example when --nocapture is passed. + print!("{line}"); + let _ = std::io::stdout().flush(); + } } } } From 08284449a24f28ca9d76b8ccd823bc59ed2b30e3 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 22 Mar 2023 04:32:23 +0000 Subject: [PATCH 086/346] Subst gat normalize pred correctly --- .../src/check/compare_impl_item.rs | 2 +- .../gat-bounds-normalize-pred.rs | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 tests/ui/generic-associated-types/gat-bounds-normalize-pred.rs diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 49665525967..fd89a2067b7 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -1958,7 +1958,7 @@ pub(super) fn check_type_bounds<'tcx>( let container_id = impl_ty.container_id(tcx); let rebased_substs = impl_ty_substs.rebase_onto(tcx, container_id, impl_trait_ref.substs); - let impl_ty_value = tcx.type_of(impl_ty.def_id).subst_identity(); + let impl_ty_value = tcx.type_of(impl_ty.def_id).subst(tcx, impl_ty_substs); let param_env = tcx.param_env(impl_ty.def_id); diff --git a/tests/ui/generic-associated-types/gat-bounds-normalize-pred.rs b/tests/ui/generic-associated-types/gat-bounds-normalize-pred.rs new file mode 100644 index 00000000000..b43f982283b --- /dev/null +++ b/tests/ui/generic-associated-types/gat-bounds-normalize-pred.rs @@ -0,0 +1,17 @@ +// check-pass + +trait Foo { + type Assoc: PartialEq>; +} + +impl Foo for () { + type Assoc = Wrapper; +} + +struct Wrapper(T); + +impl PartialEq> for Wrapper { + fn eq(&self, _other: &Wrapper) -> bool { true } +} + +fn main() {} From 5456eecab0eb17bd34d3368db3bc6002ba619a64 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 22 Mar 2023 04:33:20 +0000 Subject: [PATCH 087/346] Clean up substs building --- .../src/check/compare_impl_item.rs | 103 +++++++++--------- 1 file changed, 50 insertions(+), 53 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index fd89a2067b7..17abb6ef75a 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -1876,14 +1876,17 @@ pub(super) fn check_type_bounds<'tcx>( impl_ty: ty::AssocItem, impl_trait_ref: ty::TraitRef<'tcx>, ) -> Result<(), ErrorGuaranteed> { + let param_env = tcx.param_env(impl_ty.def_id); + let container_id = impl_ty.container_id(tcx); // Given // // impl Foo for (A, B) { - // type Bar =... + // type Bar = Wrapper // } // // - `impl_trait_ref` would be `<(A, B) as Foo>` - // - `impl_ty_substs` would be `[A, B, ^0.0]` (`^0.0` here is the bound var with db 0 and index 0) + // - `normalize_impl_ty_substs` would be `[A, B, ^0.0]` (`^0.0` here is the bound var with db 0 and index 0) + // - `normalize_impl_ty` would be `Wrapper` // - `rebased_substs` would be `[(A, B), u32, ^0.0]`, combining the substs from // the *trait* with the generic associated type parameters (as bound vars). // @@ -1912,56 +1915,46 @@ pub(super) fn check_type_bounds<'tcx>( // Member = .... That type would fail a well-formedness check that we ought to be doing // elsewhere, which would check that any ::Member meets the bounds declared in // the trait (notably, that X: Eq and T: Family). - let defs: &ty::Generics = tcx.generics_of(impl_ty.def_id); - let mut substs = smallvec::SmallVec::with_capacity(defs.count()); - if let Some(def_id) = defs.parent { - let parent_defs = tcx.generics_of(def_id); - InternalSubsts::fill_item(&mut substs, tcx, parent_defs, &mut |param, _| { - tcx.mk_param_from_def(param) - }); - } let mut bound_vars: smallvec::SmallVec<[ty::BoundVariableKind; 8]> = - smallvec::SmallVec::with_capacity(defs.count()); - InternalSubsts::fill_single(&mut substs, defs, &mut |param, _| match param.kind { - GenericParamDefKind::Type { .. } => { - let kind = ty::BoundTyKind::Param(param.def_id, param.name); - let bound_var = ty::BoundVariableKind::Ty(kind); - bound_vars.push(bound_var); - tcx.mk_bound( - ty::INNERMOST, - ty::BoundTy { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind }, - ) - .into() - } - GenericParamDefKind::Lifetime => { - let kind = ty::BoundRegionKind::BrNamed(param.def_id, param.name); - let bound_var = ty::BoundVariableKind::Region(kind); - bound_vars.push(bound_var); - tcx.mk_re_late_bound( - ty::INNERMOST, - ty::BoundRegion { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind }, - ) - .into() - } - GenericParamDefKind::Const { .. } => { - let bound_var = ty::BoundVariableKind::Const; - bound_vars.push(bound_var); - tcx.mk_const( - ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from_usize(bound_vars.len() - 1)), - tcx.type_of(param.def_id).subst_identity(), - ) - .into() - } - }); - let bound_vars = tcx.mk_bound_variable_kinds(&bound_vars); - let impl_ty_substs = tcx.mk_substs(&substs); - let container_id = impl_ty.container_id(tcx); - - let rebased_substs = impl_ty_substs.rebase_onto(tcx, container_id, impl_trait_ref.substs); - let impl_ty_value = tcx.type_of(impl_ty.def_id).subst(tcx, impl_ty_substs); - - let param_env = tcx.param_env(impl_ty.def_id); - + smallvec::SmallVec::with_capacity(tcx.generics_of(impl_ty.def_id).params.len()); + // Extend the impl's identity substs with late-bound GAT vars + let normalize_impl_ty_substs = ty::InternalSubsts::identity_for_item(tcx, container_id) + .extend_to(tcx, impl_ty.def_id, |param, _| match param.kind { + GenericParamDefKind::Type { .. } => { + let kind = ty::BoundTyKind::Param(param.def_id, param.name); + let bound_var = ty::BoundVariableKind::Ty(kind); + bound_vars.push(bound_var); + tcx.mk_bound( + ty::INNERMOST, + ty::BoundTy { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind }, + ) + .into() + } + GenericParamDefKind::Lifetime => { + let kind = ty::BoundRegionKind::BrNamed(param.def_id, param.name); + let bound_var = ty::BoundVariableKind::Region(kind); + bound_vars.push(bound_var); + tcx.mk_re_late_bound( + ty::INNERMOST, + ty::BoundRegion { var: ty::BoundVar::from_usize(bound_vars.len() - 1), kind }, + ) + .into() + } + GenericParamDefKind::Const { .. } => { + let bound_var = ty::BoundVariableKind::Const; + bound_vars.push(bound_var); + tcx.mk_const( + ty::ConstKind::Bound( + ty::INNERMOST, + ty::BoundVar::from_usize(bound_vars.len() - 1), + ), + tcx.type_of(param.def_id) + .no_bound_vars() + .expect("const parameter types cannot be generic"), + ) + .into() + } + }); // When checking something like // // trait X { type Y: PartialEq<::Y> } @@ -1971,9 +1964,13 @@ pub(super) fn check_type_bounds<'tcx>( // we want ::Y to normalize to S. This is valid because we are // checking the default value specifically here. Add this equality to the // ParamEnv for normalization specifically. + let normalize_impl_ty = tcx.type_of(impl_ty.def_id).subst(tcx, normalize_impl_ty_substs); + let rebased_substs = + normalize_impl_ty_substs.rebase_onto(tcx, container_id, impl_trait_ref.substs); + let bound_vars = tcx.mk_bound_variable_kinds(&bound_vars); let normalize_param_env = { let mut predicates = param_env.caller_bounds().iter().collect::>(); - match impl_ty_value.kind() { + match normalize_impl_ty.kind() { ty::Alias(ty::Projection, proj) if proj.def_id == trait_ty.def_id && proj.substs == rebased_substs => { @@ -1987,7 +1984,7 @@ pub(super) fn check_type_bounds<'tcx>( ty::Binder::bind_with_vars( ty::ProjectionPredicate { projection_ty: tcx.mk_alias_ty(trait_ty.def_id, rebased_substs), - term: impl_ty_value.into(), + term: normalize_impl_ty.into(), }, bound_vars, ) From a34c92760c4ced5eff6ac9a3d8cabab1ec200b0d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 22 Mar 2023 17:13:00 +0000 Subject: [PATCH 088/346] Implement non-const Destruct trait in new solver --- .../rustc_trait_selection/src/solve/assembly.rs | 7 +++++++ .../src/solve/project_goals.rs | 7 +++++++ .../rustc_trait_selection/src/solve/trait_goals.rs | 14 ++++++++++++++ tests/ui/traits/new-solver/destruct.rs | 13 +++++++++++++ 4 files changed, 41 insertions(+) create mode 100644 tests/ui/traits/new-solver/destruct.rs diff --git a/compiler/rustc_trait_selection/src/solve/assembly.rs b/compiler/rustc_trait_selection/src/solve/assembly.rs index 76cde1a6692..f9cb56655ae 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly.rs @@ -209,6 +209,11 @@ pub(super) trait GoalKind<'tcx>: TypeFoldable> + Copy + Eq { ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx>; + + fn consider_builtin_destruct_candidate( + ecx: &mut EvalCtxt<'_, 'tcx>, + goal: Goal<'tcx, Self>, + ) -> QueryResult<'tcx>; } impl<'tcx> EvalCtxt<'_, 'tcx> { @@ -336,6 +341,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { G::consider_builtin_unsize_candidate(self, goal) } else if lang_items.discriminant_kind_trait() == Some(trait_def_id) { G::consider_builtin_discriminant_kind_candidate(self, goal) + } else if lang_items.destruct_trait() == Some(trait_def_id) { + G::consider_builtin_destruct_candidate(self, goal) } else { Err(NoSolution) }; diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index 93d77c39f95..df821a2913a 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -483,6 +483,13 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) } + + fn consider_builtin_destruct_candidate( + _ecx: &mut EvalCtxt<'_, 'tcx>, + goal: Goal<'tcx, Self>, + ) -> QueryResult<'tcx> { + bug!("`Destruct` does not have an associated type: {:?}", goal); + } } /// This behavior is also implemented in `rustc_ty_utils` and in the old `project` code. diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index 8ab55c79fc4..29b7ab61c7c 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -513,6 +513,20 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { // `DiscriminantKind` is automatically implemented for every type. ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } + + fn consider_builtin_destruct_candidate( + ecx: &mut EvalCtxt<'_, 'tcx>, + goal: Goal<'tcx, Self>, + ) -> QueryResult<'tcx> { + if !goal.param_env.is_const() { + // `Destruct` is automatically implemented for every type in + // non-const environments. + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + } else { + // FIXME(-Ztrait-solver=next): Implement this when we get const working in the new solver + Err(NoSolution) + } + } } impl<'tcx> EvalCtxt<'_, 'tcx> { diff --git a/tests/ui/traits/new-solver/destruct.rs b/tests/ui/traits/new-solver/destruct.rs new file mode 100644 index 00000000000..30d7777b78a --- /dev/null +++ b/tests/ui/traits/new-solver/destruct.rs @@ -0,0 +1,13 @@ +// compile-flags: -Ztrait-solver=next +// check-pass + +#![feature(const_trait_impl)] + +fn foo(_: impl std::marker::Destruct) {} + +struct MyAdt; + +fn main() { + foo(1); + foo(MyAdt); +} From 8390c61690186ddc45f97684732c8d3b6458cc44 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 22 Mar 2023 18:26:33 +0000 Subject: [PATCH 089/346] Drive-by: Add -Ztrait-solver=next to canonical int var test --- tests/ui/traits/new-solver/canonical-int-var-eq-in-response.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/ui/traits/new-solver/canonical-int-var-eq-in-response.rs b/tests/ui/traits/new-solver/canonical-int-var-eq-in-response.rs index 3f7316a2279..4b013983a4a 100644 --- a/tests/ui/traits/new-solver/canonical-int-var-eq-in-response.rs +++ b/tests/ui/traits/new-solver/canonical-int-var-eq-in-response.rs @@ -1,3 +1,4 @@ +// compile-flags: -Ztrait-solver=next // check-pass trait Mirror { From 966d5b0e348c9bd29eb1d9ddc2c2cf42555a25b7 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Wed, 22 Mar 2023 22:12:19 +0100 Subject: [PATCH 090/346] Cache `has_sig_drop_attr` for `significant_drop_tightening` The lint is very slow as it doesn't cache the deeply nested check for the attribute. If we cache it, we can reduce the time spent on checking `rustc_borrowck` from 28s to 9s, which is a nice improvement. In the profile, the time inside `has_sig_drop_attr` goes from 66% to 0.2%, which is a lot more reasonable. See the PR for nice graphs. --- .../src/significant_drop_tightening.rs | 38 +++++++++++++++---- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/clippy_lints/src/significant_drop_tightening.rs b/clippy_lints/src/significant_drop_tightening.rs index e2d90edec5a..c3e99aa0055 100644 --- a/clippy_lints/src/significant_drop_tightening.rs +++ b/clippy_lints/src/significant_drop_tightening.rs @@ -1,9 +1,9 @@ -use crate::FxHashSet; use clippy_utils::{ diagnostics::span_lint_and_then, get_attr, source::{indent_of, snippet}, }; +use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::{Applicability, Diagnostic}; use rustc_hir::{ self as hir, @@ -58,6 +58,7 @@ impl_lint_pass!(SignificantDropTightening<'_> => [SIGNIFICANT_DROP_TIGHTENING]); pub struct SignificantDropTightening<'tcx> { /// Auxiliary structure used to avoid having to verify the same type multiple times. seen_types: FxHashSet>, + type_cache: FxHashMap, bool>, } impl<'tcx> SignificantDropTightening<'tcx> { @@ -118,7 +119,7 @@ impl<'tcx> SignificantDropTightening<'tcx> { stmt: &hir::Stmt<'_>, cb: impl Fn(&mut SigDropAuxParams), ) { - let mut sig_drop_finder = SigDropFinder::new(cx, &mut self.seen_types); + let mut sig_drop_finder = SigDropFinder::new(cx, &mut self.seen_types, &mut self.type_cache); sig_drop_finder.visit_expr(expr); if sig_drop_finder.has_sig_drop { cb(sdap); @@ -296,15 +297,24 @@ impl Default for SigDropAuxParams { struct SigDropChecker<'cx, 'sdt, 'tcx> { cx: &'cx LateContext<'tcx>, seen_types: &'sdt mut FxHashSet>, + type_cache: &'sdt mut FxHashMap, bool>, } impl<'cx, 'sdt, 'tcx> SigDropChecker<'cx, 'sdt, 'tcx> { - pub(crate) fn new(cx: &'cx LateContext<'tcx>, seen_types: &'sdt mut FxHashSet>) -> Self { + pub(crate) fn new( + cx: &'cx LateContext<'tcx>, + seen_types: &'sdt mut FxHashSet>, + type_cache: &'sdt mut FxHashMap, bool>, + ) -> Self { seen_types.clear(); - Self { cx, seen_types } + Self { + cx, + seen_types, + type_cache, + } } - pub(crate) fn has_sig_drop_attr(&mut self, ty: Ty<'tcx>) -> bool { + pub(crate) fn has_sig_drop_attr_uncached(&mut self, ty: Ty<'tcx>) -> bool { if let Some(adt) = ty.ty_adt_def() { let mut iter = get_attr( self.cx.sess(), @@ -340,6 +350,16 @@ impl<'cx, 'sdt, 'tcx> SigDropChecker<'cx, 'sdt, 'tcx> { } } + pub(crate) fn has_sig_drop_attr(&mut self, ty: Ty<'tcx>) -> bool { + // The borrow checker prevents us from using something fancier like or_insert_with. + if let Some(ty) = self.type_cache.get(&ty) { + return *ty; + } + let value = self.has_sig_drop_attr_uncached(ty); + self.type_cache.insert(ty, value); + value + } + fn has_seen_ty(&mut self, ty: Ty<'tcx>) -> bool { !self.seen_types.insert(ty) } @@ -353,11 +373,15 @@ struct SigDropFinder<'cx, 'sdt, 'tcx> { } impl<'cx, 'sdt, 'tcx> SigDropFinder<'cx, 'sdt, 'tcx> { - fn new(cx: &'cx LateContext<'tcx>, seen_types: &'sdt mut FxHashSet>) -> Self { + fn new( + cx: &'cx LateContext<'tcx>, + seen_types: &'sdt mut FxHashSet>, + type_cache: &'sdt mut FxHashMap, bool>, + ) -> Self { Self { cx, has_sig_drop: false, - sig_drop_checker: SigDropChecker::new(cx, seen_types), + sig_drop_checker: SigDropChecker::new(cx, seen_types, type_cache), } } } From 8bdd54e8c6f3b19d66030551a40f7c781335905f Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Fri, 24 Feb 2023 18:32:52 -0800 Subject: [PATCH 091/346] Add `CastKind::Transmute` to MIR Updates `interpret`, `codegen_ssa`, and `codegen_cranelift` to consume the new cast instead of the intrinsic. Includes `CastTransmute` for custom MIR building, to be able to test the extra UB. --- clippy_utils/src/qualify_min_const_fn.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/clippy_utils/src/qualify_min_const_fn.rs b/clippy_utils/src/qualify_min_const_fn.rs index 24403e8b6f3..ff492a5104d 100644 --- a/clippy_utils/src/qualify_min_const_fn.rs +++ b/clippy_utils/src/qualify_min_const_fn.rs @@ -176,6 +176,9 @@ fn check_rvalue<'tcx>( // FIXME(dyn-star) unimplemented!() }, + Rvalue::Cast(CastKind::Transmute, _, _) => { + Err((span, "transmute can attempt to turn pointers into integers, so is unstable in const fn".into())) + }, // binops are fine on integers Rvalue::BinaryOp(_, box (lhs, rhs)) | Rvalue::CheckedBinaryOp(_, box (lhs, rhs)) => { check_operand(tcx, lhs, span, body)?; From 2da2ade0f7b289cd2d670fa6c77f50b3559ede2b Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 22 Mar 2023 21:12:40 -0700 Subject: [PATCH 092/346] Rename tests to ensure they don't have overlapping names. Some tests will delete their output directory before starting. The output directory is based on the test names. If one test is the prefix of another test, then when that test starts, it could try to delete the output directory of the other test with the longer path. --- tests/rustdoc/{ => primitive}/primitive.rs | 0 .../ui/impl-trait/{ => multiple-lifetimes}/multiple-lifetimes.rs | 0 .../mod_file_disambig_aux/compiletest-ignore-dir | 0 .../non_modrs_mods_and_inline_mods/x/y/z/compiletest-ignore-dir | 0 tests/ui/use/{ => use-mod}/use-mod.rs | 0 tests/ui/use/{ => use-mod}/use-mod.stderr | 0 tests/ui/{ => use}/use.rs | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename tests/rustdoc/{ => primitive}/primitive.rs (100%) rename tests/ui/impl-trait/{ => multiple-lifetimes}/multiple-lifetimes.rs (100%) create mode 100644 tests/ui/modules_and_files_visibility/mod_file_disambig_aux/compiletest-ignore-dir create mode 100644 tests/ui/non_modrs_mods_and_inline_mods/x/y/z/compiletest-ignore-dir rename tests/ui/use/{ => use-mod}/use-mod.rs (100%) rename tests/ui/use/{ => use-mod}/use-mod.stderr (100%) rename tests/ui/{ => use}/use.rs (100%) diff --git a/tests/rustdoc/primitive.rs b/tests/rustdoc/primitive/primitive.rs similarity index 100% rename from tests/rustdoc/primitive.rs rename to tests/rustdoc/primitive/primitive.rs diff --git a/tests/ui/impl-trait/multiple-lifetimes.rs b/tests/ui/impl-trait/multiple-lifetimes/multiple-lifetimes.rs similarity index 100% rename from tests/ui/impl-trait/multiple-lifetimes.rs rename to tests/ui/impl-trait/multiple-lifetimes/multiple-lifetimes.rs diff --git a/tests/ui/modules_and_files_visibility/mod_file_disambig_aux/compiletest-ignore-dir b/tests/ui/modules_and_files_visibility/mod_file_disambig_aux/compiletest-ignore-dir new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/ui/non_modrs_mods_and_inline_mods/x/y/z/compiletest-ignore-dir b/tests/ui/non_modrs_mods_and_inline_mods/x/y/z/compiletest-ignore-dir new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/ui/use/use-mod.rs b/tests/ui/use/use-mod/use-mod.rs similarity index 100% rename from tests/ui/use/use-mod.rs rename to tests/ui/use/use-mod/use-mod.rs diff --git a/tests/ui/use/use-mod.stderr b/tests/ui/use/use-mod/use-mod.stderr similarity index 100% rename from tests/ui/use/use-mod.stderr rename to tests/ui/use/use-mod/use-mod.stderr diff --git a/tests/ui/use.rs b/tests/ui/use/use.rs similarity index 100% rename from tests/ui/use.rs rename to tests/ui/use/use.rs From b506eb5338d3c23f73190615367bca14a36b9ae3 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 21 Mar 2023 22:11:40 +0000 Subject: [PATCH 093/346] Rename AliasEq -> AliasRelate --- clippy_utils/src/qualify_min_const_fn.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_utils/src/qualify_min_const_fn.rs b/clippy_utils/src/qualify_min_const_fn.rs index 24403e8b6f3..58f7742ab87 100644 --- a/clippy_utils/src/qualify_min_const_fn.rs +++ b/clippy_utils/src/qualify_min_const_fn.rs @@ -37,7 +37,7 @@ pub fn is_min_const_fn<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, msrv: &Msrv) | ty::PredicateKind::ConstEvaluatable(..) | ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::TypeWellFormedFromEnv(..) => continue, - ty::PredicateKind::AliasEq(..) => panic!("alias eq predicate on function: {predicate:#?}"), + ty::PredicateKind::AliasRelate(..) => panic!("alias relate predicate on function: {predicate:#?}"), ty::PredicateKind::ObjectSafe(_) => panic!("object safe predicate on function: {predicate:#?}"), ty::PredicateKind::ClosureKind(..) => panic!("closure kind predicate on function: {predicate:#?}"), ty::PredicateKind::Subtype(_) => panic!("subtype predicate on function: {predicate:#?}"), From a912a93acc0a3e618cfb0d2fb90b5ac9543d24cb Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Thu, 23 Mar 2023 06:19:25 +0000 Subject: [PATCH 094/346] bump `askama_derive` to 0.12.1 --- Cargo.lock | 83 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 47 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2b08aab41ed..31dd103f962 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -149,9 +149,9 @@ dependencies = [ [[package]] name = "askama_derive" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e80b5ad1afe82872b7aa3e9de9b206ecb85584aa324f0f60fa4c903ce935936b" +checksum = "c22fbe0413545c098358e56966ff22cdd039e10215ae213cfbd65032b119fc94" dependencies = [ "basic-toml", "mime", @@ -160,7 +160,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn", + "syn 2.0.8", ] [[package]] @@ -590,7 +590,7 @@ checksum = "d552b2fa341f5fc35c6b917b1d289d3c3a34d0b74e579390ea6192d6152a8cdb" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.102", "synstructure", ] @@ -702,7 +702,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.102", ] [[package]] @@ -715,7 +715,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.102", ] [[package]] @@ -757,7 +757,7 @@ dependencies = [ "rustc_tools_util", "semver", "serde", - "syn", + "syn 1.0.102", "tempfile", "termize", "tester", @@ -1108,7 +1108,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" dependencies = [ "quote", - "syn", + "syn 1.0.102", ] [[package]] @@ -1154,7 +1154,7 @@ version = "0.1.70" dependencies = [ "itertools", "quote", - "syn", + "syn 1.0.102", ] [[package]] @@ -1176,7 +1176,7 @@ checksum = "71f31892cd5c62e414316f2963c5689242c43d8e7bbcaaeca97e5e28c95d91d9" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.102", ] [[package]] @@ -1189,7 +1189,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn", + "syn 1.0.102", ] [[package]] @@ -1267,7 +1267,7 @@ checksum = "3bf95dc3f046b9da4f2d51833c0d3547d8564ef6910f5c1ed130306a75b92886" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.102", ] [[package]] @@ -1683,7 +1683,7 @@ checksum = "6dbd947adfffb0efc70599b3ddcf7b5597bb5fa9e245eb99f62b3a5f7bb8bd3c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.102", ] [[package]] @@ -2530,7 +2530,7 @@ dependencies = [ "markup5ever", "proc-macro2", "quote", - "syn", + "syn 1.0.102", ] [[package]] @@ -2619,7 +2619,7 @@ checksum = "9ddb07844c2ffc4c28840e799e9e54ff054393cf090740decf25624e9d94b93a" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.102", ] [[package]] @@ -3089,7 +3089,7 @@ checksum = "0f1b8c13cb1f814b634a96b2c725449fe7ed464a7b8781de8688be5ffbd3f305" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.102", ] [[package]] @@ -3679,7 +3679,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn", + "syn 1.0.102", ] [[package]] @@ -3823,7 +3823,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.102", "version_check", ] @@ -3846,9 +3846,9 @@ checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" [[package]] name = "proc-macro2" -version = "1.0.46" +version = "1.0.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b" +checksum = "ba466839c78239c09faf015484e5cc04860f88242cff4d03eb038f04b4699b73" dependencies = [ "unicode-ident", ] @@ -3925,9 +3925,9 @@ checksum = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45" [[package]] name = "quote" -version = "1.0.21" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" dependencies = [ "proc-macro2", ] @@ -4224,7 +4224,7 @@ dependencies = [ "regex", "serde_json", "smallvec", - "syn", + "syn 1.0.102", "url", "winapi", ] @@ -4932,7 +4932,7 @@ dependencies = [ "fluent-syntax", "proc-macro2", "quote", - "syn", + "syn 1.0.102", "synstructure", "unic-langid", ] @@ -5509,7 +5509,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn", + "syn 1.0.102", ] [[package]] @@ -5679,7 +5679,7 @@ checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.102", ] [[package]] @@ -6023,7 +6023,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn", + "syn 1.0.102", ] [[package]] @@ -6043,6 +6043,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "2.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcc02725fd69ab9f26eab07fad303e2497fad6fb9eba4f96c4d1687bdf704ad9" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "synstructure" version = "0.12.6" @@ -6051,7 +6062,7 @@ checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.102", "unicode-xid", ] @@ -6185,7 +6196,7 @@ checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.102", ] [[package]] @@ -6382,7 +6393,7 @@ checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.102", ] [[package]] @@ -6581,7 +6592,7 @@ checksum = "1f5cdec05b907f4e2f6843f4354f4ce6a5bebe1a56df320a49134944477ce4d8" dependencies = [ "proc-macro-hack", "quote", - "syn", + "syn 1.0.102", "unic-langid-impl", ] @@ -6829,7 +6840,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 1.0.102", "wasm-bindgen-shared", ] @@ -6851,7 +6862,7 @@ checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.102", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -7077,7 +7088,7 @@ checksum = "ca800d73d6b7a7ee54f2608205c98b549fca71c9500c1abcb3abdc7708b4a8cb" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.102", "synstructure", ] @@ -7098,7 +7109,7 @@ checksum = "2e8aa86add9ddbd2409c1ed01e033cd457d79b1b1229b64922c25095c595e829" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.102", "synstructure", ] @@ -7127,6 +7138,6 @@ checksum = "2154cb6e2a748163354165e22c6a555effb09ca2d16334767bf66bb404f2206e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.102", "synstructure", ] From 3a7977e3ca65ae8b6da8d81f475189333c149ac4 Mon Sep 17 00:00:00 2001 From: Kai Luo Date: Thu, 23 Mar 2023 16:33:54 +0800 Subject: [PATCH 095/346] Link against libc++ on AIX --- compiler/rustc_llvm/build.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs index 9fe59a1d826..f8e9ec535e4 100644 --- a/compiler/rustc_llvm/build.rs +++ b/compiler/rustc_llvm/build.rs @@ -333,6 +333,7 @@ fn main() { } else if target.contains("darwin") || target.contains("freebsd") || target.contains("windows-gnullvm") + || target.contains("aix") { "c++" } else if target.contains("netbsd") && llvm_static_stdcpp.is_some() { From 6e8a8282b8c131adb7f39909b9148687ea6c3b7b Mon Sep 17 00:00:00 2001 From: Kai Luo Date: Thu, 23 Mar 2023 16:50:49 +0800 Subject: [PATCH 096/346] Implement current_dll_path for AIX --- compiler/rustc_session/src/filesearch.rs | 34 ++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index e734599cbfc..2c804f0f0a4 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -67,6 +67,7 @@ fn current_dll_path() -> Result { use std::ffi::{CStr, OsStr}; use std::os::unix::prelude::*; + #[cfg(not(target_os = "aix"))] unsafe { let addr = current_dll_path as usize as *mut _; let mut info = std::mem::zeroed(); @@ -80,6 +81,39 @@ fn current_dll_path() -> Result { let os = OsStr::from_bytes(bytes); Ok(PathBuf::from(os)) } + + #[cfg(target_os = "aix")] + unsafe { + let addr = current_dll_path as u64; + let mut buffer = vec![0i8; 4096]; + loop { + if libc::loadquery(libc::L_GETINFO, buffer.as_mut_ptr(), buffer.len() as u32) >= 0 { + break; + } else { + if std::io::Error::last_os_error().raw_os_error().unwrap() != libc::ENOMEM { + return Err("loadquery failed".into()); + } + buffer.resize(buffer.len() * 2, 0i8); + } + } + let mut current = buffer.as_mut_ptr() as *mut libc::ld_info; + loop { + let data_base = (*current).ldinfo_dataorg as u64; + let data_end = data_base + (*current).ldinfo_datasize; + let text_base = (*current).ldinfo_textorg as u64; + let text_end = text_base + (*current).ldinfo_textsize; + if (data_base <= addr && addr < data_end) || (text_base <= addr && addr < text_end) { + let bytes = CStr::from_ptr(&(*current).ldinfo_filename[0]).to_bytes(); + let os = OsStr::from_bytes(bytes); + return Ok(PathBuf::from(os)); + } + if (*current).ldinfo_next == 0 { + break; + } + current = ((current as u64) + ((*current).ldinfo_next) as u64) as *mut libc::ld_info; + } + return Err(format!("current dll's address {} is not in the load map", addr)); + } } #[cfg(windows)] From 35726e909d44f41e090ac22e626bb4fa0e68afdb Mon Sep 17 00:00:00 2001 From: Kai Luo Date: Thu, 23 Mar 2023 17:56:26 +0800 Subject: [PATCH 097/346] LIBPATH is used as dylib's path environment variable on AIX --- src/bootstrap/dylib_util.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/bootstrap/dylib_util.rs b/src/bootstrap/dylib_util.rs index 6d75272c501..b14c0bed66c 100644 --- a/src/bootstrap/dylib_util.rs +++ b/src/bootstrap/dylib_util.rs @@ -12,6 +12,8 @@ pub fn dylib_path_var() -> &'static str { "DYLD_LIBRARY_PATH" } else if cfg!(target_os = "haiku") { "LIBRARY_PATH" + } else if cfg!(target_os = "aix") { + "LIBPATH" } else { "LD_LIBRARY_PATH" } From 1692d0c142985a01a2770da8654912dc40342412 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 22 Mar 2023 21:13:27 -0700 Subject: [PATCH 098/346] Add a check to ensure tests with overlapping prefixes aren't added. Some tests will delete their output directory before starting. The output directory is based on the test names. If one test is the prefix of another test, then when that test starts, it could try to delete the output directory of the other test with the longer path. --- src/tools/compiletest/src/main.rs | 37 +++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index cbaa599f793..c4d9bb6cec6 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -12,6 +12,7 @@ use build_helper::git::{get_git_modified_files, get_git_untracked_files}; use core::panic; use getopts::Options; use lazycell::LazyCell; +use std::collections::BTreeSet; use std::ffi::OsString; use std::fs; use std::io::{self, ErrorKind}; @@ -406,7 +407,9 @@ pub fn run_tests(config: Config) { let mut tests = Vec::new(); for c in &configs { - make_tests(c, &mut tests); + let mut found_paths = BTreeSet::new(); + make_tests(c, &mut tests, &mut found_paths); + check_overlapping_tests(&found_paths); } tests.sort_by(|a, b| a.desc.name.as_slice().cmp(&b.desc.name.as_slice())); @@ -528,7 +531,11 @@ pub fn test_opts(config: &Config) -> test::TestOpts { } } -pub fn make_tests(config: &Config, tests: &mut Vec) { +pub fn make_tests( + config: &Config, + tests: &mut Vec, + found_paths: &mut BTreeSet, +) { debug!("making tests from {:?}", config.src_base.display()); let inputs = common_inputs_stamp(config); let modified_tests = modified_tests(config, &config.src_base).unwrap_or_else(|err| { @@ -540,6 +547,7 @@ pub fn make_tests(config: &Config, tests: &mut Vec) { &PathBuf::new(), &inputs, tests, + found_paths, &modified_tests, ) .unwrap_or_else(|_| panic!("Could not read tests from {}", config.src_base.display())); @@ -610,6 +618,7 @@ fn collect_tests_from_dir( relative_dir_path: &Path, inputs: &Stamp, tests: &mut Vec, + found_paths: &mut BTreeSet, modified_tests: &Vec, ) -> io::Result<()> { // Ignore directories that contain a file named `compiletest-ignore-dir`. @@ -643,6 +652,8 @@ fn collect_tests_from_dir( let file_name = file.file_name(); if is_test(&file_name) && (!config.only_modified || modified_tests.contains(&file_path)) { debug!("found test file: {:?}", file_path.display()); + let rel_test_path = relative_dir_path.join(file_path.file_stem().unwrap()); + found_paths.insert(rel_test_path); let paths = TestPaths { file: file_path, relative_dir: relative_dir_path.to_path_buf() }; @@ -657,6 +668,7 @@ fn collect_tests_from_dir( &relative_file_path, inputs, tests, + found_paths, modified_tests, )?; } @@ -1072,3 +1084,24 @@ fn extract_lldb_version(full_version_line: &str) -> Option<(u32, bool)> { fn not_a_digit(c: char) -> bool { !c.is_digit(10) } + +fn check_overlapping_tests(found_paths: &BTreeSet) { + let mut collisions = Vec::new(); + for path in found_paths { + for ancestor in path.ancestors().skip(1) { + if found_paths.contains(ancestor) { + collisions.push((path, ancestor.clone())); + } + } + } + if !collisions.is_empty() { + let collisions: String = collisions + .into_iter() + .map(|(path, check_parent)| format!("test {path:?} clashes with {check_parent:?}\n")) + .collect(); + panic!( + "{collisions}\n\ + Tests cannot have overlapping names. Make sure they use unique prefixes." + ); + } +} From 1dad788d8d18672e79d20c832c9219967421f11d Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 18 Mar 2023 23:10:42 +0100 Subject: [PATCH 099/346] Fix ICE for intra-doc link on intermediate re-export --- src/librustdoc/clean/mod.rs | 64 ++++++++++++++++++++++++----------- src/librustdoc/clean/types.rs | 51 ++++++++++++++++++++-------- 2 files changed, 80 insertions(+), 35 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 2e1f456f50e..b419c81301c 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -39,7 +39,6 @@ use std::hash::Hash; use std::mem; use thin_vec::ThinVec; -use crate::clean::inline::merge_attrs; use crate::core::{self, DocContext, ImplTraitParam}; use crate::formats::item_type::ItemType; use crate::visit_ast::Module as DocModule; @@ -2168,32 +2167,40 @@ impl<'hir> hir::intravisit::Visitor<'hir> for OneLevelVisitor<'hir> { /// documentation. Otherwise, we repeat the same operation until we find the "end item". fn get_all_import_attributes<'hir>( mut item: &hir::Item<'hir>, - tcx: TyCtxt<'hir>, + cx: &mut DocContext<'hir>, target_def_id: LocalDefId, - attributes: &mut Vec, is_inline: bool, -) { + mut prev_import: LocalDefId, +) -> Vec<(ast::Attribute, Option)> { + let mut attributes: Vec<(ast::Attribute, Option)> = Vec::new(); let mut first = true; - let hir_map = tcx.hir(); + let hir_map = cx.tcx.hir(); let mut visitor = OneLevelVisitor::new(hir_map, target_def_id); let mut visited = FxHashSet::default(); + let mut import_attrs = Vec::new(); // If the item is an import and has at least a path with two parts, we go into it. while let hir::ItemKind::Use(path, _) = item.kind && visited.insert(item.hir_id()) { + let import_parent = cx.tcx.opt_local_parent(prev_import).map(|def_id| def_id.to_def_id()); if first { // This is the "original" reexport so we get all its attributes without filtering them. - attributes.extend_from_slice(hir_map.attrs(item.hir_id())); + attributes = hir_map.attrs(item.hir_id()).iter().cloned().map(|attr| (attr, import_parent)).collect::>(); first = false; } else { - add_without_unwanted_attributes(attributes, hir_map.attrs(item.hir_id()), is_inline); + add_without_unwanted_attributes(&mut import_attrs, hir_map.attrs(item.hir_id()), is_inline); + for attr in import_attrs.drain(..) { + attributes.push((attr, import_parent)); + } } - if let Some(i) = visitor.find_target(tcx, item.owner_id.def_id.to_def_id(), path) { + if let Some(i) = visitor.find_target(cx.tcx, item.owner_id.def_id.to_def_id(), path) { item = i; } else { break; } + prev_import = item.owner_id.def_id; } + attributes } fn filter_tokens_from_list( @@ -2244,7 +2251,7 @@ fn add_without_unwanted_attributes( new_attrs: &[ast::Attribute], is_inline: bool, ) { - // If it's `#[doc(inline)]`, we don't want all attributes, otherwise we keep everything. + // If it's not `#[doc(inline)]`, we don't want all attributes, otherwise we keep everything. if !is_inline { attrs.extend_from_slice(new_attrs); return; @@ -2374,26 +2381,43 @@ fn clean_maybe_renamed_item<'tcx>( _ => unreachable!("not yet converted"), }; - let mut import_attrs = Vec::new(); - let mut target_attrs = Vec::new(); - if let Some(import_id) = import_id && + let attrs = if let Some(import_id) = import_id && let Some(hir::Node::Item(use_node)) = cx.tcx.hir().find_by_def_id(import_id) { - let is_inline = inline::load_attrs(cx, import_id.to_def_id()).lists(sym::doc).get_word_attr(sym::inline).is_some(); + let is_inline = inline::load_attrs(cx, import_id.to_def_id()) + .lists(sym::doc) + .get_word_attr(sym::inline) + .is_some(); // Then we get all the various imports' attributes. - get_all_import_attributes(use_node, cx.tcx, item.owner_id.def_id, &mut import_attrs, is_inline); - add_without_unwanted_attributes(&mut target_attrs, inline::load_attrs(cx, def_id), is_inline); + let mut attrs = get_all_import_attributes( + use_node, + cx, + item.owner_id.def_id, + is_inline, + import_id, + ); + + let mut target_attrs = Vec::new(); + add_without_unwanted_attributes( + &mut target_attrs, + inline::load_attrs(cx, def_id), + is_inline, + ); + for attr in target_attrs.into_iter() { + attrs.push((attr, None)); + } + attrs } else { // We only keep the item's attributes. - target_attrs.extend_from_slice(inline::load_attrs(cx, def_id)); - } + inline::load_attrs(cx, def_id).iter().cloned().map(|attr| (attr, None)).collect::>() + }; - let import_id = import_id.map(|def_id| def_id.to_def_id()); - let (attrs, cfg) = merge_attrs(cx, &target_attrs, Some((&import_attrs, import_id))); + let cfg = attrs.cfg(cx.tcx, &cx.cache.hidden_cfg); + let attrs = Attributes::from_ast_iter(attrs.iter().map(|(attr, did)| (attr, *did)), false); let mut item = Item::from_def_id_and_attrs_and_parts(def_id, Some(name), kind, Box::new(attrs), cfg); - item.inline_stmt_id = import_id; + item.inline_stmt_id = import_id.map(|local| local.to_def_id()); vec![item] }) } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 7dbb3f76a0a..74831811aa2 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -867,27 +867,16 @@ pub(crate) struct Module { pub(crate) trait AttributesExt { type AttributeIterator<'a>: Iterator + where + Self: 'a; + type Attributes<'a>: Iterator where Self: 'a; fn lists<'a>(&'a self, name: Symbol) -> Self::AttributeIterator<'a>; - fn span(&self) -> Option; + fn iter<'a>(&'a self) -> Self::Attributes<'a>; - fn cfg(&self, tcx: TyCtxt<'_>, hidden_cfg: &FxHashSet) -> Option>; -} - -impl AttributesExt for [ast::Attribute] { - type AttributeIterator<'a> = impl Iterator + 'a; - - fn lists<'a>(&'a self, name: Symbol) -> Self::AttributeIterator<'a> { - self.iter() - .filter(move |attr| attr.has_name(name)) - .filter_map(ast::Attribute::meta_item_list) - .flatten() - } - - /// Return the span of the first doc-comment, if it exists. fn span(&self) -> Option { self.iter().find(|attr| attr.doc_str().is_some()).map(|attr| attr.span) } @@ -980,6 +969,38 @@ impl AttributesExt for [ast::Attribute] { } } +impl AttributesExt for [ast::Attribute] { + type AttributeIterator<'a> = impl Iterator + 'a; + type Attributes<'a> = impl Iterator + 'a; + + fn lists<'a>(&'a self, name: Symbol) -> Self::AttributeIterator<'a> { + self.iter() + .filter(move |attr| attr.has_name(name)) + .filter_map(ast::Attribute::meta_item_list) + .flatten() + } + + fn iter<'a>(&'a self) -> Self::Attributes<'a> { + self.into_iter() + } +} + +impl AttributesExt for [(ast::Attribute, Option)] { + type AttributeIterator<'a> = impl Iterator + 'a; + type Attributes<'a> = impl Iterator + 'a; + + fn lists<'a>(&'a self, name: Symbol) -> Self::AttributeIterator<'a> { + AttributesExt::iter(self) + .filter(move |attr| attr.has_name(name)) + .filter_map(ast::Attribute::meta_item_list) + .flatten() + } + + fn iter<'a>(&'a self) -> Self::Attributes<'a> { + self.into_iter().map(|(attr, _)| attr) + } +} + pub(crate) trait NestedAttributesExt { /// Returns `true` if the attribute list contains a specific `word` fn has_word(self, word: Symbol) -> bool From c8c342c07276e5b1864780ac70b55b52afa3ed60 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 18 Mar 2023 23:27:36 +0100 Subject: [PATCH 100/346] Add regression test for #109282 --- .../rustdoc-ui/issue-109282-import-inline-merge.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 tests/rustdoc-ui/issue-109282-import-inline-merge.rs diff --git a/tests/rustdoc-ui/issue-109282-import-inline-merge.rs b/tests/rustdoc-ui/issue-109282-import-inline-merge.rs new file mode 100644 index 00000000000..0ec8523222f --- /dev/null +++ b/tests/rustdoc-ui/issue-109282-import-inline-merge.rs @@ -0,0 +1,14 @@ +// Regression test for . +// Import for `ValueEnum` is inlined and doc comments on the import and `ValueEnum` itself are +// merged. After the merge they still have correct parent scopes to resolve both `[ValueEnum]`. + +// check-pass + +mod m { + pub enum ValueEnum {} +} +mod m2 { + /// [`ValueEnum`] + pub use crate::m::ValueEnum; +} +pub use m2::ValueEnum; From bec4eab3f972495df32b4861a3117ef16d73a018 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 11 Feb 2023 19:14:25 +0400 Subject: [PATCH 101/346] rustdoc: Skip doc link resolution for non-exported items --- compiler/rustc_resolve/src/late.rs | 5 ++++- compiler/rustc_resolve/src/rustdoc.rs | 16 +++++++++++++++- src/librustdoc/core.rs | 9 ++------- src/librustdoc/passes/collect_intra_doc_links.rs | 13 +++++++++++-- .../intra-doc/reachable-non-exported.rs | 13 +++++++++++++ 5 files changed, 45 insertions(+), 11 deletions(-) create mode 100644 tests/rustdoc-ui/intra-doc/reachable-non-exported.rs diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 6af9dc89e56..4ca54bab31a 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -4236,7 +4236,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { { return; } - ResolveDocLinks::Exported if !maybe_exported.eval(self.r) => { + ResolveDocLinks::Exported + if !maybe_exported.eval(self.r) + && !rustdoc::has_primitive_or_keyword_docs(attrs) => + { return; } ResolveDocLinks::ExportedMetadata diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs index 0e40f794f18..44a27bbc175 100644 --- a/compiler/rustc_resolve/src/rustdoc.rs +++ b/compiler/rustc_resolve/src/rustdoc.rs @@ -3,7 +3,7 @@ use rustc_ast as ast; use rustc_ast::util::comments::beautify_doc_string; use rustc_data_structures::fx::FxHashMap; use rustc_span::def_id::DefId; -use rustc_span::symbol::{kw, Symbol}; +use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; use std::{cmp, mem}; @@ -339,6 +339,20 @@ pub fn inner_docs(attrs: &[ast::Attribute]) -> bool { attrs.iter().find(|a| a.doc_str().is_some()).map_or(true, |a| a.style == ast::AttrStyle::Inner) } +/// Has `#[doc(primitive)]` or `#[doc(keyword)]`. +pub fn has_primitive_or_keyword_docs(attrs: &[ast::Attribute]) -> bool { + for attr in attrs { + if attr.has_name(sym::doc) && let Some(items) = attr.meta_item_list() { + for item in items { + if item.has_name(sym::primitive) || item.has_name(sym::keyword) { + return true; + } + } + } + } + false +} + /// Simplified version of the corresponding function in rustdoc. /// If the rustdoc version returns a successful result, this function must return the same result. /// Otherwise this function may return anything. diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index fbfc58a436b..28458f32903 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -217,13 +217,8 @@ pub(crate) fn create_config( let crate_types = if proc_macro_crate { vec![CrateType::ProcMacro] } else { vec![CrateType::Rlib] }; - let resolve_doc_links = if *document_private { - ResolveDocLinks::All - } else { - // Should be `ResolveDocLinks::Exported` in theory, but for some reason rustdoc - // still tries to request resolutions for links on private items. - ResolveDocLinks::All - }; + let resolve_doc_links = + if *document_private { ResolveDocLinks::All } else { ResolveDocLinks::Exported }; let test = scrape_examples_options.map(|opts| opts.scrape_tests).unwrap_or(false); // plays with error output here! let sessopts = config::Options { diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 789523c561e..d98cf251e97 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -15,8 +15,8 @@ use rustc_hir::def_id::{DefId, CRATE_DEF_ID}; use rustc_hir::Mutability; use rustc_middle::ty::{fast_reject::TreatProjections, Ty, TyCtxt}; use rustc_middle::{bug, ty}; -use rustc_resolve::rustdoc::MalformedGenerics; -use rustc_resolve::rustdoc::{prepare_to_doc_link_resolution, strip_generics_from_path}; +use rustc_resolve::rustdoc::{has_primitive_or_keyword_docs, prepare_to_doc_link_resolution}; +use rustc_resolve::rustdoc::{strip_generics_from_path, MalformedGenerics}; use rustc_session::lint::Lint; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{sym, Ident, Symbol}; @@ -899,6 +899,15 @@ fn preprocessed_markdown_links(s: &str) -> Vec { impl LinkCollector<'_, '_> { fn resolve_links(&mut self, item: &Item) { + if !self.cx.render_options.document_private + && let Some(def_id) = item.item_id.as_def_id() + && let Some(def_id) = def_id.as_local() + && !self.cx.tcx.effective_visibilities(()).is_exported(def_id) + && !has_primitive_or_keyword_docs(&item.attrs.other_attrs) { + // Skip link resolution for non-exported items. + return; + } + // We want to resolve in the lexical scope of the documentation. // In the presence of re-exports, this is not the same as the module of the item. // Rather than merging all documentation into one, resolve it one attribute at a time diff --git a/tests/rustdoc-ui/intra-doc/reachable-non-exported.rs b/tests/rustdoc-ui/intra-doc/reachable-non-exported.rs new file mode 100644 index 00000000000..6afcad4f921 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/reachable-non-exported.rs @@ -0,0 +1,13 @@ +// The structure is reachable, but not exported, so rustdoc +// doesn't attempt to request doc link resolutions on it. + +// check-pass + +mod private { + /// [core::str::FromStr] + pub struct ReachableButNotExported; +} + +pub fn foo() -> private::ReachableButNotExported { + private::ReachableButNotExported +} From de61a789af309f60bd55f989ed6593c8db3f4fa3 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 23 Mar 2023 17:31:26 +0100 Subject: [PATCH 102/346] Use Cow to reduce numbers of memory clone --- src/librustdoc/clean/mod.rs | 54 +++++++++++++++++++---------------- src/librustdoc/clean/types.rs | 14 ++++++--- 2 files changed, 39 insertions(+), 29 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index b419c81301c..dd4e652de06 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -32,6 +32,7 @@ use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{self, ExpnKind}; use std::assert_matches::assert_matches; +use std::borrow::Cow; use std::collections::hash_map::Entry; use std::collections::BTreeMap; use std::default::Default; @@ -2171,26 +2172,25 @@ fn get_all_import_attributes<'hir>( target_def_id: LocalDefId, is_inline: bool, mut prev_import: LocalDefId, -) -> Vec<(ast::Attribute, Option)> { - let mut attributes: Vec<(ast::Attribute, Option)> = Vec::new(); +) -> Vec<(Cow<'hir, ast::Attribute>, Option)> { + let mut attributes: Vec<(Cow<'hir, ast::Attribute>, Option)> = Vec::new(); let mut first = true; let hir_map = cx.tcx.hir(); let mut visitor = OneLevelVisitor::new(hir_map, target_def_id); let mut visited = FxHashSet::default(); - let mut import_attrs = Vec::new(); // If the item is an import and has at least a path with two parts, we go into it. while let hir::ItemKind::Use(path, _) = item.kind && visited.insert(item.hir_id()) { let import_parent = cx.tcx.opt_local_parent(prev_import).map(|def_id| def_id.to_def_id()); if first { // This is the "original" reexport so we get all its attributes without filtering them. - attributes = hir_map.attrs(item.hir_id()).iter().cloned().map(|attr| (attr, import_parent)).collect::>(); + attributes = hir_map.attrs(item.hir_id()) + .iter() + .map(|attr| (Cow::Borrowed(attr), import_parent)) + .collect::>(); first = false; } else { - add_without_unwanted_attributes(&mut import_attrs, hir_map.attrs(item.hir_id()), is_inline); - for attr in import_attrs.drain(..) { - attributes.push((attr, import_parent)); - } + add_without_unwanted_attributes(&mut attributes, hir_map.attrs(item.hir_id()), is_inline, import_parent); } if let Some(i) = visitor.find_target(cx.tcx, item.owner_id.def_id.to_def_id(), path) { @@ -2246,17 +2246,24 @@ fn filter_tokens_from_list( /// * `doc(inline)` /// * `doc(no_inline)` /// * `doc(hidden)` -fn add_without_unwanted_attributes( - attrs: &mut Vec, - new_attrs: &[ast::Attribute], +fn add_without_unwanted_attributes<'hir>( + attrs: &mut Vec<(Cow<'hir, ast::Attribute>, Option)>, + new_attrs: &'hir [ast::Attribute], is_inline: bool, + import_parent: Option, ) { // If it's not `#[doc(inline)]`, we don't want all attributes, otherwise we keep everything. if !is_inline { - attrs.extend_from_slice(new_attrs); + for attr in new_attrs { + attrs.push((Cow::Borrowed(attr), import_parent)); + } return; } for attr in new_attrs { + if matches!(attr.kind, ast::AttrKind::DocComment(..)) { + attrs.push((Cow::Borrowed(attr), import_parent)); + continue; + } let mut attr = attr.clone(); match attr.kind { ast::AttrKind::Normal(ref mut normal) => { @@ -2283,18 +2290,15 @@ fn add_without_unwanted_attributes( ) }); args.tokens = TokenStream::new(tokens); - attrs.push(attr); + attrs.push((Cow::Owned(attr), import_parent)); } ast::AttrArgs::Empty | ast::AttrArgs::Eq(..) => { - attrs.push(attr); - continue; + attrs.push((Cow::Owned(attr), import_parent)); } } } } - ast::AttrKind::DocComment(..) => { - attrs.push(attr); - } + _ => unreachable!(), } } } @@ -2397,23 +2401,23 @@ fn clean_maybe_renamed_item<'tcx>( import_id, ); - let mut target_attrs = Vec::new(); add_without_unwanted_attributes( - &mut target_attrs, + &mut attrs, inline::load_attrs(cx, def_id), is_inline, + None ); - for attr in target_attrs.into_iter() { - attrs.push((attr, None)); - } attrs } else { // We only keep the item's attributes. - inline::load_attrs(cx, def_id).iter().cloned().map(|attr| (attr, None)).collect::>() + inline::load_attrs(cx, def_id).iter().map(|attr| (Cow::Borrowed(attr), None)).collect::>() }; let cfg = attrs.cfg(cx.tcx, &cx.cache.hidden_cfg); - let attrs = Attributes::from_ast_iter(attrs.iter().map(|(attr, did)| (attr, *did)), false); + let attrs = Attributes::from_ast_iter(attrs.iter().map(|(attr, did)| match attr { + Cow::Borrowed(attr) => (*attr, *did), + Cow::Owned(attr) => (attr, *did) + }), false); let mut item = Item::from_def_id_and_attrs_and_parts(def_id, Some(name), kind, Box::new(attrs), cfg); diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 74831811aa2..3e7e311cfc5 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1,3 +1,4 @@ +use std::borrow::Cow; use std::cell::RefCell; use std::default::Default; use std::hash::Hash; @@ -985,9 +986,11 @@ impl AttributesExt for [ast::Attribute] { } } -impl AttributesExt for [(ast::Attribute, Option)] { - type AttributeIterator<'a> = impl Iterator + 'a; - type Attributes<'a> = impl Iterator + 'a; +impl AttributesExt for [(Cow<'_, ast::Attribute>, Option)] { + type AttributeIterator<'a> = impl Iterator + 'a + where Self: 'a; + type Attributes<'a> = impl Iterator + 'a + where Self: 'a; fn lists<'a>(&'a self, name: Symbol) -> Self::AttributeIterator<'a> { AttributesExt::iter(self) @@ -997,7 +1000,10 @@ impl AttributesExt for [(ast::Attribute, Option)] { } fn iter<'a>(&'a self) -> Self::Attributes<'a> { - self.into_iter().map(|(attr, _)| attr) + self.into_iter().map(move |(attr, _)| match attr { + Cow::Borrowed(attr) => *attr, + Cow::Owned(attr) => attr, + }) } } From 87ea9941d530194f9d04ed3bb1472509f786dd4e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 23 Mar 2023 17:37:29 +0100 Subject: [PATCH 103/346] Remove `span` method from AttributesExt trait --- src/librustdoc/clean/types.rs | 4 ---- src/librustdoc/doctest.rs | 5 +++-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 3e7e311cfc5..9019a6c49ec 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -878,10 +878,6 @@ pub(crate) trait AttributesExt { fn iter<'a>(&'a self) -> Self::Attributes<'a>; - fn span(&self) -> Option { - self.iter().find(|attr| attr.doc_str().is_some()).map(|attr| attr.span) - } - fn cfg(&self, tcx: TyCtxt<'_>, hidden_cfg: &FxHashSet) -> Option> { let sess = tcx.sess; let doc_cfg_active = tcx.features().doc_cfg; diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index aaa83ecce48..1a896b411ab 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -1239,8 +1239,9 @@ impl<'a, 'hir, 'tcx> HirCollector<'a, 'hir, 'tcx> { if let Some(doc) = attrs.collapsed_doc_value() { // Use the outermost invocation, so that doctest names come from where the docs were written. let span = ast_attrs - .span() - .map(|span| span.ctxt().outer_expn().expansion_cause().unwrap_or(span)) + .iter() + .find(|attr| attr.doc_str().is_some()) + .map(|attr| attr.span.ctxt().outer_expn().expansion_cause().unwrap_or(attr.span)) .unwrap_or(DUMMY_SP); self.collector.set_position(span); markdown::find_testable_code( From 17f1db672ef5fa3200a2e21791ad3ed3d174b6ac Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 29 Jan 2023 15:16:18 +0000 Subject: [PATCH 104/346] Extract parse_stability and parse_unstability. --- compiler/rustc_attr/src/builtin.rs | 429 +++++++++++++++-------------- 1 file changed, 224 insertions(+), 205 deletions(-) diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index d6dbdd3975e..08d75d85779 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -245,15 +245,13 @@ fn find_stability_generic<'a, I>( where I: Iterator, { - use StabilityLevel::*; - let mut stab: Option<(Stability, Span)> = None; let mut const_stab: Option<(ConstStability, Span)> = None; let mut body_stab: Option<(DefaultBodyStability, Span)> = None; let mut promotable = false; let mut allowed_through_unstable_modules = false; - 'outer: for attr in attrs_iter { + for attr in attrs_iter { if ![ sym::rustc_const_unstable, sym::rustc_const_stable, @@ -275,27 +273,7 @@ where promotable = true; } else if attr.has_name(sym::rustc_allowed_through_unstable_modules) { allowed_through_unstable_modules = true; - } - // attributes with data - else if let Some(meta @ MetaItem { kind: MetaItemKind::List(metas), .. }) = &meta { - let get = |meta: &MetaItem, item: &mut Option| { - if item.is_some() { - handle_errors( - &sess.parse_sess, - meta.span, - AttrError::MultipleItem(pprust::path_to_string(&meta.path)), - ); - return false; - } - if let Some(v) = meta.value_str() { - *item = Some(v); - true - } else { - sess.emit_err(session_diagnostics::IncorrectMetaItem { span: meta.span }); - false - } - }; - + } else if let Some(meta) = &meta { let meta_name = meta.name_or_empty(); match meta_name { sym::rustc_const_unstable | sym::rustc_default_body_unstable | sym::unstable => { @@ -322,122 +300,18 @@ where break; } - let mut feature = None; - let mut reason = None; - let mut issue = None; - let mut issue_num = None; - let mut is_soft = false; - let mut implied_by = None; - for meta in metas { - let Some(mi) = meta.meta_item() else { - handle_errors( - &sess.parse_sess, - meta.span(), - AttrError::UnsupportedLiteral(UnsupportedLiteralReason::Generic, false), - ); - continue 'outer; - }; - match mi.name_or_empty() { - sym::feature => { - if !get(mi, &mut feature) { - continue 'outer; - } - } - sym::reason => { - if !get(mi, &mut reason) { - continue 'outer; - } - } - sym::issue => { - if !get(mi, &mut issue) { - continue 'outer; - } - - // These unwraps are safe because `get` ensures the meta item - // is a name/value pair string literal. - issue_num = match issue.unwrap().as_str() { - "none" => None, - issue => match issue.parse::() { - Ok(num) => Some(num), - Err(err) => { - sess.emit_err( - session_diagnostics::InvalidIssueString { - span: mi.span, - cause: session_diagnostics::InvalidIssueStringCause::from_int_error_kind( - mi.name_value_literal_span().unwrap(), - err.kind(), - ), - }, - ); - continue 'outer; - } - }, - }; - } - sym::soft => { - if !mi.is_word() { - sess.emit_err(session_diagnostics::SoftNoArgs { - span: mi.span, - }); - } - is_soft = true; - } - sym::implied_by => { - if !get(mi, &mut implied_by) { - continue 'outer; - } - } - _ => { - handle_errors( - &sess.parse_sess, - meta.span(), - AttrError::UnknownMetaItem( - pprust::path_to_string(&mi.path), - &["feature", "reason", "issue", "soft"], - ), - ); - continue 'outer; - } - } - } - - match (feature, reason, issue) { - (Some(feature), reason, Some(_)) => { - if !rustc_lexer::is_ident(feature.as_str()) { - handle_errors( - &sess.parse_sess, - attr.span, - AttrError::NonIdentFeature, - ); - continue; - } - let level = Unstable { - reason: UnstableReason::from_opt_reason(reason), - issue: issue_num, - is_soft, - implied_by, - }; - if sym::unstable == meta_name { - stab = Some((Stability { level, feature }, attr.span)); - } else if sym::rustc_const_unstable == meta_name { - const_stab = Some(( - ConstStability { level, feature, promotable: false }, - attr.span, - )); - } else if sym::rustc_default_body_unstable == meta_name { - body_stab = - Some((DefaultBodyStability { level, feature }, attr.span)); - } else { - unreachable!("Unknown stability attribute {meta_name}"); - } - } - (None, _, _) => { - handle_errors(&sess.parse_sess, attr.span, AttrError::MissingFeature); - continue; - } - _ => { - sess.emit_err(session_diagnostics::MissingIssue { span: attr.span }); - continue; + if let Some((feature, level)) = parse_unstability(sess, attr) { + if sym::unstable == meta_name { + stab = Some((Stability { level, feature }, attr.span)); + } else if sym::rustc_const_unstable == meta_name { + const_stab = Some(( + ConstStability { level, feature, promotable: false }, + attr.span, + )); + } else if sym::rustc_default_body_unstable == meta_name { + body_stab = Some((DefaultBodyStability { level, feature }, attr.span)); + } else { + unreachable!("Unknown stability attribute {meta_name}"); } } } @@ -457,71 +331,14 @@ where ); break; } - - let mut feature = None; - let mut since = None; - for meta in metas { - match meta { - NestedMetaItem::MetaItem(mi) => match mi.name_or_empty() { - sym::feature => { - if !get(mi, &mut feature) { - continue 'outer; - } - } - sym::since => { - if !get(mi, &mut since) { - continue 'outer; - } - } - _ => { - handle_errors( - &sess.parse_sess, - meta.span(), - AttrError::UnknownMetaItem( - pprust::path_to_string(&mi.path), - &["feature", "since"], - ), - ); - continue 'outer; - } - }, - NestedMetaItem::Lit(lit) => { - handle_errors( - &sess.parse_sess, - lit.span, - AttrError::UnsupportedLiteral( - UnsupportedLiteralReason::Generic, - false, - ), - ); - continue 'outer; - } - } - } - - if let Some(s) = since && s.as_str() == VERSION_PLACEHOLDER { - since = Some(rust_version_symbol()); - } - - match (feature, since) { - (Some(feature), Some(since)) => { - let level = Stable { since, allowed_through_unstable_modules: false }; - if sym::stable == meta_name { - stab = Some((Stability { level, feature }, attr.span)); - } else { - const_stab = Some(( - ConstStability { level, feature, promotable: false }, - attr.span, - )); - } - } - (None, _) => { - handle_errors(&sess.parse_sess, attr.span, AttrError::MissingFeature); - continue; - } - _ => { - handle_errors(&sess.parse_sess, attr.span, AttrError::MissingSince); - continue; + if let Some((feature, level)) = parse_stability(sess, attr) { + if sym::stable == meta_name { + stab = Some((Stability { level, feature }, attr.span)); + } else { + const_stab = Some(( + ConstStability { level, feature, promotable: false }, + attr.span, + )); } } } @@ -556,6 +373,208 @@ where (stab, const_stab, body_stab) } +fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, StabilityLevel)> { + let meta = attr.meta()?; + let MetaItem { kind: MetaItemKind::List(ref metas), .. } = meta else { return None }; + let insert = |meta: &MetaItem, item: &mut Option| { + if item.is_some() { + handle_errors( + &sess.parse_sess, + meta.span, + AttrError::MultipleItem(pprust::path_to_string(&meta.path)), + ); + return false; + } + if let Some(v) = meta.value_str() { + *item = Some(v); + true + } else { + sess.emit_err(session_diagnostics::IncorrectMetaItem { span: meta.span }); + false + } + }; + + let mut feature = None; + let mut since = None; + for meta in metas { + let Some(mi) = meta.meta_item() else { + handle_errors( + &sess.parse_sess, + meta.span(), + AttrError::UnsupportedLiteral(UnsupportedLiteralReason::Generic, false), + ); + return None; + }; + + match mi.name_or_empty() { + sym::feature => { + if !insert(mi, &mut feature) { + return None; + } + } + sym::since => { + if !insert(mi, &mut since) { + return None; + } + } + _ => { + handle_errors( + &sess.parse_sess, + meta.span(), + AttrError::UnknownMetaItem( + pprust::path_to_string(&mi.path), + &["feature", "since"], + ), + ); + return None; + } + } + } + + if let Some(s) = since && s.as_str() == VERSION_PLACEHOLDER { + since = Some(rust_version_symbol()); + } + + match (feature, since) { + (Some(feature), Some(since)) => { + let level = StabilityLevel::Stable { since, allowed_through_unstable_modules: false }; + Some((feature, level)) + } + (None, _) => { + handle_errors(&sess.parse_sess, attr.span, AttrError::MissingFeature); + None + } + _ => { + handle_errors(&sess.parse_sess, attr.span, AttrError::MissingSince); + None + } + } +} + +fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, StabilityLevel)> { + let meta = attr.meta()?; + let MetaItem { kind: MetaItemKind::List(ref metas), .. } = meta else { return None }; + let insert = |meta: &MetaItem, item: &mut Option| { + if item.is_some() { + handle_errors( + &sess.parse_sess, + meta.span, + AttrError::MultipleItem(pprust::path_to_string(&meta.path)), + ); + return false; + } + if let Some(v) = meta.value_str() { + *item = Some(v); + true + } else { + sess.emit_err(session_diagnostics::IncorrectMetaItem { span: meta.span }); + false + } + }; + + let mut feature = None; + let mut reason = None; + let mut issue = None; + let mut issue_num = None; + let mut is_soft = false; + let mut implied_by = None; + for meta in metas { + let Some(mi) = meta.meta_item() else { + handle_errors( + &sess.parse_sess, + meta.span(), + AttrError::UnsupportedLiteral(UnsupportedLiteralReason::Generic, false), + ); + return None; + }; + + match mi.name_or_empty() { + sym::feature => { + if !insert(mi, &mut feature) { + return None; + } + } + sym::reason => { + if !insert(mi, &mut reason) { + return None; + } + } + sym::issue => { + if !insert(mi, &mut issue) { + return None; + } + + // These unwraps are safe because `insert` ensures the meta item + // is a name/value pair string literal. + issue_num = match issue.unwrap().as_str() { + "none" => None, + issue => match issue.parse::() { + Ok(num) => Some(num), + Err(err) => { + sess.emit_err( + session_diagnostics::InvalidIssueString { + span: mi.span, + cause: session_diagnostics::InvalidIssueStringCause::from_int_error_kind( + mi.name_value_literal_span().unwrap(), + err.kind(), + ), + }, + ); + return None; + } + }, + }; + } + sym::soft => { + if !mi.is_word() { + sess.emit_err(session_diagnostics::SoftNoArgs { span: mi.span }); + } + is_soft = true; + } + sym::implied_by => { + if !insert(mi, &mut implied_by) { + return None; + } + } + _ => { + handle_errors( + &sess.parse_sess, + meta.span(), + AttrError::UnknownMetaItem( + pprust::path_to_string(&mi.path), + &["feature", "reason", "issue", "soft", "implied_by"], + ), + ); + return None; + } + } + } + + match (feature, reason, issue) { + (Some(feature), reason, Some(_)) => { + if !rustc_lexer::is_ident(feature.as_str()) { + handle_errors(&sess.parse_sess, attr.span, AttrError::NonIdentFeature); + return None; + } + let level = StabilityLevel::Unstable { + reason: UnstableReason::from_opt_reason(reason), + issue: issue_num, + is_soft, + implied_by, + }; + Some((feature, level)) + } + (None, _, _) => { + handle_errors(&sess.parse_sess, attr.span, AttrError::MissingFeature); + return None; + } + _ => { + sess.emit_err(session_diagnostics::MissingIssue { span: attr.span }); + return None; + } + } +} + pub fn find_crate_name(attrs: &[Attribute]) -> Option { attr::first_attr_value_str_by_name(attrs, sym::crate_name) } From 5f9c004d355ecff847743de3c6a16e8f3c17ef71 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 29 Jan 2023 15:56:47 +0000 Subject: [PATCH 105/346] Separate find_*_stability. --- compiler/rustc_attr/src/builtin.rs | 210 +++++++++++-------------- compiler/rustc_expand/src/base.rs | 4 +- compiler/rustc_passes/src/stability.rs | 8 +- 3 files changed, 103 insertions(+), 119 deletions(-) diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 08d75d85779..ccc5eedfe26 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -232,126 +232,33 @@ pub fn find_stability( sess: &Session, attrs: &[Attribute], item_sp: Span, -) -> (Option<(Stability, Span)>, Option<(ConstStability, Span)>, Option<(DefaultBodyStability, Span)>) -{ - find_stability_generic(sess, attrs.iter(), item_sp) -} - -fn find_stability_generic<'a, I>( - sess: &Session, - attrs_iter: I, - item_sp: Span, -) -> (Option<(Stability, Span)>, Option<(ConstStability, Span)>, Option<(DefaultBodyStability, Span)>) -where - I: Iterator, -{ +) -> Option<(Stability, Span)> { let mut stab: Option<(Stability, Span)> = None; - let mut const_stab: Option<(ConstStability, Span)> = None; - let mut body_stab: Option<(DefaultBodyStability, Span)> = None; - let mut promotable = false; let mut allowed_through_unstable_modules = false; - for attr in attrs_iter { - if ![ - sym::rustc_const_unstable, - sym::rustc_const_stable, - sym::unstable, - sym::stable, - sym::rustc_promotable, - sym::rustc_allowed_through_unstable_modules, - sym::rustc_default_body_unstable, - ] - .iter() - .any(|&s| attr.has_name(s)) - { - continue; // not a stability level - } - - let meta = attr.meta(); - - if attr.has_name(sym::rustc_promotable) { - promotable = true; - } else if attr.has_name(sym::rustc_allowed_through_unstable_modules) { - allowed_through_unstable_modules = true; - } else if let Some(meta) = &meta { - let meta_name = meta.name_or_empty(); - match meta_name { - sym::rustc_const_unstable | sym::rustc_default_body_unstable | sym::unstable => { - if meta_name == sym::unstable && stab.is_some() { - handle_errors( - &sess.parse_sess, - attr.span, - AttrError::MultipleStabilityLevels, - ); - break; - } else if meta_name == sym::rustc_const_unstable && const_stab.is_some() { - handle_errors( - &sess.parse_sess, - attr.span, - AttrError::MultipleStabilityLevels, - ); - break; - } else if meta_name == sym::rustc_default_body_unstable && body_stab.is_some() { - handle_errors( - &sess.parse_sess, - attr.span, - AttrError::MultipleStabilityLevels, - ); - break; - } - - if let Some((feature, level)) = parse_unstability(sess, attr) { - if sym::unstable == meta_name { - stab = Some((Stability { level, feature }, attr.span)); - } else if sym::rustc_const_unstable == meta_name { - const_stab = Some(( - ConstStability { level, feature, promotable: false }, - attr.span, - )); - } else if sym::rustc_default_body_unstable == meta_name { - body_stab = Some((DefaultBodyStability { level, feature }, attr.span)); - } else { - unreachable!("Unknown stability attribute {meta_name}"); - } - } + for attr in attrs { + match attr.name_or_empty() { + sym::rustc_allowed_through_unstable_modules => allowed_through_unstable_modules = true, + sym::unstable => { + if stab.is_some() { + handle_errors(&sess.parse_sess, attr.span, AttrError::MultipleStabilityLevels); + break; } - sym::rustc_const_stable | sym::stable => { - if meta_name == sym::stable && stab.is_some() { - handle_errors( - &sess.parse_sess, - attr.span, - AttrError::MultipleStabilityLevels, - ); - break; - } else if meta_name == sym::rustc_const_stable && const_stab.is_some() { - handle_errors( - &sess.parse_sess, - attr.span, - AttrError::MultipleStabilityLevels, - ); - break; - } - if let Some((feature, level)) = parse_stability(sess, attr) { - if sym::stable == meta_name { - stab = Some((Stability { level, feature }, attr.span)); - } else { - const_stab = Some(( - ConstStability { level, feature, promotable: false }, - attr.span, - )); - } - } + + if let Some((feature, level)) = parse_unstability(sess, attr) { + stab = Some((Stability { level, feature }, attr.span)); } - _ => unreachable!(), } - } - } - - // Merge the const-unstable info into the stability info - if promotable { - match &mut const_stab { - Some((stab, _)) => stab.promotable = promotable, - _ => _ = sess.emit_err(session_diagnostics::RustcPromotablePairing { span: item_sp }), + sym::stable => { + if stab.is_some() { + handle_errors(&sess.parse_sess, attr.span, AttrError::MultipleStabilityLevels); + break; + } + if let Some((feature, level)) = parse_stability(sess, attr) { + stab = Some((Stability { level, feature }, attr.span)); + } + } + _ => {} } } @@ -370,7 +277,80 @@ where } } - (stab, const_stab, body_stab) + stab +} + +/// Collects stability info from all stability attributes in `attrs`. +/// Returns `None` if no stability attributes are found. +pub fn find_const_stability( + sess: &Session, + attrs: &[Attribute], + item_sp: Span, +) -> Option<(ConstStability, Span)> { + let mut const_stab: Option<(ConstStability, Span)> = None; + let mut promotable = false; + + for attr in attrs { + match attr.name_or_empty() { + sym::rustc_promotable => promotable = true, + sym::rustc_const_unstable => { + if const_stab.is_some() { + handle_errors(&sess.parse_sess, attr.span, AttrError::MultipleStabilityLevels); + break; + } + + if let Some((feature, level)) = parse_unstability(sess, attr) { + const_stab = + Some((ConstStability { level, feature, promotable: false }, attr.span)); + } + } + sym::rustc_const_stable => { + if const_stab.is_some() { + handle_errors(&sess.parse_sess, attr.span, AttrError::MultipleStabilityLevels); + break; + } + if let Some((feature, level)) = parse_stability(sess, attr) { + const_stab = + Some((ConstStability { level, feature, promotable: false }, attr.span)); + } + } + _ => {} + } + } + + // Merge the const-unstable info into the stability info + if promotable { + match &mut const_stab { + Some((stab, _)) => stab.promotable = promotable, + _ => _ = sess.emit_err(session_diagnostics::RustcPromotablePairing { span: item_sp }), + } + } + + const_stab +} + +/// Collects stability info from all stability attributes in `attrs`. +/// Returns `None` if no stability attributes are found. +pub fn find_body_stability( + sess: &Session, + attrs: &[Attribute], +) -> Option<(DefaultBodyStability, Span)> { + let mut body_stab: Option<(DefaultBodyStability, Span)> = None; + + for attr in attrs { + if attr.has_name(sym::rustc_default_body_unstable) { + if body_stab.is_some() { + handle_errors(&sess.parse_sess, attr.span, AttrError::MultipleStabilityLevels); + break; + } + + if let Some((feature, level)) = parse_unstability(sess, attr) { + body_stab = Some((DefaultBodyStability { level, feature }, attr.span)); + } + } + } + + body_stab } fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, StabilityLevel)> { diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index d32af10914e..caa2a201c75 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -793,7 +793,9 @@ impl SyntaxExtension { ) }) .unwrap_or_else(|| (None, helper_attrs)); - let (stability, const_stability, body_stability) = attr::find_stability(&sess, attrs, span); + let stability = attr::find_stability(&sess, attrs, span); + let const_stability = attr::find_const_stability(&sess, attrs, span); + let body_stability = attr::find_body_stability(&sess, attrs); if let Some((_, sp)) = const_stability { sess.emit_err(errors::MacroConstStability { span: sp, diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index 6d0cfea00d1..4a1ba19c920 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -159,7 +159,9 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> { return; } - let (stab, const_stab, body_stab) = attr::find_stability(&self.tcx.sess, attrs, item_sp); + let stab = attr::find_stability(&self.tcx.sess, attrs, item_sp); + let const_stab = attr::find_const_stability(&self.tcx.sess, attrs, item_sp); + let body_stab = attr::find_body_stability(&self.tcx.sess, attrs); let mut const_span = None; let const_stab = const_stab.map(|(const_stab, const_span_node)| { @@ -742,8 +744,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { let features = self.tcx.features(); if features.staged_api { let attrs = self.tcx.hir().attrs(item.hir_id()); - let (stab, const_stab, _) = - attr::find_stability(&self.tcx.sess, attrs, item.span); + let stab = attr::find_stability(&self.tcx.sess, attrs, item.span); + let const_stab = attr::find_const_stability(&self.tcx.sess, attrs, item.span); // If this impl block has an #[unstable] attribute, give an // error if all involved types and traits are stable, because From d7d3dbf06022c3ec020c3906afa0090ad5ae239c Mon Sep 17 00:00:00 2001 From: "Samuel \"Sam\" Tardieu" Date: Sat, 11 Mar 2023 12:44:18 +0100 Subject: [PATCH 106/346] New lint: detect unnecessary struct building --- CHANGELOG.md | 1 + clippy_lints/src/declared_lints.rs | 1 + clippy_lints/src/lib.rs | 2 + .../src/unnecessary_struct_initialization.rs | 84 +++++++++++++++++++ tests/ui/needless_update.rs | 2 +- tests/ui/no_effect.rs | 7 +- tests/ui/no_effect.stderr | 60 ++++++------- tests/ui/unnecessary_operation.fixed | 8 +- tests/ui/unnecessary_operation.rs | 8 +- tests/ui/unnecessary_operation.stderr | 40 ++++----- .../unnecessary_struct_initialization.fixed | 73 ++++++++++++++++ tests/ui/unnecessary_struct_initialization.rs | 77 +++++++++++++++++ .../unnecessary_struct_initialization.stderr | 46 ++++++++++ 13 files changed, 355 insertions(+), 54 deletions(-) create mode 100644 clippy_lints/src/unnecessary_struct_initialization.rs create mode 100644 tests/ui/unnecessary_struct_initialization.fixed create mode 100644 tests/ui/unnecessary_struct_initialization.rs create mode 100644 tests/ui/unnecessary_struct_initialization.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index 47a503510c1..1323f973ccf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4987,6 +4987,7 @@ Released 2018-09-13 [`unnecessary_safety_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_safety_doc [`unnecessary_self_imports`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_self_imports [`unnecessary_sort_by`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_sort_by +[`unnecessary_struct_initialization`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_struct_initialization [`unnecessary_to_owned`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_to_owned [`unnecessary_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_unwrap [`unnecessary_wraps`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_wraps diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 2331e857b1f..8ca91301472 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -618,6 +618,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::unnamed_address::VTABLE_ADDRESS_COMPARISONS_INFO, crate::unnecessary_owned_empty_strings::UNNECESSARY_OWNED_EMPTY_STRINGS_INFO, crate::unnecessary_self_imports::UNNECESSARY_SELF_IMPORTS_INFO, + crate::unnecessary_struct_initialization::UNNECESSARY_STRUCT_INITIALIZATION_INFO, crate::unnecessary_wraps::UNNECESSARY_WRAPS_INFO, crate::unnested_or_patterns::UNNESTED_OR_PATTERNS_INFO, crate::unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME_INFO, diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 100cba45679..c9210bf73f8 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -302,6 +302,7 @@ mod unit_types; mod unnamed_address; mod unnecessary_owned_empty_strings; mod unnecessary_self_imports; +mod unnecessary_struct_initialization; mod unnecessary_wraps; mod unnested_or_patterns; mod unsafe_removed_from_name; @@ -938,6 +939,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: store.register_late_pass(|_| Box::new(let_with_type_underscore::UnderscoreTyped)); store.register_late_pass(|_| Box::new(allow_attributes::AllowAttribute)); store.register_late_pass(move |_| Box::new(manual_main_separator_str::ManualMainSeparatorStr::new(msrv()))); + store.register_late_pass(|_| Box::new(unnecessary_struct_initialization::UnnecessaryStruct)); // add lints here, do not remove this comment, it's used in `new_lint` } diff --git a/clippy_lints/src/unnecessary_struct_initialization.rs b/clippy_lints/src/unnecessary_struct_initialization.rs new file mode 100644 index 00000000000..af0b4b1592f --- /dev/null +++ b/clippy_lints/src/unnecessary_struct_initialization.rs @@ -0,0 +1,84 @@ +use clippy_utils::{diagnostics::span_lint_and_sugg, get_parent_expr, path_to_local, source::snippet, ty::is_copy}; +use rustc_hir::{BindingAnnotation, Expr, ExprKind, Node, PatKind, UnOp}; +use rustc_lint::{LateContext, LateLintPass}; +use rustc_session::{declare_lint_pass, declare_tool_lint}; + +declare_clippy_lint! { + /// ### What it does + /// Checks for initialization of a `struct` by copying a base without setting + /// any field. + /// + /// ### Why is this bad? + /// Readibility suffers from unnecessary struct building. + /// + /// ### Example + /// ```rust + /// struct S { s: String } + /// + /// let a = S { s: String::from("Hello, world!") }; + /// let b = S { ..a }; + /// ``` + /// Use instead: + /// ```rust + /// struct S { s: String } + /// + /// let a = S { s: String::from("Hello, world!") }; + /// let b = a; + /// ``` + #[clippy::version = "1.70.0"] + pub UNNECESSARY_STRUCT_INITIALIZATION, + complexity, + "struct built from a base that can be written mode concisely" +} +declare_lint_pass!(UnnecessaryStruct => [UNNECESSARY_STRUCT_INITIALIZATION]); + +impl LateLintPass<'_> for UnnecessaryStruct { + fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) { + if let ExprKind::Struct(_, &[], Some(base)) = expr.kind { + if let Some(parent) = get_parent_expr(cx, expr) && + let parent_ty = cx.typeck_results().expr_ty_adjusted(parent) && + parent_ty.is_any_ptr() + { + if is_copy(cx, cx.typeck_results().expr_ty(expr)) && path_to_local(base).is_some() { + // When the type implements `Copy`, a reference to the new struct works on the + // copy. Using the original would borrow it. + return; + } + + if parent_ty.is_mutable_ptr() && !is_mutable(cx, base) { + // The original can be used in a mutable reference context only if it is mutable. + return; + } + } + + // TODO: do not propose to replace *XX if XX is not Copy + if let ExprKind::Unary(UnOp::Deref, target) = base.kind && + matches!(target.kind, ExprKind::Path(..)) && + !is_copy(cx, cx.typeck_results().expr_ty(expr)) + { + // `*base` cannot be used instead of the struct in the general case if it is not Copy. + return; + } + + span_lint_and_sugg( + cx, + UNNECESSARY_STRUCT_INITIALIZATION, + expr.span, + "unnecessary struct building", + "replace with", + snippet(cx, base.span, "..").into_owned(), + rustc_errors::Applicability::MachineApplicable, + ); + } + } +} + +fn is_mutable(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { + if let Some(hir_id) = path_to_local(expr) && + let Node::Pat(pat) = cx.tcx.hir().get(hir_id) + { + matches!(pat.kind, PatKind::Binding(BindingAnnotation::MUT, ..)) + } else { + true + } +} diff --git a/tests/ui/needless_update.rs b/tests/ui/needless_update.rs index b93ff048a62..4e8517cad10 100644 --- a/tests/ui/needless_update.rs +++ b/tests/ui/needless_update.rs @@ -1,5 +1,5 @@ #![warn(clippy::needless_update)] -#![allow(clippy::no_effect)] +#![allow(clippy::no_effect, clippy::unnecessary_struct_initialization)] struct S { pub a: i32, diff --git a/tests/ui/no_effect.rs b/tests/ui/no_effect.rs index f08eb092e6b..ac8b1e756f2 100644 --- a/tests/ui/no_effect.rs +++ b/tests/ui/no_effect.rs @@ -1,7 +1,12 @@ #![feature(box_syntax, fn_traits, unboxed_closures)] #![warn(clippy::no_effect_underscore_binding)] #![allow(dead_code, path_statements)] -#![allow(clippy::deref_addrof, clippy::redundant_field_names, clippy::uninlined_format_args)] +#![allow( + clippy::deref_addrof, + clippy::redundant_field_names, + clippy::uninlined_format_args, + clippy::unnecessary_struct_initialization +)] struct Unit; struct Tuple(i32); diff --git a/tests/ui/no_effect.stderr b/tests/ui/no_effect.stderr index 6a1e636f9a6..2efefd2b2a3 100644 --- a/tests/ui/no_effect.stderr +++ b/tests/ui/no_effect.stderr @@ -1,5 +1,5 @@ error: statement with no effect - --> $DIR/no_effect.rs:92:5 + --> $DIR/no_effect.rs:97:5 | LL | 0; | ^^ @@ -7,157 +7,157 @@ LL | 0; = note: `-D clippy::no-effect` implied by `-D warnings` error: statement with no effect - --> $DIR/no_effect.rs:93:5 + --> $DIR/no_effect.rs:98:5 | LL | s2; | ^^^ error: statement with no effect - --> $DIR/no_effect.rs:94:5 + --> $DIR/no_effect.rs:99:5 | LL | Unit; | ^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:95:5 + --> $DIR/no_effect.rs:100:5 | LL | Tuple(0); | ^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:96:5 + --> $DIR/no_effect.rs:101:5 | LL | Struct { field: 0 }; | ^^^^^^^^^^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:97:5 + --> $DIR/no_effect.rs:102:5 | LL | Struct { ..s }; | ^^^^^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:98:5 + --> $DIR/no_effect.rs:103:5 | LL | Union { a: 0 }; | ^^^^^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:99:5 + --> $DIR/no_effect.rs:104:5 | LL | Enum::Tuple(0); | ^^^^^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:100:5 + --> $DIR/no_effect.rs:105:5 | LL | Enum::Struct { field: 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:101:5 + --> $DIR/no_effect.rs:106:5 | LL | 5 + 6; | ^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:102:5 + --> $DIR/no_effect.rs:107:5 | LL | *&42; | ^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:103:5 + --> $DIR/no_effect.rs:108:5 | LL | &6; | ^^^ error: statement with no effect - --> $DIR/no_effect.rs:104:5 + --> $DIR/no_effect.rs:109:5 | LL | (5, 6, 7); | ^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:105:5 + --> $DIR/no_effect.rs:110:5 | LL | box 42; | ^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:106:5 + --> $DIR/no_effect.rs:111:5 | LL | ..; | ^^^ error: statement with no effect - --> $DIR/no_effect.rs:107:5 + --> $DIR/no_effect.rs:112:5 | LL | 5..; | ^^^^ error: statement with no effect - --> $DIR/no_effect.rs:108:5 + --> $DIR/no_effect.rs:113:5 | LL | ..5; | ^^^^ error: statement with no effect - --> $DIR/no_effect.rs:109:5 + --> $DIR/no_effect.rs:114:5 | LL | 5..6; | ^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:110:5 + --> $DIR/no_effect.rs:115:5 | LL | 5..=6; | ^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:111:5 + --> $DIR/no_effect.rs:116:5 | LL | [42, 55]; | ^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:112:5 + --> $DIR/no_effect.rs:117:5 | LL | [42, 55][1]; | ^^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:113:5 + --> $DIR/no_effect.rs:118:5 | LL | (42, 55).1; | ^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:114:5 + --> $DIR/no_effect.rs:119:5 | LL | [42; 55]; | ^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:115:5 + --> $DIR/no_effect.rs:120:5 | LL | [42; 55][13]; | ^^^^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:117:5 + --> $DIR/no_effect.rs:122:5 | LL | || x += 5; | ^^^^^^^^^^ error: statement with no effect - --> $DIR/no_effect.rs:119:5 + --> $DIR/no_effect.rs:124:5 | LL | FooString { s: s }; | ^^^^^^^^^^^^^^^^^^^ error: binding to `_` prefixed variable with no side-effect - --> $DIR/no_effect.rs:120:5 + --> $DIR/no_effect.rs:125:5 | LL | let _unused = 1; | ^^^^^^^^^^^^^^^^ @@ -165,19 +165,19 @@ LL | let _unused = 1; = note: `-D clippy::no-effect-underscore-binding` implied by `-D warnings` error: binding to `_` prefixed variable with no side-effect - --> $DIR/no_effect.rs:121:5 + --> $DIR/no_effect.rs:126:5 | LL | let _penguin = || println!("Some helpful closure"); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: binding to `_` prefixed variable with no side-effect - --> $DIR/no_effect.rs:122:5 + --> $DIR/no_effect.rs:127:5 | LL | let _duck = Struct { field: 0 }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: binding to `_` prefixed variable with no side-effect - --> $DIR/no_effect.rs:123:5 + --> $DIR/no_effect.rs:128:5 | LL | let _cat = [2, 4, 6, 8][2]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/unnecessary_operation.fixed b/tests/ui/unnecessary_operation.fixed index d37163570ab..ec931c726ee 100644 --- a/tests/ui/unnecessary_operation.fixed +++ b/tests/ui/unnecessary_operation.fixed @@ -1,7 +1,13 @@ // run-rustfix #![feature(box_syntax)] -#![allow(clippy::deref_addrof, dead_code, unused, clippy::no_effect)] +#![allow( + clippy::deref_addrof, + dead_code, + unused, + clippy::no_effect, + clippy::unnecessary_struct_initialization +)] #![warn(clippy::unnecessary_operation)] struct Tuple(i32); diff --git a/tests/ui/unnecessary_operation.rs b/tests/ui/unnecessary_operation.rs index a14fd4bca0e..d896df32e41 100644 --- a/tests/ui/unnecessary_operation.rs +++ b/tests/ui/unnecessary_operation.rs @@ -1,7 +1,13 @@ // run-rustfix #![feature(box_syntax)] -#![allow(clippy::deref_addrof, dead_code, unused, clippy::no_effect)] +#![allow( + clippy::deref_addrof, + dead_code, + unused, + clippy::no_effect, + clippy::unnecessary_struct_initialization +)] #![warn(clippy::unnecessary_operation)] struct Tuple(i32); diff --git a/tests/ui/unnecessary_operation.stderr b/tests/ui/unnecessary_operation.stderr index f66d08ecb82..c183082ec86 100644 --- a/tests/ui/unnecessary_operation.stderr +++ b/tests/ui/unnecessary_operation.stderr @@ -1,5 +1,5 @@ error: unnecessary operation - --> $DIR/unnecessary_operation.rs:51:5 + --> $DIR/unnecessary_operation.rs:57:5 | LL | Tuple(get_number()); | ^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` @@ -7,109 +7,109 @@ LL | Tuple(get_number()); = note: `-D clippy::unnecessary-operation` implied by `-D warnings` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:52:5 + --> $DIR/unnecessary_operation.rs:58:5 | LL | Struct { field: get_number() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:53:5 + --> $DIR/unnecessary_operation.rs:59:5 | LL | Struct { ..get_struct() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_struct();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:54:5 + --> $DIR/unnecessary_operation.rs:60:5 | LL | Enum::Tuple(get_number()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:55:5 + --> $DIR/unnecessary_operation.rs:61:5 | LL | Enum::Struct { field: get_number() }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:56:5 + --> $DIR/unnecessary_operation.rs:62:5 | LL | 5 + get_number(); | ^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `5;get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:57:5 + --> $DIR/unnecessary_operation.rs:63:5 | LL | *&get_number(); | ^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:58:5 + --> $DIR/unnecessary_operation.rs:64:5 | LL | &get_number(); | ^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:59:5 + --> $DIR/unnecessary_operation.rs:65:5 | LL | (5, 6, get_number()); | ^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `5;6;get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:60:5 + --> $DIR/unnecessary_operation.rs:66:5 | LL | box get_number(); | ^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:61:5 + --> $DIR/unnecessary_operation.rs:67:5 | LL | get_number()..; | ^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:62:5 + --> $DIR/unnecessary_operation.rs:68:5 | LL | ..get_number(); | ^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:63:5 + --> $DIR/unnecessary_operation.rs:69:5 | LL | 5..get_number(); | ^^^^^^^^^^^^^^^^ help: statement can be reduced to: `5;get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:64:5 + --> $DIR/unnecessary_operation.rs:70:5 | LL | [42, get_number()]; | ^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `42;get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:65:5 + --> $DIR/unnecessary_operation.rs:71:5 | LL | [42, 55][get_usize()]; | ^^^^^^^^^^^^^^^^^^^^^^ help: statement can be written as: `assert!([42, 55].len() > get_usize());` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:66:5 + --> $DIR/unnecessary_operation.rs:72:5 | LL | (42, get_number()).1; | ^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `42;get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:67:5 + --> $DIR/unnecessary_operation.rs:73:5 | LL | [get_number(); 55]; | ^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:68:5 + --> $DIR/unnecessary_operation.rs:74:5 | LL | [42; 55][get_usize()]; | ^^^^^^^^^^^^^^^^^^^^^^ help: statement can be written as: `assert!([42; 55].len() > get_usize());` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:69:5 + --> $DIR/unnecessary_operation.rs:75:5 | LL | / { LL | | get_number() @@ -117,7 +117,7 @@ LL | | }; | |______^ help: statement can be reduced to: `get_number();` error: unnecessary operation - --> $DIR/unnecessary_operation.rs:72:5 + --> $DIR/unnecessary_operation.rs:78:5 | LL | / FooString { LL | | s: String::from("blah"), diff --git a/tests/ui/unnecessary_struct_initialization.fixed b/tests/ui/unnecessary_struct_initialization.fixed new file mode 100644 index 00000000000..b47129e4a36 --- /dev/null +++ b/tests/ui/unnecessary_struct_initialization.fixed @@ -0,0 +1,73 @@ +// run-rustfix + +#![allow(unused)] +#![warn(clippy::unnecessary_struct_initialization)] + +struct S { + f: String, +} + +#[derive(Clone, Copy)] +struct T { + f: u32, +} + +struct U { + f: u32, +} + +impl Clone for U { + fn clone(&self) -> Self { + // Do not lint: `Self` does not implement `Copy` + Self { ..*self } + } +} + +#[derive(Copy)] +struct V { + f: u32, +} + +impl Clone for V { + fn clone(&self) -> Self { + // Lint: `Self` implements `Copy` + *self + } +} + +fn main() { + // Should lint: `a` would be consumed anyway + let a = S { f: String::from("foo") }; + let mut b = a; + + // Should lint: `b` would be consumed, and is mutable + let c = &mut b; + + // Should not lint as `d` is not mutable + let d = S { f: String::from("foo") }; + let e = &mut S { ..d }; + + // Should lint as `f` would be consumed anyway + let f = S { f: String::from("foo") }; + let g = &f; + + // Should lint: the result of an expression is mutable + let h = &mut *Box::new(S { f: String::from("foo") }); + + // Should not lint: `m` would be both alive and borrowed + let m = T { f: 17 }; + let n = &T { ..m }; + + // Should not lint: `m` should not be modified + let o = &mut T { ..m }; + o.f = 32; + assert_eq!(m.f, 17); + + // Should not lint: `m` should not be modified + let o = &mut T { ..m } as *mut T; + unsafe { &mut *o }.f = 32; + assert_eq!(m.f, 17); + + // Should lint: the result of an expression is mutable and temporary + let p = &mut *Box::new(T { f: 5 }); +} diff --git a/tests/ui/unnecessary_struct_initialization.rs b/tests/ui/unnecessary_struct_initialization.rs new file mode 100644 index 00000000000..63b11c626e5 --- /dev/null +++ b/tests/ui/unnecessary_struct_initialization.rs @@ -0,0 +1,77 @@ +// run-rustfix + +#![allow(unused)] +#![warn(clippy::unnecessary_struct_initialization)] + +struct S { + f: String, +} + +#[derive(Clone, Copy)] +struct T { + f: u32, +} + +struct U { + f: u32, +} + +impl Clone for U { + fn clone(&self) -> Self { + // Do not lint: `Self` does not implement `Copy` + Self { ..*self } + } +} + +#[derive(Copy)] +struct V { + f: u32, +} + +impl Clone for V { + fn clone(&self) -> Self { + // Lint: `Self` implements `Copy` + Self { ..*self } + } +} + +fn main() { + // Should lint: `a` would be consumed anyway + let a = S { f: String::from("foo") }; + let mut b = S { ..a }; + + // Should lint: `b` would be consumed, and is mutable + let c = &mut S { ..b }; + + // Should not lint as `d` is not mutable + let d = S { f: String::from("foo") }; + let e = &mut S { ..d }; + + // Should lint as `f` would be consumed anyway + let f = S { f: String::from("foo") }; + let g = &S { ..f }; + + // Should lint: the result of an expression is mutable + let h = &mut S { + ..*Box::new(S { f: String::from("foo") }) + }; + + // Should not lint: `m` would be both alive and borrowed + let m = T { f: 17 }; + let n = &T { ..m }; + + // Should not lint: `m` should not be modified + let o = &mut T { ..m }; + o.f = 32; + assert_eq!(m.f, 17); + + // Should not lint: `m` should not be modified + let o = &mut T { ..m } as *mut T; + unsafe { &mut *o }.f = 32; + assert_eq!(m.f, 17); + + // Should lint: the result of an expression is mutable and temporary + let p = &mut T { + ..*Box::new(T { f: 5 }) + }; +} diff --git a/tests/ui/unnecessary_struct_initialization.stderr b/tests/ui/unnecessary_struct_initialization.stderr new file mode 100644 index 00000000000..ca497057702 --- /dev/null +++ b/tests/ui/unnecessary_struct_initialization.stderr @@ -0,0 +1,46 @@ +error: unnecessary struct building + --> $DIR/unnecessary_struct_initialization.rs:34:9 + | +LL | Self { ..*self } + | ^^^^^^^^^^^^^^^^ help: replace with: `*self` + | + = note: `-D clippy::unnecessary-struct-initialization` implied by `-D warnings` + +error: unnecessary struct building + --> $DIR/unnecessary_struct_initialization.rs:41:17 + | +LL | let mut b = S { ..a }; + | ^^^^^^^^^ help: replace with: `a` + +error: unnecessary struct building + --> $DIR/unnecessary_struct_initialization.rs:44:18 + | +LL | let c = &mut S { ..b }; + | ^^^^^^^^^ help: replace with: `b` + +error: unnecessary struct building + --> $DIR/unnecessary_struct_initialization.rs:52:14 + | +LL | let g = &S { ..f }; + | ^^^^^^^^^ help: replace with: `f` + +error: unnecessary struct building + --> $DIR/unnecessary_struct_initialization.rs:55:18 + | +LL | let h = &mut S { + | __________________^ +LL | | ..*Box::new(S { f: String::from("foo") }) +LL | | }; + | |_____^ help: replace with: `*Box::new(S { f: String::from("foo") })` + +error: unnecessary struct building + --> $DIR/unnecessary_struct_initialization.rs:74:18 + | +LL | let p = &mut T { + | __________________^ +LL | | ..*Box::new(T { f: 5 }) +LL | | }; + | |_____^ help: replace with: `*Box::new(T { f: 5 })` + +error: aborting due to 6 previous errors + From ba3d6055adf0a93800d79ea2281222df81b44b59 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Thu, 23 Mar 2023 14:19:50 -0700 Subject: [PATCH 107/346] rustdoc: clean up `storage.js` This converts a few functions to more compact versions of themselves, and moves `RUSTDOC_MOBILE_BREAKPOINT` to main.js where it's actually used. --- src/librustdoc/html/static/css/rustdoc.css | 2 +- src/librustdoc/html/static/js/main.js | 5 +++ src/librustdoc/html/static/js/storage.js | 37 +++++----------------- 3 files changed, 14 insertions(+), 30 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 7d578b5c775..7e036626efc 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1538,7 +1538,7 @@ However, it's not needed with smaller screen width because the doc/code block is /* WARNING: RUSTDOC_MOBILE_BREAKPOINT MEDIA QUERY If you update this line, then you also need to update the line with the same warning -in storage.js +in main.js */ @media (max-width: 700px) { /* When linking to an item with an `id` (for instance, by clicking a link in the sidebar, diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 403b5004d65..1487ebf9b0a 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -4,6 +4,11 @@ "use strict"; +// WARNING: RUSTDOC_MOBILE_BREAKPOINT MEDIA QUERY +// If you update this line, then you also need to update the media query with the same +// warning in rustdoc.css +window.RUSTDOC_MOBILE_BREAKPOINT = 700; + // Given a basename (e.g. "storage") and an extension (e.g. ".js"), return a URL // for a resource under the root-path, with the resource-suffix. function resourcePath(basename, extension) { diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js index c3fed9a72d4..aa90d9f6be9 100644 --- a/src/librustdoc/html/static/js/storage.js +++ b/src/librustdoc/html/static/js/storage.js @@ -8,29 +8,14 @@ const darkThemes = ["dark", "ayu"]; window.currentTheme = document.getElementById("themeStyle"); -// WARNING: RUSTDOC_MOBILE_BREAKPOINT MEDIA QUERY -// If you update this line, then you also need to update the media query with the same -// warning in rustdoc.css -window.RUSTDOC_MOBILE_BREAKPOINT = 700; - const settingsDataset = (function() { const settingsElement = document.getElementById("default-settings"); - if (settingsElement === null) { - return null; - } - const dataset = settingsElement.dataset; - if (dataset === undefined) { - return null; - } - return dataset; + return settingsElement && settingsElement.dataset ? settingsElement.dataset : null; })(); function getSettingValue(settingName) { const current = getCurrentValue(settingName); - if (current !== null) { - return current; - } - if (settingsDataset !== null) { + if (current === null && settingsDataset !== null) { // See the comment for `default_settings.into_iter()` etc. in // `Options::from_matches` in `librustdoc/config.rs`. const def = settingsDataset[settingName.replace(/-/g,"_")]; @@ -38,7 +23,7 @@ function getSettingValue(settingName) { return def; } } - return null; + return current; } const localStoredTheme = getSettingValue("theme"); @@ -49,18 +34,16 @@ function hasClass(elem, className) { } function addClass(elem, className) { - if (!elem || !elem.classList) { - return; + if (elem && elem.classList) { + elem.classList.add(className); } - elem.classList.add(className); } // eslint-disable-next-line no-unused-vars function removeClass(elem, className) { - if (!elem || !elem.classList) { - return; + if (elem && elem.classList) { + elem.classList.remove(className); } - elem.classList.remove(className); } /** @@ -127,11 +110,7 @@ function getCurrentValue(name) { // Rust to the JS. If there is no such element, return null. const getVar = (function getVar(name) { const el = document.getElementById("rustdoc-vars"); - if (el) { - return el.attributes["data-" + name].value; - } else { - return null; - } + return el ? el.attributes["data-" + name].value : null; }); function switchTheme(newThemeName, saveTheme) { From 95ef91c573c7c49d620688e81ffe1c97fd22501c Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Thu, 23 Mar 2023 14:25:43 -0700 Subject: [PATCH 108/346] rustdoc: remove old `content` hack for theme switching This is based on the compatibility data for `window.matchMedia` and `MediaQueryList`'s `EventTarget` implementation. https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList#browser_compatibility https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia#browser_compatibility * EventTarget would require us to drop support for all Chrome versions before 39. However, we already require Chrome 49, because rustdoc requires [CSS variables]. * EventTarget would also limit us to Firefox 55, but since #106502 rustdoc only supports Firefox > 68. * EventTarget limits us to Mobile Safari version 14, but #102404 shows that our CSS is broken in Safari versions before 15.5. [CSS variables]: https://developer.mozilla.org/en-US/docs/Web/CSS/--*#browser_compatibility --- src/librustdoc/html/static/css/rustdoc.css | 15 --------- src/librustdoc/html/static/js/storage.js | 37 +++------------------- 2 files changed, 5 insertions(+), 47 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 7e036626efc..933a44c5aa7 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -87,21 +87,6 @@ box-sizing: border-box; } -/* This part handles the "default" theme being used depending on the system one. */ -html { - content: ""; -} -@media (prefers-color-scheme: light) { - html { - content: "light"; - } -} -@media (prefers-color-scheme: dark) { - html { - content: "dark"; - } -} - /* General structure and fonts */ body { diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js index aa90d9f6be9..8d82b5b78ed 100644 --- a/src/librustdoc/html/static/js/storage.js +++ b/src/librustdoc/html/static/js/storage.js @@ -137,6 +137,9 @@ function switchTheme(newThemeName, saveTheme) { } const updateTheme = (function() { + // only listen to (prefers-color-scheme: dark) because light is the default + const mql = window.matchMedia("(prefers-color-scheme: dark)"); + /** * Update the current theme to match whatever the current combination of * * the preference for using the system theme @@ -156,7 +159,7 @@ const updateTheme = (function() { const lightTheme = getSettingValue("preferred-light-theme") || "light"; const darkTheme = getSettingValue("preferred-dark-theme") || "dark"; - if (isDarkMode()) { + if (mql.matches) { use(darkTheme, true); } else { // prefers a light theme, or has no preference @@ -170,37 +173,7 @@ const updateTheme = (function() { } } - // This is always updated below to a function () => bool. - let isDarkMode; - - // Determine the function for isDarkMode, and if we have - // `window.matchMedia`, set up an event listener on the preferred color - // scheme. - // - // Otherwise, fall back to the prefers-color-scheme value CSS captured in - // the "content" property. - if (window.matchMedia) { - // only listen to (prefers-color-scheme: dark) because light is the default - const mql = window.matchMedia("(prefers-color-scheme: dark)"); - - isDarkMode = () => mql.matches; - - if (mql.addEventListener) { - mql.addEventListener("change", updateTheme); - } else { - // This is deprecated, see: - // https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList/addListener - mql.addListener(updateTheme); - } - } else { - // fallback to the CSS computed value - const cssContent = getComputedStyle(document.documentElement) - .getPropertyValue("content"); - // (Note: the double-quotes come from that this is a CSS value, which - // might be a length, string, etc.) - const cssColorScheme = cssContent || "\"light\""; - isDarkMode = () => (cssColorScheme === "\"dark\""); - } + mql.addEventListener("change", updateTheme); return updateTheme; })(); From 8ccf53332e2ab70fa4efed5716ddcbb61e98dac2 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Thu, 10 Nov 2022 11:37:28 -0500 Subject: [PATCH 109/346] A MIR transform that checks pointers are aligned --- compiler/rustc_codegen_cranelift/src/base.rs | 12 + compiler/rustc_codegen_ssa/src/mir/block.rs | 7 + .../src/const_eval/machine.rs | 6 + compiler/rustc_hir/src/lang_items.rs | 1 + compiler/rustc_middle/src/mir/mod.rs | 20 +- compiler/rustc_middle/src/mir/syntax.rs | 1 + compiler/rustc_middle/src/mir/visit.rs | 4 + .../src/check_alignment.rs | 220 ++++++++++++++++++ compiler/rustc_mir_transform/src/lib.rs | 2 + compiler/rustc_span/src/symbol.rs | 1 + library/core/src/panicking.rs | 14 ++ .../clippy_utils/src/qualify_min_const_fn.rs | 2 +- src/tools/miri/src/shims/panic.rs | 28 +++ .../fail/unaligned_pointers/alignment.rs | 1 + .../unaligned_pointers/atomic_unaligned.rs | 2 +- .../fail/unaligned_pointers/drop_in_place.rs | 2 + .../fail/unaligned_pointers/dyn_alignment.rs | 2 +- .../intptrcast_alignment_check.rs | 2 +- .../unaligned_pointers/reference_to_packed.rs | 2 +- .../fail/unaligned_pointers/unaligned_ptr1.rs | 2 +- .../fail/unaligned_pointers/unaligned_ptr2.rs | 2 +- .../fail/unaligned_pointers/unaligned_ptr3.rs | 2 +- .../fail/unaligned_pointers/unaligned_ptr4.rs | 2 +- .../unaligned_ptr_addr_of.rs | 2 +- .../unaligned_pointers/unaligned_ptr_zst.rs | 2 +- .../miri/tests/panic/alignment-assertion.rs | 9 + .../tests/panic/alignment-assertion.stderr | 2 + .../tests/pass/disable-alignment-check.rs | 2 +- tests/codegen/issues/issue-37945.rs | 1 + tests/codegen/virtual-function-elimination.rs | 1 + .../inline_into_box_place.main.Inline.diff | 8 +- tests/mir-opt/inline/inline_into_box_place.rs | 1 + tests/run-make/fmt-write-bloat/Makefile | 4 +- tests/ui/mir/mir_alignment_check.rs | 11 + 34 files changed, 360 insertions(+), 20 deletions(-) create mode 100644 compiler/rustc_mir_transform/src/check_alignment.rs create mode 100644 src/tools/miri/tests/panic/alignment-assertion.rs create mode 100644 src/tools/miri/tests/panic/alignment-assertion.stderr create mode 100644 tests/ui/mir/mir_alignment_check.rs diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 2107ae147e9..67ed2b33c5a 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -379,6 +379,18 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) { source_info.span, ); } + AssertKind::MisalignedPointerDereference { ref required, ref found } => { + let required = codegen_operand(fx, required).load_scalar(fx); + let found = codegen_operand(fx, found).load_scalar(fx); + let location = fx.get_caller_location(source_info).load_scalar(fx); + + codegen_panic_inner( + fx, + rustc_hir::LangItem::PanicBoundsCheck, + &[required, found, location], + source_info.span, + ); + } _ => { let msg_str = msg.description(); codegen_panic(fx, msg_str, source_info); diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 5da0e826c56..343ecd3613f 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -600,6 +600,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // and `#[track_caller]` adds an implicit third argument. (LangItem::PanicBoundsCheck, vec![index, len, location]) } + AssertKind::MisalignedPointerDereference { ref required, ref found } => { + let required = self.codegen_operand(bx, required).immediate(); + let found = self.codegen_operand(bx, found).immediate(); + // It's `fn panic_bounds_check(index: usize, len: usize)`, + // and `#[track_caller]` adds an implicit third argument. + (LangItem::PanicMisalignedPointerDereference, vec![required, found, location]) + } _ => { let msg = bx.const_str(msg.description()); // It's `pub fn panic(expr: &str)`, with the wide reference being passed diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index 350ce529ef5..c87ea18af4f 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -544,6 +544,12 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, RemainderByZero(op) => RemainderByZero(eval_to_int(op)?), ResumedAfterReturn(generator_kind) => ResumedAfterReturn(*generator_kind), ResumedAfterPanic(generator_kind) => ResumedAfterPanic(*generator_kind), + MisalignedPointerDereference { ref required, ref found } => { + MisalignedPointerDereference { + required: eval_to_int(required)?, + found: eval_to_int(found)?, + } + } }; Err(ConstEvalErrKind::AssertFailure(err).into()) } diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 0863d65d8f9..8f70c7ce110 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -237,6 +237,7 @@ language_item_table! { PanicDisplay, sym::panic_display, panic_display, Target::Fn, GenericRequirement::None; ConstPanicFmt, sym::const_panic_fmt, const_panic_fmt, Target::Fn, GenericRequirement::None; PanicBoundsCheck, sym::panic_bounds_check, panic_bounds_check_fn, Target::Fn, GenericRequirement::Exact(0); + PanicMisalignedPointerDereference, sym::panic_misaligned_pointer_dereference, panic_misaligned_pointer_dereference_fn, Target::Fn, GenericRequirement::Exact(0); PanicInfo, sym::panic_info, panic_info, Target::Struct, GenericRequirement::None; PanicLocation, sym::panic_location, panic_location, Target::Struct, GenericRequirement::None; PanicImpl, sym::panic_impl, panic_impl, Target::Fn, GenericRequirement::None; diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 9c575f6eb9f..697d4af09f3 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -1277,7 +1277,7 @@ impl AssertKind { /// Getting a description does not require `O` to be printable, and does not /// require allocation. - /// The caller is expected to handle `BoundsCheck` separately. + /// The caller is expected to handle `BoundsCheck` and `MisalignedPointerDereference` separately. pub fn description(&self) -> &'static str { use AssertKind::*; match self { @@ -1296,7 +1296,9 @@ impl AssertKind { ResumedAfterReturn(GeneratorKind::Async(_)) => "`async fn` resumed after completion", ResumedAfterPanic(GeneratorKind::Gen) => "generator resumed after panicking", ResumedAfterPanic(GeneratorKind::Async(_)) => "`async fn` resumed after panicking", - BoundsCheck { .. } => bug!("Unexpected AssertKind"), + BoundsCheck { .. } | MisalignedPointerDereference { .. } => { + bug!("Unexpected AssertKind") + } } } @@ -1353,6 +1355,13 @@ impl AssertKind { Overflow(BinOp::Shl, _, r) => { write!(f, "\"attempt to shift left by `{{}}`, which would overflow\", {:?}", r) } + MisalignedPointerDereference { required, found } => { + write!( + f, + "\"misaligned pointer dereference: address must be a multiple of {{}} but is {{}}\", {:?}, {:?}", + required, found + ) + } _ => write!(f, "\"{}\"", self.description()), } } @@ -1397,6 +1406,13 @@ impl fmt::Debug for AssertKind { Overflow(BinOp::Shl, _, r) => { write!(f, "attempt to shift left by `{:#?}`, which would overflow", r) } + MisalignedPointerDereference { required, found } => { + write!( + f, + "misaligned pointer dereference: address must be a multiple of {:?} but is {:?}", + required, found + ) + } _ => write!(f, "{}", self.description()), } } diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index bbd913d071d..8544b81d57d 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -760,6 +760,7 @@ pub enum AssertKind { RemainderByZero(O), ResumedAfterReturn(GeneratorKind), ResumedAfterPanic(GeneratorKind), + MisalignedPointerDereference { required: O, found: O }, } #[derive(Clone, Debug, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)] diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index cffdd7ff37f..1f72f00cc5a 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -608,6 +608,10 @@ macro_rules! make_mir_visitor { ResumedAfterReturn(_) | ResumedAfterPanic(_) => { // Nothing to visit } + MisalignedPointerDereference { required, found } => { + self.visit_operand(required, location); + self.visit_operand(found, location); + } } } diff --git a/compiler/rustc_mir_transform/src/check_alignment.rs b/compiler/rustc_mir_transform/src/check_alignment.rs new file mode 100644 index 00000000000..d654c973e02 --- /dev/null +++ b/compiler/rustc_mir_transform/src/check_alignment.rs @@ -0,0 +1,220 @@ +use crate::MirPass; +use rustc_hir::def_id::DefId; +use rustc_index::vec::IndexVec; +use rustc_middle::mir::*; +use rustc_middle::mir::{ + interpret::{ConstValue, Scalar}, + visit::{PlaceContext, Visitor}, +}; +use rustc_middle::ty::{Ty, TyCtxt, TypeAndMut}; +use rustc_session::Session; + +pub struct CheckAlignment; + +impl<'tcx> MirPass<'tcx> for CheckAlignment { + fn is_enabled(&self, sess: &Session) -> bool { + sess.opts.debug_assertions + } + + fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + let basic_blocks = body.basic_blocks.as_mut(); + let local_decls = &mut body.local_decls; + + for block in (0..basic_blocks.len()).rev() { + let block = block.into(); + for statement_index in (0..basic_blocks[block].statements.len()).rev() { + let location = Location { block, statement_index }; + let statement = &basic_blocks[block].statements[statement_index]; + let source_info = statement.source_info; + + let mut finder = PointerFinder { + local_decls, + tcx, + pointers: Vec::new(), + def_id: body.source.def_id(), + }; + for (pointer, pointee_ty) in finder.find_pointers(statement) { + debug!("Inserting alignment check for {:?}", pointer.ty(&*local_decls, tcx).ty); + + let new_block = split_block(basic_blocks, location); + insert_alignment_check( + tcx, + local_decls, + &mut basic_blocks[block], + pointer, + pointee_ty, + source_info, + new_block, + ); + } + } + } + } +} + +impl<'tcx, 'a> PointerFinder<'tcx, 'a> { + fn find_pointers(&mut self, statement: &Statement<'tcx>) -> Vec<(Place<'tcx>, Ty<'tcx>)> { + self.pointers.clear(); + self.visit_statement(statement, Location::START); + core::mem::take(&mut self.pointers) + } +} + +struct PointerFinder<'tcx, 'a> { + local_decls: &'a mut LocalDecls<'tcx>, + tcx: TyCtxt<'tcx>, + def_id: DefId, + pointers: Vec<(Place<'tcx>, Ty<'tcx>)>, +} + +impl<'tcx, 'a> Visitor<'tcx> for PointerFinder<'tcx, 'a> { + fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: Location) { + if let PlaceContext::NonUse(_) = context { + return; + } + if !place.is_indirect() { + return; + } + + let pointer = Place::from(place.local); + let pointer_ty = pointer.ty(&*self.local_decls, self.tcx).ty; + + // We only want to check unsafe pointers + if !pointer_ty.is_unsafe_ptr() { + trace!("Indirect, but not an unsafe ptr, not checking {:?}", pointer_ty); + return; + } + + let Some(pointee) = pointer_ty.builtin_deref(true) else { + debug!("Indirect but no builtin deref: {:?}", pointer_ty); + return; + }; + let mut pointee_ty = pointee.ty; + if pointee_ty.is_array() || pointee_ty.is_slice() || pointee_ty.is_str() { + pointee_ty = pointee_ty.sequence_element_type(self.tcx); + } + + if !pointee_ty.is_sized(self.tcx, self.tcx.param_env_reveal_all_normalized(self.def_id)) { + debug!("Unsafe pointer, but unsized: {:?}", pointer_ty); + return; + } + + self.pointers.push((pointer, pointee_ty)) + } +} + +fn split_block( + basic_blocks: &mut IndexVec>, + location: Location, +) -> BasicBlock { + let block_data = &mut basic_blocks[location.block]; + + // Drain every statement after this one and move the current terminator to a new basic block + let new_block = BasicBlockData { + statements: block_data.statements.drain(location.statement_index..).collect(), + terminator: block_data.terminator.take(), + is_cleanup: block_data.is_cleanup, + }; + + basic_blocks.push(new_block) +} + +fn insert_alignment_check<'tcx>( + tcx: TyCtxt<'tcx>, + local_decls: &mut LocalDecls<'tcx>, + block_data: &mut BasicBlockData<'tcx>, + pointer: Place<'tcx>, + pointee_ty: Ty<'tcx>, + source_info: SourceInfo, + new_block: BasicBlock, +) { + // Cast the pointer to a *const () + let const_raw_ptr = tcx.mk_ptr(TypeAndMut { ty: tcx.types.unit, mutbl: Mutability::Not }); + let rvalue = Rvalue::Cast(CastKind::PtrToPtr, Operand::Copy(pointer), const_raw_ptr); + let thin_ptr = local_decls.push(LocalDecl::with_source_info(const_raw_ptr, source_info)).into(); + block_data + .statements + .push(Statement { source_info, kind: StatementKind::Assign(Box::new((thin_ptr, rvalue))) }); + + // Cast the pointer to a usize + let rvalue = Rvalue::Cast(CastKind::Transmute, Operand::Copy(thin_ptr), tcx.types.usize); + let addr = local_decls.push(LocalDecl::with_source_info(tcx.types.usize, source_info)).into(); + block_data + .statements + .push(Statement { source_info, kind: StatementKind::Assign(Box::new((addr, rvalue))) }); + + // Get the alignment of the pointee + let alignment = + local_decls.push(LocalDecl::with_source_info(tcx.types.usize, source_info)).into(); + let rvalue = Rvalue::NullaryOp(NullOp::AlignOf, pointee_ty); + block_data.statements.push(Statement { + source_info, + kind: StatementKind::Assign(Box::new((alignment, rvalue))), + }); + + // Subtract 1 from the alignment to get the alignment mask + let alignment_mask = + local_decls.push(LocalDecl::with_source_info(tcx.types.usize, source_info)).into(); + let one = Operand::Constant(Box::new(Constant { + span: source_info.span, + user_ty: None, + literal: ConstantKind::Val( + ConstValue::Scalar(Scalar::from_target_usize(1, &tcx)), + tcx.types.usize, + ), + })); + block_data.statements.push(Statement { + source_info, + kind: StatementKind::Assign(Box::new(( + alignment_mask, + Rvalue::BinaryOp(BinOp::Sub, Box::new((Operand::Copy(alignment), one))), + ))), + }); + + // BitAnd the alignment mask with the pointer + let alignment_bits = + local_decls.push(LocalDecl::with_source_info(tcx.types.usize, source_info)).into(); + block_data.statements.push(Statement { + source_info, + kind: StatementKind::Assign(Box::new(( + alignment_bits, + Rvalue::BinaryOp( + BinOp::BitAnd, + Box::new((Operand::Copy(addr), Operand::Copy(alignment_mask))), + ), + ))), + }); + + // Check if the alignment bits are all zero + let is_ok = local_decls.push(LocalDecl::with_source_info(tcx.types.bool, source_info)).into(); + let zero = Operand::Constant(Box::new(Constant { + span: source_info.span, + user_ty: None, + literal: ConstantKind::Val( + ConstValue::Scalar(Scalar::from_target_usize(0, &tcx)), + tcx.types.usize, + ), + })); + block_data.statements.push(Statement { + source_info, + kind: StatementKind::Assign(Box::new(( + is_ok, + Rvalue::BinaryOp(BinOp::Eq, Box::new((Operand::Copy(alignment_bits), zero.clone()))), + ))), + }); + + // Set this block's terminator to our assert, continuing to new_block if we pass + block_data.terminator = Some(Terminator { + source_info, + kind: TerminatorKind::Assert { + cond: Operand::Copy(is_ok), + expected: true, + target: new_block, + msg: AssertKind::MisalignedPointerDereference { + required: Operand::Copy(alignment), + found: Operand::Copy(addr), + }, + cleanup: None, + }, + }); +} diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 3a515fe8323..4c30a57c481 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -91,6 +91,7 @@ mod separate_const_switch; mod shim; mod ssa; // This pass is public to allow external drivers to perform MIR cleanup +mod check_alignment; pub mod simplify; mod simplify_branches; mod simplify_comparison_integral; @@ -546,6 +547,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { tcx, body, &[ + &check_alignment::CheckAlignment, &reveal_all::RevealAll, // has to be done before inlining, since inlined code is in RevealAll mode. &lower_slice_len::LowerSliceLenCalls, // has to be done before inlining, otherwise actual call will be almost always inlined. Also simple, so can just do first &unreachable_prop::UnreachablePropagation, diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 4a1abdf6318..e2613341e46 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1067,6 +1067,7 @@ symbols! { panic_implementation, panic_info, panic_location, + panic_misaligned_pointer_dereference, panic_nounwind, panic_runtime, panic_str, diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index dd0105c0eb4..0d060e123b1 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -159,6 +159,20 @@ fn panic_bounds_check(index: usize, len: usize) -> ! { panic!("index out of bounds: the len is {len} but the index is {index}") } +#[cold] +#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))] +#[track_caller] +#[cfg_attr(not(bootstrap), lang = "panic_misaligned_pointer_dereference")] // needed by codegen for panic on misaligned pointer deref +fn panic_misaligned_pointer_dereference(required: usize, found: usize) -> ! { + if cfg!(feature = "panic_immediate_abort") { + super::intrinsics::abort() + } + + panic!( + "misaligned pointer dereference: address must be a multiple of {required:#x} but is {found:#x}" + ) +} + /// Panic because we cannot unwind out of a function. /// /// This function is called directly by the codegen backend, and must not have diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 9f6adf3e3fa..cd9cc8bccb6 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -169,7 +169,7 @@ fn check_rvalue<'tcx>( Err((span, "unsizing casts are not allowed in const fn".into())) } }, - Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => { + Rvalue::Cast(CastKind::PointerExposeAddress | CastKind::PointerAddress, _, _) => { Err((span, "casting pointers to ints is unstable in const fn".into())) }, Rvalue::Cast(CastKind::DynStar, _, _) => { diff --git a/src/tools/miri/src/shims/panic.rs b/src/tools/miri/src/shims/panic.rs index 0ea1137200b..acc97c4b8a0 100644 --- a/src/tools/miri/src/shims/panic.rs +++ b/src/tools/miri/src/shims/panic.rs @@ -220,6 +220,34 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { }, )?; } + MisalignedPointerDereference { required, found } => { + // Forward to `panic_misaligned_pointer_dereference` lang item. + + // First arg: required. + let required = this.read_scalar(&this.eval_operand(required, None)?)?; + // Second arg: found. + let found = this.read_scalar(&this.eval_operand(found, None)?)?; + + // Call the lang item. + let panic_misaligned_pointer_dereference = + this.tcx.lang_items().panic_misaligned_pointer_dereference_fn().unwrap(); + let panic_misaligned_pointer_dereference = + ty::Instance::mono(this.tcx.tcx, panic_misaligned_pointer_dereference); + this.call_function( + panic_misaligned_pointer_dereference, + Abi::Rust, + &[required.into(), found.into()], + None, + StackPopCleanup::Goto { + ret: None, + unwind: match unwind { + Some(cleanup) => StackPopUnwind::Cleanup(cleanup), + None => StackPopUnwind::Skip, + }, + }, + )?; + } + _ => { // Forward everything else to `panic` lang item. this.start_panic( diff --git a/src/tools/miri/tests/fail/unaligned_pointers/alignment.rs b/src/tools/miri/tests/fail/unaligned_pointers/alignment.rs index 438e74e5b8d..6bb95ae4bcb 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/alignment.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/alignment.rs @@ -1,4 +1,5 @@ //@normalize-stderr-test: "\| +\^+" -> "| ^" +//@compile-flags: -Cdebug-assertions=no fn main() { // No retry needed, this fails reliably. diff --git a/src/tools/miri/tests/fail/unaligned_pointers/atomic_unaligned.rs b/src/tools/miri/tests/fail/unaligned_pointers/atomic_unaligned.rs index 9dd652fd821..29976836b0b 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/atomic_unaligned.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/atomic_unaligned.rs @@ -1,4 +1,4 @@ -//@compile-flags: -Zmiri-symbolic-alignment-check +//@compile-flags: -Zmiri-symbolic-alignment-check -Cdebug-assertions=no #![feature(core_intrinsics)] fn main() { diff --git a/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.rs b/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.rs index cf3a558bb99..8a40e527f0e 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.rs @@ -1,3 +1,5 @@ +//@compile-flags: -Cdebug-assertions=no + #[repr(transparent)] struct HasDrop(u8); diff --git a/src/tools/miri/tests/fail/unaligned_pointers/dyn_alignment.rs b/src/tools/miri/tests/fail/unaligned_pointers/dyn_alignment.rs index ca8590cc6b3..6d31ded75c6 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/dyn_alignment.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/dyn_alignment.rs @@ -1,5 +1,5 @@ // should find the bug even without validation and stacked borrows, but gets masked by optimizations -//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -Zmir-opt-level=0 +//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -Zmir-opt-level=0 -Cdebug-assertions=no #[repr(align(256))] #[derive(Debug)] diff --git a/src/tools/miri/tests/fail/unaligned_pointers/intptrcast_alignment_check.rs b/src/tools/miri/tests/fail/unaligned_pointers/intptrcast_alignment_check.rs index da4cadc1c87..c1041ee32a4 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/intptrcast_alignment_check.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/intptrcast_alignment_check.rs @@ -1,4 +1,4 @@ -//@compile-flags: -Zmiri-symbolic-alignment-check -Zmiri-permissive-provenance +//@compile-flags: -Zmiri-symbolic-alignment-check -Zmiri-permissive-provenance -Cdebug-assertions=no // With the symbolic alignment check, even with intptrcast and without // validation, we want to be *sure* to catch bugs that arise from pointers being // insufficiently aligned. The only way to achieve that is not not let programs diff --git a/src/tools/miri/tests/fail/unaligned_pointers/reference_to_packed.rs b/src/tools/miri/tests/fail/unaligned_pointers/reference_to_packed.rs index 4a43db0aac5..4a8cf405ae2 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/reference_to_packed.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/reference_to_packed.rs @@ -1,5 +1,5 @@ // This should fail even without validation/SB -//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows +//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -Cdebug-assertions=no #![allow(dead_code, unused_variables)] diff --git a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr1.rs b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr1.rs index 47d1f782cb6..921bcd6ce24 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr1.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr1.rs @@ -1,5 +1,5 @@ // This should fail even without validation or Stacked Borrows. -//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows +//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -Cdebug-assertions=no fn main() { // Try many times as this might work by chance. diff --git a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr2.rs b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr2.rs index c252944ffb7..8f597659f73 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr2.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr2.rs @@ -1,5 +1,5 @@ // This should fail even without validation or Stacked Borrows. -//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows +//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -Cdebug-assertions=no fn main() { // No retry needed, this fails reliably. diff --git a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr3.rs b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr3.rs index 3aa8cb492a1..a7fcf30c6ea 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr3.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr3.rs @@ -1,5 +1,5 @@ // This should fail even without validation or Stacked Borrows. -//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows +//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -Cdebug-assertions=no fn main() { // Try many times as this might work by chance. diff --git a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr4.rs b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr4.rs index 606316120d6..b8b01e113c9 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr4.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr4.rs @@ -1,5 +1,5 @@ // This should fail even without validation or Stacked Borrows. -//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows +//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -Cdebug-assertions=no fn main() { // Make sure we notice when a u16 is loaded at offset 1 into a u8 allocation. diff --git a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_addr_of.rs b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_addr_of.rs index f1032ab52bc..b414b905472 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_addr_of.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_addr_of.rs @@ -1,5 +1,5 @@ // This should fail even without validation or Stacked Borrows. -//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows +//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -Cdebug-assertions=no use std::ptr; fn main() { diff --git a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_zst.rs b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_zst.rs index eff42375956..04dbe3fd8d4 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_zst.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_zst.rs @@ -1,6 +1,6 @@ // This should fail even without validation // Some optimizations remove ZST accesses, thus masking this UB. -//@compile-flags: -Zmir-opt-level=0 -Zmiri-disable-validation +//@compile-flags: -Zmir-opt-level=0 -Zmiri-disable-validation -Cdebug-assertions=no fn main() { // Try many times as this might work by chance. diff --git a/src/tools/miri/tests/panic/alignment-assertion.rs b/src/tools/miri/tests/panic/alignment-assertion.rs new file mode 100644 index 00000000000..68aa19a88db --- /dev/null +++ b/src/tools/miri/tests/panic/alignment-assertion.rs @@ -0,0 +1,9 @@ +//@compile-flags: -Zmiri-disable-alignment-check -Cdebug-assertions=yes + +fn main() { + let mut x = [0u32; 2]; + let ptr: *mut u8 = x.as_mut_ptr().cast::(); + unsafe { + *(ptr.add(1).cast::()) = 42; + } +} diff --git a/src/tools/miri/tests/panic/alignment-assertion.stderr b/src/tools/miri/tests/panic/alignment-assertion.stderr new file mode 100644 index 00000000000..26cf51b0cd2 --- /dev/null +++ b/src/tools/miri/tests/panic/alignment-assertion.stderr @@ -0,0 +1,2 @@ +thread 'main' panicked at 'misaligned pointer dereference: address must be a multiple of 0x4 but is $HEX', $DIR/alignment-assertion.rs:LL:CC +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace diff --git a/src/tools/miri/tests/pass/disable-alignment-check.rs b/src/tools/miri/tests/pass/disable-alignment-check.rs index fdcacc6cea4..e8c0e027673 100644 --- a/src/tools/miri/tests/pass/disable-alignment-check.rs +++ b/src/tools/miri/tests/pass/disable-alignment-check.rs @@ -1,6 +1,6 @@ //@revisions: stack tree //@[tree]compile-flags: -Zmiri-tree-borrows -//@compile-flags: -Zmiri-disable-alignment-check +//@compile-flags: -Zmiri-disable-alignment-check -Cdebug-assertions=no fn main() { let mut x = [0u8; 20]; diff --git a/tests/codegen/issues/issue-37945.rs b/tests/codegen/issues/issue-37945.rs index fe54375bbf6..19e7e8b1f6e 100644 --- a/tests/codegen/issues/issue-37945.rs +++ b/tests/codegen/issues/issue-37945.rs @@ -4,6 +4,7 @@ // ignore-emscripten // ignore-gnux32 // ignore 32-bit platforms (LLVM has a bug with them) +// ignore-debug // Check that LLVM understands that `Iter` pointer is not null. Issue #37945. diff --git a/tests/codegen/virtual-function-elimination.rs b/tests/codegen/virtual-function-elimination.rs index 4cf7e12fee2..30e5cd0584d 100644 --- a/tests/codegen/virtual-function-elimination.rs +++ b/tests/codegen/virtual-function-elimination.rs @@ -1,5 +1,6 @@ // compile-flags: -Zvirtual-function-elimination -Clto -O -Csymbol-mangling-version=v0 // ignore-32bit +// ignore-debug // CHECK: @vtable.0 = {{.*}}, !type ![[TYPE0:[0-9]+]], !vcall_visibility ![[VCALL_VIS0:[0-9]+]] // CHECK: @vtable.1 = {{.*}}, !type ![[TYPE1:[0-9]+]], !vcall_visibility ![[VCALL_VIS0:[0-9]+]] diff --git a/tests/mir-opt/inline/inline_into_box_place.main.Inline.diff b/tests/mir-opt/inline/inline_into_box_place.main.Inline.diff index bc1c913c00e..a4f0ad465e2 100644 --- a/tests/mir-opt/inline/inline_into_box_place.main.Inline.diff +++ b/tests/mir-opt/inline/inline_into_box_place.main.Inline.diff @@ -8,10 +8,10 @@ scope 1 { debug _x => _1; // in scope 1 at $DIR/inline_into_box_place.rs:+1:9: +1:11 } -+ scope 2 (inlined Vec::::new) { // at $DIR/inline_into_box_place.rs:7:38: 7:48 ++ scope 2 (inlined Vec::::new) { // at $DIR/inline_into_box_place.rs:8:38: 8:48 + let mut _3: alloc::raw_vec::RawVec; // in scope 2 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + } -+ scope 3 (inlined Box::>::new) { // at $DIR/inline_into_box_place.rs:7:29: 7:49 ++ scope 3 (inlined Box::>::new) { // at $DIR/inline_into_box_place.rs:8:29: 8:49 + debug x => _2; // in scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + let mut _4: usize; // in scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL + let mut _5: usize; // in scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL @@ -28,7 +28,7 @@ + StorageLive(_3); // scope 2 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + _3 = const _; // scope 2 at $SRC_DIR/alloc/src/vec/mod.rs:LL:COL // mir::Constant -- // + span: $DIR/inline_into_box_place.rs:7:38: 7:46 +- // + span: $DIR/inline_into_box_place.rs:8:38: 8:46 - // + user_ty: UserType(2) - // + literal: Const { ty: fn() -> Vec {Vec::::new}, val: Value() } + // + span: $SRC_DIR/alloc/src/vec/mod.rs:LL:COL @@ -47,7 +47,7 @@ bb1: { - _1 = Box::>::new(move _2) -> [return: bb2, unwind: bb4]; // scope 0 at $DIR/inline_into_box_place.rs:+1:29: +1:49 - // mir::Constant -- // + span: $DIR/inline_into_box_place.rs:7:29: 7:37 +- // + span: $DIR/inline_into_box_place.rs:8:29: 8:37 - // + user_ty: UserType(1) - // + literal: Const { ty: fn(Vec) -> Box> {Box::>::new}, val: Value() } + StorageDead(_1); // scope 0 at $DIR/inline_into_box_place.rs:+2:1: +2:2 diff --git a/tests/mir-opt/inline/inline_into_box_place.rs b/tests/mir-opt/inline/inline_into_box_place.rs index b8b73f0c44c..02823e4e1b7 100644 --- a/tests/mir-opt/inline/inline_into_box_place.rs +++ b/tests/mir-opt/inline/inline_into_box_place.rs @@ -1,5 +1,6 @@ // ignore-endian-big // ignore-wasm32-bare compiled with panic=abort by default +// ignore-debug MIR alignment checks in std alter the diff, breaking the test // compile-flags: -Z mir-opt-level=4 // EMIT_MIR inline_into_box_place.main.Inline.diff diff --git a/tests/run-make/fmt-write-bloat/Makefile b/tests/run-make/fmt-write-bloat/Makefile index 07e6e025e08..53615775486 100644 --- a/tests/run-make/fmt-write-bloat/Makefile +++ b/tests/run-make/fmt-write-bloat/Makefile @@ -11,11 +11,11 @@ else NM = nm -PANIC_SYMS = panic_bounds_check pad_integral Display Debug +PANIC_SYMS = panic_bounds_check Debug # Allow for debug_assert!() in debug builds of std. ifdef NO_DEBUG_ASSERTIONS -PANIC_SYMS += panicking panic_fmt +PANIC_SYMS += panicking panic_fmt pad_integral Display Debug endif all: main.rs diff --git a/tests/ui/mir/mir_alignment_check.rs b/tests/ui/mir/mir_alignment_check.rs new file mode 100644 index 00000000000..6c964c78bd1 --- /dev/null +++ b/tests/ui/mir/mir_alignment_check.rs @@ -0,0 +1,11 @@ +// run-fail +// compile-flags: -C debug-assertions +// error-pattern: misaligned pointer dereference: address must be a multiple of 0x4 but is + +fn main() { + let mut x = [0u32; 2]; + let ptr: *mut u8 = x.as_mut_ptr().cast::(); + unsafe { + *(ptr.add(1).cast::()) = 42; + } +} From b605d0740fff80fad27ef4dcfb2c33866202a6e1 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 23 Mar 2023 23:30:13 +0000 Subject: [PATCH 110/346] Deeply check WF for RPITITs --- .../rustc_hir_analysis/src/check/wfcheck.rs | 105 ++++++++++++------ .../in-trait/wf-bounds.current.stderr | 20 +++- .../impl-trait/in-trait/wf-bounds.next.stderr | 20 +++- tests/ui/impl-trait/in-trait/wf-bounds.rs | 7 +- 4 files changed, 108 insertions(+), 44 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 737532b98a4..491bd04f346 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1544,42 +1544,81 @@ fn check_return_position_impl_trait_in_trait_bounds<'tcx>( span: Span, ) { let tcx = wfcx.tcx(); - if let Some(assoc_item) = tcx.opt_associated_item(fn_def_id.to_def_id()) - && assoc_item.container == ty::AssocItemContainer::TraitContainer - { - // FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty): Even with the new lowering - // strategy, we can't just call `check_associated_item` on the new RPITITs, - // because tests like `tests/ui/async-await/in-trait/implied-bounds.rs` will fail. - // That's because we need to check that the bounds of the RPITIT hold using - // the special substs that we create during opaque type lowering, otherwise we're - // getting a bunch of early bound and free regions mixed up... Haven't looked too - // deep into this, though. - for arg in fn_output.walk() { - if let ty::GenericArgKind::Type(ty) = arg.unpack() - // RPITITs are always eagerly normalized into opaques, so always look for an - // opaque here. - && let ty::Alias(ty::Opaque, opaque_ty) = ty.kind() - && let Some(opaque_def_id) = opaque_ty.def_id.as_local() - && let opaque = tcx.hir().expect_item(opaque_def_id).expect_opaque_ty() - && let hir::OpaqueTyOrigin::FnReturn(source) | hir::OpaqueTyOrigin::AsyncFn(source) = opaque.origin - && source == fn_def_id + let Some(assoc_item) = tcx.opt_associated_item(fn_def_id.to_def_id()) else { + return; + }; + if assoc_item.container != ty::AssocItemContainer::TraitContainer { + return; + } + fn_output.visit_with(&mut ImplTraitInTraitFinder { + wfcx, + fn_def_id, + depth: ty::INNERMOST, + seen: FxHashSet::default(), + }); +} + +// FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty): Even with the new lowering +// strategy, we can't just call `check_associated_item` on the new RPITITs, +// because tests like `tests/ui/async-await/in-trait/implied-bounds.rs` will fail. +// That's because we need to check that the bounds of the RPITIT hold using +// the special substs that we create during opaque type lowering, otherwise we're +// getting a bunch of early bound and free regions mixed up... Haven't looked too +// deep into this, though. +struct ImplTraitInTraitFinder<'a, 'tcx> { + wfcx: &'a WfCheckingCtxt<'a, 'tcx>, + fn_def_id: LocalDefId, + depth: ty::DebruijnIndex, + seen: FxHashSet, +} +impl<'tcx> TypeVisitor> for ImplTraitInTraitFinder<'_, 'tcx> { + type BreakTy = !; + + fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { + let tcx = self.wfcx.tcx(); + if let ty::Alias(ty::Opaque, unshifted_opaque_ty) = *ty.kind() + && self.seen.insert(unshifted_opaque_ty.def_id) + && let Some(opaque_def_id) = unshifted_opaque_ty.def_id.as_local() + && let opaque = tcx.hir().expect_item(opaque_def_id).expect_opaque_ty() + && let hir::OpaqueTyOrigin::FnReturn(source) | hir::OpaqueTyOrigin::AsyncFn(source) = opaque.origin + && source == self.fn_def_id + { + let opaque_ty = tcx.fold_regions(unshifted_opaque_ty, |re, depth| { + if let ty::ReLateBound(index, bv) = re.kind() { + if depth != ty::INNERMOST { + return tcx.mk_re_error_with_message( + DUMMY_SP, + "we shouldn't walk non-predicate binders with `impl Trait`...", + ); + } + tcx.mk_re_late_bound(index.shifted_out_to_binder(self.depth), bv) + } else { + re + } + }); + for (bound, bound_span) in tcx + .bound_explicit_item_bounds(opaque_ty.def_id) + .subst_iter_copied(tcx, opaque_ty.substs) { - let span = tcx.def_span(opaque_ty.def_id); - let bounds = wfcx.tcx().explicit_item_bounds(opaque_ty.def_id); - let wf_obligations = bounds.iter().flat_map(|&(bound, bound_span)| { - let bound = ty::EarlyBinder(bound).subst(tcx, opaque_ty.substs); - let normalized_bound = wfcx.normalize(span, None, bound); - traits::wf::predicate_obligations( - wfcx.infcx, - wfcx.param_env, - wfcx.body_def_id, - normalized_bound, - bound_span, - ) - }); - wfcx.register_obligations(wf_obligations); + let bound = self.wfcx.normalize(bound_span, None, bound); + self.wfcx.register_obligations(traits::wf::predicate_obligations( + self.wfcx.infcx, + self.wfcx.param_env, + self.wfcx.body_def_id, + bound, + bound_span, + )); + // Set the debruijn index back to innermost here, since we already eagerly + // shifted the substs that we use to generate these bounds. This is unfortunately + // subtly different behavior than the `ImplTraitInTraitFinder` we use in `param_env`, + // but that function doesn't actually need to normalize the bound it's visiting + // (whereas we have to do so here)... + let old_depth = std::mem::replace(&mut self.depth, ty::INNERMOST); + bound.visit_with(self); + self.depth = old_depth; } } + ty.super_visit_with(self) } } diff --git a/tests/ui/impl-trait/in-trait/wf-bounds.current.stderr b/tests/ui/impl-trait/in-trait/wf-bounds.current.stderr index 8392f26e7c8..1a70716123c 100644 --- a/tests/ui/impl-trait/in-trait/wf-bounds.current.stderr +++ b/tests/ui/impl-trait/in-trait/wf-bounds.current.stderr @@ -1,5 +1,5 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/wf-bounds.rs:11:22 + --> $DIR/wf-bounds.rs:13:22 | LL | fn nya() -> impl Wf>; | ^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -9,7 +9,7 @@ note: required by a bound in `Vec` --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/wf-bounds.rs:14:23 + --> $DIR/wf-bounds.rs:16:23 | LL | fn nya2() -> impl Wf<[u8]>; | ^^^^^^^^ doesn't have a size known at compile-time @@ -18,13 +18,23 @@ LL | fn nya2() -> impl Wf<[u8]>; note: required by a bound in `Wf` --> $DIR/wf-bounds.rs:8:10 | -LL | trait Wf {} +LL | trait Wf { | ^ required by this bound in `Wf` help: consider relaxing the implicit `Sized` restriction | -LL | trait Wf {} +LL | trait Wf { | ++++++++ -error: aborting due to 2 previous errors +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/wf-bounds.rs:19:44 + | +LL | fn nya3() -> impl Wf<(), Output = impl Wf>>; + | ^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: required by a bound in `Vec` + --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/in-trait/wf-bounds.next.stderr b/tests/ui/impl-trait/in-trait/wf-bounds.next.stderr index 8392f26e7c8..1a70716123c 100644 --- a/tests/ui/impl-trait/in-trait/wf-bounds.next.stderr +++ b/tests/ui/impl-trait/in-trait/wf-bounds.next.stderr @@ -1,5 +1,5 @@ error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/wf-bounds.rs:11:22 + --> $DIR/wf-bounds.rs:13:22 | LL | fn nya() -> impl Wf>; | ^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -9,7 +9,7 @@ note: required by a bound in `Vec` --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/wf-bounds.rs:14:23 + --> $DIR/wf-bounds.rs:16:23 | LL | fn nya2() -> impl Wf<[u8]>; | ^^^^^^^^ doesn't have a size known at compile-time @@ -18,13 +18,23 @@ LL | fn nya2() -> impl Wf<[u8]>; note: required by a bound in `Wf` --> $DIR/wf-bounds.rs:8:10 | -LL | trait Wf {} +LL | trait Wf { | ^ required by this bound in `Wf` help: consider relaxing the implicit `Sized` restriction | -LL | trait Wf {} +LL | trait Wf { | ++++++++ -error: aborting due to 2 previous errors +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/wf-bounds.rs:19:44 + | +LL | fn nya3() -> impl Wf<(), Output = impl Wf>>; + | ^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` +note: required by a bound in `Vec` + --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/in-trait/wf-bounds.rs b/tests/ui/impl-trait/in-trait/wf-bounds.rs index 39f41275315..1c9590bd853 100644 --- a/tests/ui/impl-trait/in-trait/wf-bounds.rs +++ b/tests/ui/impl-trait/in-trait/wf-bounds.rs @@ -5,7 +5,9 @@ #![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] -trait Wf {} +trait Wf { + type Output; +} trait Uwu { fn nya() -> impl Wf>; @@ -13,6 +15,9 @@ trait Uwu { fn nya2() -> impl Wf<[u8]>; //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time + + fn nya3() -> impl Wf<(), Output = impl Wf>>; + //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time } fn main() {} From 5896f8672da837e973bcabd9c415019205f3f8ef Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Thu, 23 Mar 2023 20:19:45 -0400 Subject: [PATCH 111/346] Fix clippy --- src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index cd9cc8bccb6..9f6adf3e3fa 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -169,7 +169,7 @@ fn check_rvalue<'tcx>( Err((span, "unsizing casts are not allowed in const fn".into())) } }, - Rvalue::Cast(CastKind::PointerExposeAddress | CastKind::PointerAddress, _, _) => { + Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => { Err((span, "casting pointers to ints is unstable in const fn".into())) }, Rvalue::Cast(CastKind::DynStar, _, _) => { From 5aad51098d4bae73220aa58180cf562bccc4a213 Mon Sep 17 00:00:00 2001 From: Kai Luo Date: Fri, 24 Mar 2023 10:25:52 +0800 Subject: [PATCH 112/346] Avoid misalign --- compiler/rustc_session/src/filesearch.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index 2c804f0f0a4..9c8a28a4a7e 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -85,15 +85,20 @@ fn current_dll_path() -> Result { #[cfg(target_os = "aix")] unsafe { let addr = current_dll_path as u64; - let mut buffer = vec![0i8; 4096]; + let mut buffer = vec![std::mem::zeroed::(); 64]; loop { - if libc::loadquery(libc::L_GETINFO, buffer.as_mut_ptr(), buffer.len() as u32) >= 0 { + if libc::loadquery( + libc::L_GETINFO, + buffer.as_mut_ptr() as *mut i8, + (std::mem::size_of::() * buffer.len()) as u32, + ) >= 0 + { break; } else { if std::io::Error::last_os_error().raw_os_error().unwrap() != libc::ENOMEM { return Err("loadquery failed".into()); } - buffer.resize(buffer.len() * 2, 0i8); + buffer.resize(buffer.len() * 2, std::mem::zeroed::()); } } let mut current = buffer.as_mut_ptr() as *mut libc::ld_info; From d4d1cc4db6e0fb1f5427fcbece7b04bfb7952d9e Mon Sep 17 00:00:00 2001 From: Nathan Fenner Date: Thu, 23 Mar 2023 20:24:37 -0700 Subject: [PATCH 113/346] Make helper functions private --- .../src/fn_ctxt/adjust_fulfillment_errors.rs | 62 +++++++++---------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index d64492e503d..a148742c1cb 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -302,7 +302,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .iter() .filter(|field| { let field_ty = field.ty(self.tcx, identity_substs); - Self::find_param_in_ty(field_ty.into(), param_to_point_at) + find_param_in_ty(field_ty.into(), param_to_point_at) }) .collect(); @@ -348,7 +348,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .inputs() .iter() .enumerate() - .filter(|(_, ty)| Self::find_param_in_ty((**ty).into(), param_to_point_at)) + .filter(|(_, ty)| find_param_in_ty((**ty).into(), param_to_point_at)) .collect(); // If there's one field that references the given generic, great! if let [(idx, _)] = args_referencing_param.as_slice() @@ -571,8 +571,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Find out which of `in_ty_elements` refer to `param`. // FIXME: It may be better to take the first if there are multiple, // just so that the error points to a smaller expression. - let Some((drill_expr, drill_ty)) = Self::is_iterator_singleton(expr_elements.iter().zip( in_ty_elements.iter()).filter(|(_expr_elem, in_ty_elem)| { - Self::find_param_in_ty((*in_ty_elem).into(), param) + let Some((drill_expr, drill_ty)) = is_iterator_singleton(expr_elements.iter().zip( in_ty_elements.iter()).filter(|(_expr_elem, in_ty_elem)| { + find_param_in_ty((*in_ty_elem).into(), param) })) else { // The param is not mentioned, or it is mentioned in multiple indexes. return Err(expr); @@ -620,10 +620,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We need to know which of the generic parameters mentions our target param. // We expect that at least one of them does, since it is expected to be mentioned. let Some((drill_generic_index, generic_argument_type)) = - Self::is_iterator_singleton( + is_iterator_singleton( in_ty_adt_generic_args.iter().enumerate().filter( |(_index, in_ty_generic)| { - Self::find_param_in_ty(*in_ty_generic, param) + find_param_in_ty(*in_ty_generic, param) }, ), ) else { @@ -729,10 +729,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We need to know which of the generic parameters mentions our target param. // We expect that at least one of them does, since it is expected to be mentioned. let Some((drill_generic_index, generic_argument_type)) = - Self::is_iterator_singleton( + is_iterator_singleton( in_ty_adt_generic_args.iter().enumerate().filter( |(_index, in_ty_generic)| { - Self::find_param_in_ty(*in_ty_generic, param) + find_param_in_ty(*in_ty_generic, param) }, ), ) else { @@ -771,14 +771,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // outer contextual information. // (1) Find the (unique) field index which mentions the type in our constraint: - let Some((field_index, field_type)) = Self::is_iterator_singleton( + let Some((field_index, field_type)) = is_iterator_singleton( in_ty_adt .variant_with_id(variant_def_id) .fields .iter() .map(|field| field.ty(self.tcx, *in_ty_adt_generic_args)) .enumerate() - .filter(|(_index, field_type)| Self::find_param_in_ty((*field_type).into(), param)) + .filter(|(_index, field_type)| find_param_in_ty((*field_type).into(), param)) ) else { return Err(expr); }; @@ -811,20 +811,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Err(expr) } +} - // FIXME: This can be made into a private, non-impl function later. - /// Traverses the given ty (either a `ty::Ty` or a `ty::GenericArg`) and searches for references - /// to the given `param_to_point_at`. Returns `true` if it finds any use of the param. - pub fn find_param_in_ty( - ty: ty::GenericArg<'tcx>, - param_to_point_at: ty::GenericArg<'tcx>, - ) -> bool { - let mut walk = ty.walk(); - while let Some(arg) = walk.next() { - if arg == param_to_point_at { - return true; - } - if let ty::GenericArgKind::Type(ty) = arg.unpack() +/// Traverses the given ty (either a `ty::Ty` or a `ty::GenericArg`) and searches for references +/// to the given `param_to_point_at`. Returns `true` if it finds any use of the param. +fn find_param_in_ty<'tcx>( + ty: ty::GenericArg<'tcx>, + param_to_point_at: ty::GenericArg<'tcx>, +) -> bool { + let mut walk = ty.walk(); + while let Some(arg) = walk.next() { + if arg == param_to_point_at { + return true; + } + if let ty::GenericArgKind::Type(ty) = arg.unpack() && let ty::Alias(ty::Projection, ..) = ty.kind() { // This logic may seem a bit strange, but typically when @@ -835,16 +835,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // in some UI tests. walk.skip_current_subtree(); } - } - false } + false +} - // FIXME: This can be made into a private, non-impl function later. - /// Returns `Some(iterator.next())` if it has exactly one item, and `None` otherwise. - pub fn is_iterator_singleton(mut iterator: impl Iterator) -> Option { - match (iterator.next(), iterator.next()) { - (_, Some(_)) => None, - (first, _) => first, - } +/// Returns `Some(iterator.next())` if it has exactly one item, and `None` otherwise. +fn is_iterator_singleton(mut iterator: impl Iterator) -> Option { + match (iterator.next(), iterator.next()) { + (_, Some(_)) => None, + (first, _) => first, } } From 8e56c2c5f1e8417ae7dcaf1fad1d72dd1ca964f5 Mon Sep 17 00:00:00 2001 From: Mu42 Date: Fri, 24 Mar 2023 14:24:25 +0800 Subject: [PATCH 114/346] Suggest ..= when someone tries to create an overflowing range --- compiler/rustc_lint/src/types.rs | 27 ++++++++++++++++++++------- tests/ui/lint/issue-109529.rs | 5 +++++ tests/ui/lint/issue-109529.stderr | 10 ++++++++++ 3 files changed, 35 insertions(+), 7 deletions(-) create mode 100644 tests/ui/lint/issue-109529.rs create mode 100644 tests/ui/lint/issue-109529.stderr diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 7ca50f5a2db..db93f6d3402 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -136,6 +136,13 @@ fn lint_overflowing_range_endpoint<'tcx>( expr: &'tcx hir::Expr<'tcx>, ty: &str, ) -> bool { + let (expr, cast_ty) = if let Node::Expr(par_expr) = cx.tcx.hir().get(cx.tcx.hir().parent_id(expr.hir_id)) + && let ExprKind::Cast(_, ty) = par_expr.kind { + (par_expr, Some(ty)) + } else { + (expr, None) + }; + // We only want to handle exclusive (`..`) ranges, // which are represented as `ExprKind::Struct`. let par_id = cx.tcx.hir().parent_id(expr.hir_id); @@ -157,13 +164,19 @@ fn lint_overflowing_range_endpoint<'tcx>( }; let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span) else { return false }; - use rustc_ast::{LitIntType, LitKind}; - let suffix = match lit.node { - LitKind::Int(_, LitIntType::Signed(s)) => s.name_str(), - LitKind::Int(_, LitIntType::Unsigned(s)) => s.name_str(), - LitKind::Int(_, LitIntType::Unsuffixed) => "", - _ => bug!(), + let suffix = if let Some(cast_ty) = cast_ty { + let Ok(ty) = cx.sess().source_map().span_to_snippet(cast_ty.span) else { return false }; + format!(" as {}", ty) + } else { + use rustc_ast::{LitIntType, LitKind}; + match lit.node { + LitKind::Int(_, LitIntType::Signed(s)) => s.name_str().to_owned(), + LitKind::Int(_, LitIntType::Unsigned(s)) => s.name_str().to_owned(), + LitKind::Int(_, LitIntType::Unsuffixed) => "".to_owned(), + _ => bug!(), + } }; + cx.emit_spanned_lint( OVERFLOWING_LITERALS, struct_expr.span, @@ -172,7 +185,7 @@ fn lint_overflowing_range_endpoint<'tcx>( suggestion: struct_expr.span, start, literal: lit_val - 1, - suffix, + suffix: &suffix, }, ); diff --git a/tests/ui/lint/issue-109529.rs b/tests/ui/lint/issue-109529.rs new file mode 100644 index 00000000000..f6829d0c76a --- /dev/null +++ b/tests/ui/lint/issue-109529.rs @@ -0,0 +1,5 @@ +fn main() { + for i in 0..256 as u8 { //~ ERROR range endpoint is out of range + println!("{}", i); + } +} diff --git a/tests/ui/lint/issue-109529.stderr b/tests/ui/lint/issue-109529.stderr new file mode 100644 index 00000000000..87c9119ee6f --- /dev/null +++ b/tests/ui/lint/issue-109529.stderr @@ -0,0 +1,10 @@ +error: range endpoint is out of range for `u8` + --> $DIR/issue-109529.rs:2:14 + | +LL | for i in 0..256 as u8 { + | ^^^^^^^^^^^^ help: use an inclusive range instead: `0..=255 as u8` + | + = note: `#[deny(overflowing_literals)]` on by default + +error: aborting due to previous error + From d13b423859b6df29c9d0a84b021fba0e7a97fe43 Mon Sep 17 00:00:00 2001 From: Raphael Amorim Date: Fri, 24 Mar 2023 12:23:48 +0100 Subject: [PATCH 115/346] use llvm 16.0.0 instead of 16.0.0-rc4 --- src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh index de0fb95efd0..9b274cc277e 100755 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh @@ -4,7 +4,7 @@ set -ex source shared.sh -LLVM=llvmorg-16.0.0-rc4 +LLVM=llvmorg-16.0.0 mkdir llvm-project cd llvm-project From 8b1be44758f6b828cb556ecdc7cddc2dbfe0637f Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 24 Mar 2023 11:43:14 +0000 Subject: [PATCH 116/346] Update ar_archive_writer to 0.1.3 This updates object to 0.30 and fixes a bug where the symbol table would be omitted for archives where there are object files yet none that export any symbol. This bug could lead to linker errors for crates like rustc_std_workspace_core which don't contain any code of their own but exist solely for their dependencies. This is likely the cause of the linker issues I was experiencing on Webassembly. It has been shown to cause issues on other platforms too. cc rust-lang/ar_archive_writer#5 --- Cargo.lock | 6 +++--- compiler/rustc_codegen_llvm/src/back/archive.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 449f0c73588..6b76b6e7e70 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -106,11 +106,11 @@ checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602" [[package]] name = "ar_archive_writer" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "276881980556fdadeb88aa1ffc667e4d2e8fe72531dfabcb7a82bb3c9ea9ba31" +checksum = "b0639441fd17a3197d1cbca8dc8768cc172a63b64b4bb6c372e8f41ed0acc9bb" dependencies = [ - "object 0.29.0", + "object 0.30.1", ] [[package]] diff --git a/compiler/rustc_codegen_llvm/src/back/archive.rs b/compiler/rustc_codegen_llvm/src/back/archive.rs index a570f2af0f0..12da21dc477 100644 --- a/compiler/rustc_codegen_llvm/src/back/archive.rs +++ b/compiler/rustc_codegen_llvm/src/back/archive.rs @@ -110,7 +110,7 @@ impl ArchiveBuilderBuilder for LlvmArchiveBuilderBuilder { fn new_archive_builder<'a>(&self, sess: &'a Session) -> Box + 'a> { // FIXME use ArArchiveBuilder on most targets again once reading thin archives is // implemented - if true || sess.target.arch == "wasm32" || sess.target.arch == "wasm64" { + if true { Box::new(LlvmArchiveBuilder { sess, additions: Vec::new() }) } else { Box::new(ArArchiveBuilder::new(sess, get_llvm_object_symbols)) From 64f6e4f21ccd8e0ed1f4bb32abe525b4f6ab87c1 Mon Sep 17 00:00:00 2001 From: yukang Date: Mon, 20 Mar 2023 01:41:48 +0800 Subject: [PATCH 117/346] Fix bad suggestion for clone/is_some in field init shorthand --- .../src/fn_ctxt/suggestions.rs | 29 ++++++++++++------- tests/ui/suggestions/issue-108470.fixed | 29 +++++++++++++++++++ tests/ui/suggestions/issue-108470.rs | 29 +++++++++++++++++++ tests/ui/suggestions/issue-108470.stderr | 27 +++++++++++++++++ 4 files changed, 104 insertions(+), 10 deletions(-) create mode 100644 tests/ui/suggestions/issue-108470.fixed create mode 100644 tests/ui/suggestions/issue-108470.rs create mode 100644 tests/ui/suggestions/issue-108470.stderr diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 690d8a23826..aa8767fc85c 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -985,13 +985,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) .must_apply_modulo_regions() { - diag.span_suggestion_verbose( - expr.span.shrink_to_hi(), - "consider using clone here", - ".clone()", - Applicability::MachineApplicable, - ); - return true; + let suggestion = match self.maybe_get_struct_pattern_shorthand_field(expr) { + Some(ident) => format!(": {}.clone()", ident), + None => ".clone()".to_string() + }; + + diag.span_suggestion_verbose( + expr.span.shrink_to_hi(), + "consider using clone here", + suggestion, + Applicability::MachineApplicable, + ); + return true; } false } @@ -1153,13 +1158,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { return false; } - diag.span_suggestion( + let suggestion = match self.maybe_get_struct_pattern_shorthand_field(expr) { + Some(ident) => format!(": {}.is_some()", ident), + None => ".is_some()".to_string(), + }; + + diag.span_suggestion_verbose( expr.span.shrink_to_hi(), "use `Option::is_some` to test if the `Option` has a value", - ".is_some()", + suggestion, Applicability::MachineApplicable, ); - true } diff --git a/tests/ui/suggestions/issue-108470.fixed b/tests/ui/suggestions/issue-108470.fixed new file mode 100644 index 00000000000..9d15c4a8fcb --- /dev/null +++ b/tests/ui/suggestions/issue-108470.fixed @@ -0,0 +1,29 @@ +// run-rustfix +#![allow(dead_code)] + +struct Foo { + t: Thing +} + +#[derive(Clone)] +struct Thing; + +fn test_clone() { + let t = &Thing; + let _f = Foo { + t: t.clone() //~ ERROR mismatched types + }; +} + +struct Bar { + t: bool +} + +fn test_is_some() { + let t = Option::::Some(1); + let _f = Bar { + t: t.is_some() //~ ERROR mismatched types + }; +} + +fn main() {} diff --git a/tests/ui/suggestions/issue-108470.rs b/tests/ui/suggestions/issue-108470.rs new file mode 100644 index 00000000000..bda39085d4d --- /dev/null +++ b/tests/ui/suggestions/issue-108470.rs @@ -0,0 +1,29 @@ +// run-rustfix +#![allow(dead_code)] + +struct Foo { + t: Thing +} + +#[derive(Clone)] +struct Thing; + +fn test_clone() { + let t = &Thing; + let _f = Foo { + t //~ ERROR mismatched types + }; +} + +struct Bar { + t: bool +} + +fn test_is_some() { + let t = Option::::Some(1); + let _f = Bar { + t //~ ERROR mismatched types + }; +} + +fn main() {} diff --git a/tests/ui/suggestions/issue-108470.stderr b/tests/ui/suggestions/issue-108470.stderr new file mode 100644 index 00000000000..4e561eca734 --- /dev/null +++ b/tests/ui/suggestions/issue-108470.stderr @@ -0,0 +1,27 @@ +error[E0308]: mismatched types + --> $DIR/issue-108470.rs:14:9 + | +LL | t + | ^ expected `Thing`, found `&Thing` + | +help: consider using clone here + | +LL | t: t.clone() + | +++++++++++ + +error[E0308]: mismatched types + --> $DIR/issue-108470.rs:25:9 + | +LL | t + | ^ expected `bool`, found `Option` + | + = note: expected type `bool` + found enum `Option` +help: use `Option::is_some` to test if the `Option` has a value + | +LL | t: t.is_some() + | +++++++++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. From 6034b2fcb80915d35a871d438663758b4241a0fa Mon Sep 17 00:00:00 2001 From: Mu42 Date: Fri, 24 Mar 2023 20:09:02 +0800 Subject: [PATCH 118/346] Use independent suggestions --- compiler/rustc_lint/src/lints.rs | 7 ++++--- compiler/rustc_lint/src/types.rs | 33 +++++++++++++------------------ tests/ui/lint/issue-109529.rs | 2 +- tests/ui/lint/issue-109529.stderr | 12 +++++++++-- 4 files changed, 29 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 308c02929ca..925e9654f93 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -1210,9 +1210,10 @@ impl<'a> DecorateLint<'a, ()> for DropGlue<'_> { #[diag(lint_range_endpoint_out_of_range)] pub struct RangeEndpointOutOfRange<'a> { pub ty: &'a str, - #[suggestion(code = "{start}..={literal}{suffix}", applicability = "machine-applicable")] - pub suggestion: Span, - pub start: String, + #[suggestion(code = "=", applicability = "machine-applicable")] + pub eq_suggestion: Span, + #[suggestion(code = "{literal}{suffix}", applicability = "machine-applicable")] + pub lit_suggestion: Span, pub literal: u128, pub suffix: &'a str, } diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index db93f6d3402..1cc873c6de9 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -136,11 +136,12 @@ fn lint_overflowing_range_endpoint<'tcx>( expr: &'tcx hir::Expr<'tcx>, ty: &str, ) -> bool { - let (expr, cast_ty) = if let Node::Expr(par_expr) = cx.tcx.hir().get(cx.tcx.hir().parent_id(expr.hir_id)) - && let ExprKind::Cast(_, ty) = par_expr.kind { - (par_expr, Some(ty)) + // Look past casts to support cases like `0..256 as u8` + let (expr, lit_span) = if let Node::Expr(par_expr) = cx.tcx.hir().get(cx.tcx.hir().parent_id(expr.hir_id)) + && let ExprKind::Cast(_, _) = par_expr.kind { + (par_expr, expr.span) } else { - (expr, None) + (expr, expr.span) }; // We only want to handle exclusive (`..`) ranges, @@ -162,19 +163,13 @@ fn lint_overflowing_range_endpoint<'tcx>( if !(eps[1].expr.hir_id == expr.hir_id && lit_val - 1 == max) { return false; }; - let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span) else { return false }; - let suffix = if let Some(cast_ty) = cast_ty { - let Ok(ty) = cx.sess().source_map().span_to_snippet(cast_ty.span) else { return false }; - format!(" as {}", ty) - } else { - use rustc_ast::{LitIntType, LitKind}; - match lit.node { - LitKind::Int(_, LitIntType::Signed(s)) => s.name_str().to_owned(), - LitKind::Int(_, LitIntType::Unsigned(s)) => s.name_str().to_owned(), - LitKind::Int(_, LitIntType::Unsuffixed) => "".to_owned(), - _ => bug!(), - } + use rustc_ast::{LitIntType, LitKind}; + let suffix = match lit.node { + LitKind::Int(_, LitIntType::Signed(s)) => s.name_str(), + LitKind::Int(_, LitIntType::Unsigned(s)) => s.name_str(), + LitKind::Int(_, LitIntType::Unsuffixed) => "", + _ => bug!(), }; cx.emit_spanned_lint( @@ -182,10 +177,10 @@ fn lint_overflowing_range_endpoint<'tcx>( struct_expr.span, RangeEndpointOutOfRange { ty, - suggestion: struct_expr.span, - start, + eq_suggestion: expr.span.shrink_to_lo(), + lit_suggestion: lit_span, literal: lit_val - 1, - suffix: &suffix, + suffix, }, ); diff --git a/tests/ui/lint/issue-109529.rs b/tests/ui/lint/issue-109529.rs index f6829d0c76a..36c6d4fdfe3 100644 --- a/tests/ui/lint/issue-109529.rs +++ b/tests/ui/lint/issue-109529.rs @@ -1,5 +1,5 @@ fn main() { - for i in 0..256 as u8 { //~ ERROR range endpoint is out of range + for i in 0..(256 as u8) { //~ ERROR range endpoint is out of range println!("{}", i); } } diff --git a/tests/ui/lint/issue-109529.stderr b/tests/ui/lint/issue-109529.stderr index 87c9119ee6f..e9f6d546ac2 100644 --- a/tests/ui/lint/issue-109529.stderr +++ b/tests/ui/lint/issue-109529.stderr @@ -1,10 +1,18 @@ error: range endpoint is out of range for `u8` --> $DIR/issue-109529.rs:2:14 | -LL | for i in 0..256 as u8 { - | ^^^^^^^^^^^^ help: use an inclusive range instead: `0..=255 as u8` +LL | for i in 0..(256 as u8) { + | ^^^^^^^^^^^^^^ | = note: `#[deny(overflowing_literals)]` on by default +help: use an inclusive range instead + | +LL | for i in 0..=(256 as u8) { + | + +help: use an inclusive range instead + | +LL | for i in 0..(255 as u8) { + | ~~~ error: aborting due to previous error From 8134414e03f6ddedf95d96758251124082dbe164 Mon Sep 17 00:00:00 2001 From: Philipp Krones Date: Fri, 24 Mar 2023 13:36:15 +0100 Subject: [PATCH 119/346] Bump nightly version -> 2023-03-24 --- rust-toolchain | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-toolchain b/rust-toolchain index d788c6359d7..0b2458ea007 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2023-03-10" +channel = "nightly-2023-03-24" components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"] From 291ddb85fd5d1499f944021db1f698613a068b72 Mon Sep 17 00:00:00 2001 From: Robin Hafid Date: Mon, 20 Mar 2023 18:13:05 -0500 Subject: [PATCH 120/346] Rename 'src/bootstrap/native.rs' to llvm.rs Renamed 'native.rs' to 'llvm.rs', also moved `TestHelpers` to `test.rs`.Replaced all the `native.rs` ocurrences at `src/bootstrap` files to `llvm.rs` --- src/bootstrap/builder.rs | 14 ++--- src/bootstrap/compile.rs | 18 +++---- src/bootstrap/config.rs | 6 +-- src/bootstrap/config/tests.rs | 2 +- src/bootstrap/dist.rs | 12 ++--- src/bootstrap/download.rs | 2 +- src/bootstrap/lib.rs | 2 +- src/bootstrap/{native.rs => llvm.rs} | 65 ----------------------- src/bootstrap/test.rs | 79 +++++++++++++++++++++++++--- src/ci/stage-build.py | 2 +- 10 files changed, 101 insertions(+), 101 deletions(-) rename src/bootstrap/{native.rs => llvm.rs} (95%) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 83a6d0ad292..a22679db17e 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -16,7 +16,7 @@ use crate::config::{SplitDebuginfo, TargetSelection}; use crate::doc; use crate::flags::{Color, Subcommand}; use crate::install; -use crate::native; +use crate::llvm; use crate::run; use crate::setup; use crate::test; @@ -636,13 +636,13 @@ impl<'a> Builder<'a> { tool::Rustdoc, tool::Clippy, tool::CargoClippy, - native::Llvm, - native::Sanitizers, + llvm::Llvm, + llvm::Sanitizers, tool::Rustfmt, tool::Miri, tool::CargoMiri, - native::Lld, - native::CrtBeginEnd + llvm::Lld, + llvm::CrtBeginEnd ), Kind::Check | Kind::Clippy | Kind::Fix => describe!( check::Std, @@ -1101,7 +1101,7 @@ impl<'a> Builder<'a> { /// check build or dry-run, where there's no need to build all of LLVM. fn llvm_config(&self, target: TargetSelection) -> Option { if self.config.llvm_enabled() && self.kind != Kind::Check && !self.config.dry_run() { - let native::LlvmResult { llvm_config, .. } = self.ensure(native::Llvm { target }); + let llvm::LlvmResult { llvm_config, .. } = self.ensure(llvm::Llvm { target }); if llvm_config.is_file() { return Some(llvm_config); } @@ -1227,7 +1227,7 @@ impl<'a> Builder<'a> { // rustc_llvm. But if LLVM is stale, that'll be a tiny amount // of work comparatively, and we'd likely need to rebuild it anyway, // so that's okay. - if crate::native::prebuilt_llvm_config(self, target).is_err() { + if crate::llvm::prebuilt_llvm_config(self, target).is_err() { cargo.env("RUST_CHECK", "1"); } } diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 54971af644c..67bd573a855 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -24,7 +24,7 @@ use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step}; use crate::cache::{Interned, INTERNER}; use crate::config::{LlvmLibunwind, RustcLto, TargetSelection}; use crate::dist; -use crate::native; +use crate::llvm; use crate::tool::SourceType; use crate::util::get_clang_cl_resource_dir; use crate::util::{exe, is_debug_info, is_dylib, output, symlink_dir, t, up_to_date}; @@ -191,7 +191,7 @@ fn copy_and_stamp( } fn copy_llvm_libunwind(builder: &Builder<'_>, target: TargetSelection, libdir: &Path) -> PathBuf { - let libunwind_path = builder.ensure(native::Libunwind { target }); + let libunwind_path = builder.ensure(llvm::Libunwind { target }); let libunwind_source = libunwind_path.join("libunwind.a"); let libunwind_target = libdir.join("libunwind.a"); builder.copy(&libunwind_source, &libunwind_target); @@ -266,7 +266,7 @@ fn copy_self_contained_objects( DependencyType::TargetSelfContained, ); } - let crt_path = builder.ensure(native::CrtBeginEnd { target }); + let crt_path = builder.ensure(llvm::CrtBeginEnd { target }); for &obj in &["crtbegin.o", "crtbeginS.o", "crtend.o", "crtendS.o"] { let src = crt_path.join(obj); let target = libdir_self_contained.join(obj); @@ -474,7 +474,7 @@ fn copy_sanitizers( compiler: &Compiler, target: TargetSelection, ) -> Vec { - let runtimes: Vec = builder.ensure(native::Sanitizers { target }); + let runtimes: Vec = builder.ensure(llvm::Sanitizers { target }); if builder.config.dry_run() { return Vec::new(); @@ -876,12 +876,12 @@ pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetS // busting caches (e.g. like #71152). if builder.config.llvm_enabled() && (builder.kind != Kind::Check - || crate::native::prebuilt_llvm_config(builder, target).is_ok()) + || crate::llvm::prebuilt_llvm_config(builder, target).is_ok()) { if builder.is_rust_llvm(target) { cargo.env("LLVM_RUSTLLVM", "1"); } - let native::LlvmResult { llvm_config, .. } = builder.ensure(native::Llvm { target }); + let llvm::LlvmResult { llvm_config, .. } = builder.ensure(llvm::Llvm { target }); cargo.env("LLVM_CONFIG", &llvm_config); if let Some(s) = target_config.and_then(|c| c.llvm_config.as_ref()) { cargo.env("CFG_LLVM_ROOT", s); @@ -1359,7 +1359,7 @@ impl Step for Assemble { } let lld_install = if builder.config.lld_enabled { - Some(builder.ensure(native::Lld { target: target_compiler.host })) + Some(builder.ensure(llvm::Lld { target: target_compiler.host })) } else { None }; @@ -1423,8 +1423,8 @@ impl Step for Assemble { } if builder.config.rust_codegen_backends.contains(&INTERNER.intern_str("llvm")) { - let native::LlvmResult { llvm_config, .. } = - builder.ensure(native::Llvm { target: target_compiler.host }); + let llvm::LlvmResult { llvm_config, .. } = + builder.ensure(llvm::Llvm { target: target_compiler.host }); if !builder.config.dry_run() { let llvm_bin_dir = output(Command::new(llvm_config).arg("--bindir")); let llvm_bin_dir = Path::new(llvm_bin_dir.trim()); diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 95625170478..0eba18c3a63 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -1207,11 +1207,11 @@ impl Config { config.llvm_from_ci = match llvm.download_ci_llvm { Some(StringOrBool::String(s)) => { assert!(s == "if-available", "unknown option `{}` for download-ci-llvm", s); - crate::native::is_ci_llvm_available(&config, asserts) + crate::llvm::is_ci_llvm_available(&config, asserts) } Some(StringOrBool::Bool(b)) => b, None => { - config.channel == "dev" && crate::native::is_ci_llvm_available(&config, asserts) + config.channel == "dev" && crate::llvm::is_ci_llvm_available(&config, asserts) } }; @@ -1254,7 +1254,7 @@ impl Config { } } else { config.llvm_from_ci = - config.channel == "dev" && crate::native::is_ci_llvm_available(&config, false); + config.channel == "dev" && crate::llvm::is_ci_llvm_available(&config, false); } if let Some(t) = toml.target { diff --git a/src/bootstrap/config/tests.rs b/src/bootstrap/config/tests.rs index 16dc8c63abc..5cea143e0a7 100644 --- a/src/bootstrap/config/tests.rs +++ b/src/bootstrap/config/tests.rs @@ -11,7 +11,7 @@ fn parse(config: &str) -> Config { #[test] fn download_ci_llvm() { - if crate::native::is_ci_llvm_modified(&parse("")) { + if crate::llvm::is_ci_llvm_modified(&parse("")) { eprintln!("Detected LLVM as non-available: running in CI and modified LLVM in this change"); return; } diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index dceb4bd1b89..2ce54d9a3b4 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -27,7 +27,7 @@ use crate::channel; use crate::compile; use crate::config::TargetSelection; use crate::doc::DocumentationFormat; -use crate::native; +use crate::llvm; use crate::tarball::{GeneratedTarball, OverlayKind, Tarball}; use crate::tool::{self, Tool}; use crate::util::{exe, is_dylib, output, t, timeit}; @@ -1965,8 +1965,8 @@ fn maybe_install_llvm(builder: &Builder<'_>, target: TargetSelection, dst_libdir builder.install(&llvm_dylib_path, dst_libdir, 0o644); } !builder.config.dry_run() - } else if let Ok(native::LlvmResult { llvm_config, .. }) = - native::prebuilt_llvm_config(builder, target) + } else if let Ok(llvm::LlvmResult { llvm_config, .. }) = + llvm::prebuilt_llvm_config(builder, target) { let mut cmd = Command::new(llvm_config); cmd.arg("--libfiles"); @@ -2154,7 +2154,7 @@ impl Step for LlvmTools { } } - builder.ensure(crate::native::Llvm { target }); + builder.ensure(crate::llvm::Llvm { target }); let mut tarball = Tarball::new(builder, "llvm-tools", &target.triple); tarball.set_overlay(OverlayKind::LLVM); @@ -2213,10 +2213,10 @@ impl Step for RustDev { let mut tarball = Tarball::new(builder, "rust-dev", &target.triple); tarball.set_overlay(OverlayKind::LLVM); - builder.ensure(crate::native::Llvm { target }); + builder.ensure(crate::llvm::Llvm { target }); // We want to package `lld` to use it with `download-ci-llvm`. - builder.ensure(crate::native::Lld { target }); + builder.ensure(crate::llvm::Lld { target }); let src_bindir = builder.llvm_out(target).join("bin"); // If updating this list, you likely want to change diff --git a/src/bootstrap/download.rs b/src/bootstrap/download.rs index d1e2149d3f9..8fbc034965a 100644 --- a/src/bootstrap/download.rs +++ b/src/bootstrap/download.rs @@ -12,7 +12,7 @@ use xz2::bufread::XzDecoder; use crate::{ config::RustfmtMetadata, - native::detect_llvm_sha, + llvm::detect_llvm_sha, t, util::{check_run, exe, program_out_of_date, try_run}, Config, diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 54aa5a585bb..20b92b294fe 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -53,8 +53,8 @@ mod download; mod flags; mod format; mod install; +mod llvm; mod metadata; -mod native; mod render_tests; mod run; mod sanity; diff --git a/src/bootstrap/native.rs b/src/bootstrap/llvm.rs similarity index 95% rename from src/bootstrap/native.rs rename to src/bootstrap/llvm.rs index f27db5c91e2..de06f8ca8c0 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/llvm.rs @@ -869,71 +869,6 @@ impl Step for Lld { } } -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub struct TestHelpers { - pub target: TargetSelection, -} - -impl Step for TestHelpers { - type Output = (); - - fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.path("tests/auxiliary/rust_test_helpers.c") - } - - fn make_run(run: RunConfig<'_>) { - run.builder.ensure(TestHelpers { target: run.target }) - } - - /// Compiles the `rust_test_helpers.c` library which we used in various - /// `run-pass` tests for ABI testing. - fn run(self, builder: &Builder<'_>) { - if builder.config.dry_run() { - return; - } - // The x86_64-fortanix-unknown-sgx target doesn't have a working C - // toolchain. However, some x86_64 ELF objects can be linked - // without issues. Use this hack to compile the test helpers. - let target = if self.target == "x86_64-fortanix-unknown-sgx" { - TargetSelection::from_user("x86_64-unknown-linux-gnu") - } else { - self.target - }; - let dst = builder.test_helpers_out(target); - let src = builder.src.join("tests/auxiliary/rust_test_helpers.c"); - if up_to_date(&src, &dst.join("librust_test_helpers.a")) { - return; - } - - builder.info("Building test helpers"); - t!(fs::create_dir_all(&dst)); - let mut cfg = cc::Build::new(); - // FIXME: Workaround for https://github.com/emscripten-core/emscripten/issues/9013 - if target.contains("emscripten") { - cfg.pic(false); - } - - // We may have found various cross-compilers a little differently due to our - // extra configuration, so inform cc of these compilers. Note, though, that - // on MSVC we still need cc's detection of env vars (ugh). - if !target.contains("msvc") { - if let Some(ar) = builder.ar(target) { - cfg.archiver(ar); - } - cfg.compiler(builder.cc(target)); - } - cfg.cargo_metadata(false) - .out_dir(&dst) - .target(&target.triple) - .host(&builder.config.build.triple) - .opt_level(0) - .warnings(false) - .debug(false) - .file(builder.src.join("tests/auxiliary/rust_test_helpers.c")) - .compile("rust_test_helpers"); - } -} - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct Sanitizers { pub target: TargetSelection, diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 29d37c09d88..92a7603a9df 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -19,11 +19,11 @@ use crate::config::TargetSelection; use crate::dist; use crate::doc::DocumentationFormat; use crate::flags::Subcommand; -use crate::native; +use crate::llvm; use crate::render_tests::add_flags_and_try_run_tests; use crate::tool::{self, SourceType, Tool}; use crate::toolstate::ToolState; -use crate::util::{self, add_link_lib_path, dylib_path, dylib_path_var, output, t}; +use crate::util::{self, add_link_lib_path, dylib_path, dylib_path_var, output, t, up_to_date}; use crate::{envify, CLang, DocTests, GitRepo, Mode}; const ADB_TEST_DIR: &str = "/data/local/tmp/work"; @@ -1434,11 +1434,11 @@ note: if you're sure you want to do this, please open an issue as to why. In the builder.ensure(compile::Std::new(compiler, compiler.host)); // Also provide `rust_test_helpers` for the host. - builder.ensure(native::TestHelpers { target: compiler.host }); + builder.ensure(TestHelpers { target: compiler.host }); // As well as the target, except for plain wasm32, which can't build it if !target.contains("wasm") || target.contains("emscripten") { - builder.ensure(native::TestHelpers { target }); + builder.ensure(TestHelpers { target }); } builder.ensure(RemoteCopyLibs { compiler, target }); @@ -1625,8 +1625,8 @@ note: if you're sure you want to do this, please open an issue as to why. In the let mut llvm_components_passed = false; let mut copts_passed = false; if builder.config.llvm_enabled() { - let native::LlvmResult { llvm_config, .. } = - builder.ensure(native::Llvm { target: builder.config.build }); + let llvm::LlvmResult { llvm_config, .. } = + builder.ensure(llvm::Llvm { target: builder.config.build }); if !builder.config.dry_run() { let llvm_version = output(Command::new(&llvm_config).arg("--version")); let llvm_components = output(Command::new(&llvm_config).arg("--components")); @@ -1664,7 +1664,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the // If LLD is available, add it to the PATH if builder.config.lld_enabled { let lld_install_root = - builder.ensure(native::Lld { target: builder.config.build }); + builder.ensure(llvm::Lld { target: builder.config.build }); let lld_bin_path = lld_install_root.join("bin"); @@ -2747,3 +2747,68 @@ impl Step for RustInstaller { run.builder.ensure(Self); } } + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub struct TestHelpers { + pub target: TargetSelection, +} + +impl Step for TestHelpers { + type Output = (); + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.path("tests/auxiliary/rust_test_helpers.c") + } + + fn make_run(run: RunConfig<'_>) { + run.builder.ensure(TestHelpers { target: run.target }) + } + + /// Compiles the `rust_test_helpers.c` library which we used in various + /// `run-pass` tests for ABI testing. + fn run(self, builder: &Builder<'_>) { + if builder.config.dry_run() { + return; + } + // The x86_64-fortanix-unknown-sgx target doesn't have a working C + // toolchain. However, some x86_64 ELF objects can be linked + // without issues. Use this hack to compile the test helpers. + let target = if self.target == "x86_64-fortanix-unknown-sgx" { + TargetSelection::from_user("x86_64-unknown-linux-gnu") + } else { + self.target + }; + let dst = builder.test_helpers_out(target); + let src = builder.src.join("tests/auxiliary/rust_test_helpers.c"); + if up_to_date(&src, &dst.join("librust_test_helpers.a")) { + return; + } + + builder.info("Building test helpers"); + t!(fs::create_dir_all(&dst)); + let mut cfg = cc::Build::new(); + // FIXME: Workaround for https://github.com/emscripten-core/emscripten/issues/9013 + if target.contains("emscripten") { + cfg.pic(false); + } + + // We may have found various cross-compilers a little differently due to our + // extra configuration, so inform cc of these compilers. Note, though, that + // on MSVC we still need cc's detection of env vars (ugh). + if !target.contains("msvc") { + if let Some(ar) = builder.ar(target) { + cfg.archiver(ar); + } + cfg.compiler(builder.cc(target)); + } + cfg.cargo_metadata(false) + .out_dir(&dst) + .target(&target.triple) + .host(&builder.config.build.triple) + .opt_level(0) + .warnings(false) + .debug(false) + .file(builder.src.join("tests/auxiliary/rust_test_helpers.c")) + .compile("rust_test_helpers"); + } +} diff --git a/src/ci/stage-build.py b/src/ci/stage-build.py index d4d80e8f77c..7cd5e88f6a2 100644 --- a/src/ci/stage-build.py +++ b/src/ci/stage-build.py @@ -727,7 +727,7 @@ def record_metrics(pipeline: Pipeline, timer: Timer): metrics = load_last_metrics(pipeline.metrics_path()) if metrics is None: return - llvm_steps = tuple(metrics.find_all_by_type("bootstrap::native::Llvm")) + llvm_steps = tuple(metrics.find_all_by_type("bootstrap::llvm::Llvm")) assert len(llvm_steps) > 0 llvm_duration = sum(step.duration for step in llvm_steps) From c9c1346874299b3dac07b3f310429c00fe91c998 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Fri, 24 Mar 2023 10:48:40 -0400 Subject: [PATCH 121/346] Clarify that we are doing ptr.addr() internally Co-authored-by: Ralf Jung --- compiler/rustc_mir_transform/src/check_alignment.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_mir_transform/src/check_alignment.rs b/compiler/rustc_mir_transform/src/check_alignment.rs index d654c973e02..694102388cf 100644 --- a/compiler/rustc_mir_transform/src/check_alignment.rs +++ b/compiler/rustc_mir_transform/src/check_alignment.rs @@ -136,7 +136,7 @@ fn insert_alignment_check<'tcx>( .statements .push(Statement { source_info, kind: StatementKind::Assign(Box::new((thin_ptr, rvalue))) }); - // Cast the pointer to a usize + // Transmute the pointer to a usize (equivalent to `ptr.addr()`) let rvalue = Rvalue::Cast(CastKind::Transmute, Operand::Copy(thin_ptr), tcx.types.usize); let addr = local_decls.push(LocalDecl::with_source_info(tcx.types.usize, source_info)).into(); block_data From c2fddfd8e256855c11529b79a4987b2137590f90 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 24 Mar 2023 16:01:26 +0100 Subject: [PATCH 122/346] miri: fix raw pointer dyn receivers --- .../src/interpret/terminator.rs | 10 ++++++- .../miri/tests/pass/dyn-arbitrary-self.rs | 27 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index c2d1bc11c37..fc83985eaca 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -539,7 +539,15 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let mut receiver = args[0].clone(); let receiver_place = loop { match receiver.layout.ty.kind() { - ty::Ref(..) | ty::RawPtr(..) => break self.deref_operand(&receiver)?, + ty::Ref(..) | ty::RawPtr(..) => { + // We do *not* use `deref_operand` here: we don't want to conceptually + // create a place that must be dereferenceable, since the receiver might + // be a raw pointer and (for `*const dyn Trait`) we don't need to + // actually access memory to resolve this method. + // Also see . + let val = self.read_immediate(&receiver)?; + break self.ref_to_mplace(&val)?; + } ty::Dynamic(.., ty::Dyn) => break receiver.assert_mem_place(), // no immediate unsized values ty::Dynamic(.., ty::DynStar) => { // Not clear how to handle this, so far we assume the receiver is always a pointer. diff --git a/src/tools/miri/tests/pass/dyn-arbitrary-self.rs b/src/tools/miri/tests/pass/dyn-arbitrary-self.rs index 94cf465e884..fc58775a195 100644 --- a/src/tools/miri/tests/pass/dyn-arbitrary-self.rs +++ b/src/tools/miri/tests/pass/dyn-arbitrary-self.rs @@ -123,8 +123,35 @@ fn pointers_and_wrappers() { assert_eq!(wpw.wrapper_ptr_wrapper(), 7); } +fn raw_ptr_receiver() { + use std::ptr; + + trait Foo { + fn foo(self: *const Self) -> &'static str; + } + + impl Foo for i32 { + fn foo(self: *const Self) -> &'static str { + "I'm an i32!" + } + } + + impl Foo for u32 { + fn foo(self: *const Self) -> &'static str { + "I'm a u32!" + } + } + + let null_i32 = ptr::null::() as *const dyn Foo; + let null_u32 = ptr::null::() as *const dyn Foo; + + assert_eq!("I'm an i32!", null_i32.foo()); + assert_eq!("I'm a u32!", null_u32.foo()); +} + fn main() { pin_box_dyn(); stdlib_pointers(); pointers_and_wrappers(); + raw_ptr_receiver(); } From 9cb7d4ca3932b87617276842b9d59b14a1cbe279 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 24 Mar 2023 16:57:55 +0100 Subject: [PATCH 123/346] Add GUI test for "Auto-hide item methods' documentation" setting --- .../setting-auto-hide-item-methods-docs.goml | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 tests/rustdoc-gui/setting-auto-hide-item-methods-docs.goml diff --git a/tests/rustdoc-gui/setting-auto-hide-item-methods-docs.goml b/tests/rustdoc-gui/setting-auto-hide-item-methods-docs.goml new file mode 100644 index 00000000000..e34fee33beb --- /dev/null +++ b/tests/rustdoc-gui/setting-auto-hide-item-methods-docs.goml @@ -0,0 +1,48 @@ +// This test ensures that the "Auto-hide item methods' documentation" setting is working as +// expected. + +define-function: ( + "check-setting", + (storage_value, setting_attribute_value, toggle_attribute_value), + block { + assert-local-storage: {"rustdoc-auto-hide-method-docs": |storage_value|} + click: "#settings-menu" + wait-for: "#settings" + assert-property: ("#auto-hide-method-docs", {"checked": |setting_attribute_value|}) + assert-attribute: (".toggle.method-toggle", {"open": |toggle_attribute_value|}) + } +) + +goto: "file://" + |DOC_PATH| + "/lib2/struct.Foo.html" + +// We check that the setting is disabled by default. +call-function: ("check-setting", { + "storage_value": null, + "setting_attribute_value": "false", + "toggle_attribute_value": "", +}) + +// Now we change its value. +click: "#auto-hide-method-docs" +assert-local-storage: {"rustdoc-auto-hide-method-docs": "true"} + +// We check that the changes were applied as expected. +reload: + +call-function: ("check-setting", { + "storage_value": "true", + "setting_attribute_value": "true", + "toggle_attribute_value": null, +}) + +// And now we re-disable the setting. +click: "#auto-hide-method-docs" +assert-local-storage: {"rustdoc-auto-hide-method-docs": "false"} + +// And we check everything is back the way it was before. +reload: +call-function: ("check-setting", { + "storage_value": "false", + "setting_attribute_value": "false", + "toggle_attribute_value": "", +}) From 7f89c7c32dcee0e01bb1eda00fbdb77a9ab5e281 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 23 Mar 2023 05:40:50 +0000 Subject: [PATCH 124/346] Make EvalCtxt's infcx private --- .../src/solve/canonical/mod.rs | 57 ++------- .../src/solve/eval_ctxt.rs | 112 +++++++++++++++++- .../rustc_trait_selection/src/solve/mod.rs | 24 ++-- .../src/solve/project_goals.rs | 16 ++- 4 files changed, 134 insertions(+), 75 deletions(-) diff --git a/compiler/rustc_trait_selection/src/solve/canonical/mod.rs b/compiler/rustc_trait_selection/src/solve/canonical/mod.rs index efecaf33ef9..d393ab1ba4a 100644 --- a/compiler/rustc_trait_selection/src/solve/canonical/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/canonical/mod.rs @@ -8,17 +8,15 @@ /// section of the [rustc-dev-guide][c]. /// /// [c]: https://rustc-dev-guide.rust-lang.org/solve/canonicalization.html -use self::canonicalize::{CanonicalizeMode, Canonicalizer}; +pub use self::canonicalize::{CanonicalizeMode, Canonicalizer}; + use super::{CanonicalGoal, Certainty, EvalCtxt, Goal}; -use super::{CanonicalResponse, ExternalConstraints, QueryResult, Response}; -use rustc_infer::infer::canonical::query_response::make_query_region_constraints; +use super::{CanonicalResponse, QueryResult, Response}; use rustc_infer::infer::canonical::CanonicalVarValues; use rustc_infer::infer::canonical::{CanonicalExt, QueryRegionConstraints}; use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::solve::ExternalConstraintsData; -use rustc_infer::traits::ObligationCause; use rustc_middle::ty::{self, GenericArgKind}; -use rustc_span::DUMMY_SP; use std::iter; use std::ops::Deref; @@ -32,12 +30,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { goal: Goal<'tcx, ty::Predicate<'tcx>>, ) -> (Vec>, CanonicalGoal<'tcx>) { let mut orig_values = Default::default(); - let canonical_goal = Canonicalizer::canonicalize( - self.infcx, - CanonicalizeMode::Input, - &mut orig_values, - goal, - ); + let canonical_goal = self.canonicalize(CanonicalizeMode::Input, &mut orig_values, goal); (orig_values, canonical_goal) } @@ -58,8 +51,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { let external_constraints = self.compute_external_query_constraints()?; let response = Response { var_values: self.var_values, external_constraints, certainty }; - let canonical = Canonicalizer::canonicalize( - self.infcx, + let canonical = self.canonicalize( CanonicalizeMode::Response { max_input_universe: self.max_input_universe }, &mut Default::default(), response, @@ -67,26 +59,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { Ok(canonical) } - #[instrument(level = "debug", skip(self), ret)] - fn compute_external_query_constraints(&self) -> Result, NoSolution> { - // Cannot use `take_registered_region_obligations` as we may compute the response - // inside of a `probe` whenever we have multiple choices inside of the solver. - let region_obligations = self.infcx.inner.borrow().region_obligations().to_owned(); - let region_constraints = self.infcx.with_region_constraints(|region_constraints| { - make_query_region_constraints( - self.tcx(), - region_obligations - .iter() - .map(|r_o| (r_o.sup_type, r_o.sub_region, r_o.origin.to_constraint_category())), - region_constraints, - ) - }); - let opaque_types = self.infcx.clone_opaque_types_for_query_response(); - Ok(self - .tcx() - .mk_external_constraints(ExternalConstraintsData { region_constraints, opaque_types })) - } - /// After calling a canonical query, we apply the constraints returned /// by the query using this function. /// @@ -126,10 +98,10 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { // FIXME: Longterm canonical queries should deal with all placeholders // created inside of the query directly instead of returning them to the // caller. - let prev_universe = self.infcx.universe(); + let prev_universe = self.universe(); let universes_created_in_query = response.max_universe.index() + 1; for _ in 0..universes_created_in_query { - self.infcx.create_next_universe(); + self.create_next_universe(); } let var_values = response.value.var_values; @@ -172,7 +144,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { // A variable from inside a binder of the query. While ideally these shouldn't // exist at all (see the FIXME at the start of this method), we have to deal with // them for now. - self.infcx.instantiate_canonical_var(DUMMY_SP, info, |idx| { + self.instantiate_canonical_var(info, |idx| { ty::UniverseIndex::from(prev_universe.index() + idx.index()) }) } else if info.is_existential() { @@ -186,7 +158,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { if let Some(v) = opt_values[index] { v } else { - self.infcx.instantiate_canonical_var(DUMMY_SP, info, |_| prev_universe) + self.instantiate_canonical_var(info, |_| prev_universe) } } else { // For placeholders which were already part of the input, we simply map this @@ -219,15 +191,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { fn register_region_constraints(&mut self, region_constraints: &QueryRegionConstraints<'tcx>) { for &(ty::OutlivesPredicate(lhs, rhs), _) in ®ion_constraints.outlives { match lhs.unpack() { - GenericArgKind::Lifetime(lhs) => self.infcx.region_outlives_predicate( - &ObligationCause::dummy(), - ty::Binder::dummy(ty::OutlivesPredicate(lhs, rhs)), - ), - GenericArgKind::Type(lhs) => self.infcx.register_region_obligation_with_cause( - lhs, - rhs, - &ObligationCause::dummy(), - ), + GenericArgKind::Lifetime(lhs) => self.register_region_outlives(lhs, rhs), + GenericArgKind::Type(lhs) => self.register_ty_outlives(lhs, rhs), GenericArgKind::Const(_) => bug!("const outlives: {lhs:?}: {rhs:?}"), } } diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs index e47b5ae21b5..92aff517fbb 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs @@ -1,14 +1,17 @@ use rustc_hir::def_id::DefId; use rustc_infer::infer::at::ToTrace; -use rustc_infer::infer::canonical::CanonicalVarValues; +use rustc_infer::infer::canonical::query_response::make_query_region_constraints; +use rustc_infer::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarValues}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::{ DefineOpaqueTypes, InferCtxt, InferOk, LateBoundRegionConversionTime, TyCtxtInferExt, }; use rustc_infer::traits::query::NoSolution; -use rustc_infer::traits::solve::{CanonicalGoal, Certainty, MaybeCause, QueryResult}; use rustc_infer::traits::ObligationCause; use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; +use rustc_middle::traits::solve::{ + CanonicalGoal, Certainty, ExternalConstraints, ExternalConstraintsData, MaybeCause, QueryResult, +}; use rustc_middle::ty::{ self, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, @@ -16,13 +19,31 @@ use rustc_middle::ty::{ use rustc_span::DUMMY_SP; use std::ops::ControlFlow; +use crate::traits::specialization_graph; + +use super::canonical::{CanonicalizeMode, Canonicalizer}; use super::search_graph::{self, OverflowHandler}; use super::SolverMode; use super::{search_graph::SearchGraph, Goal}; pub struct EvalCtxt<'a, 'tcx> { - // FIXME: should be private. - pub(super) infcx: &'a InferCtxt<'tcx>, + /// The inference context that backs (mostly) inference and placeholder terms + /// instantiated while solving goals. + /// + /// NOTE: The `InferCtxt` that backs the `EvalCtxt` is intentionally private, + /// because the `InferCtxt` is much more general than `EvalCtxt`. Methods such + /// as `take_registered_region_obligations` can mess up query responses, + /// using `At::normalize` is totally wrong, calling `evaluate_root_goal` can + /// cause coinductive unsoundness, etc. + /// + /// Methods that are generally of use for trait solving are *intentionally* + /// re-declared through the `EvalCtxt` below, often with cleaner signatures + /// since we don't care about things like `ObligationCause`s and `Span`s here. + /// If some `InferCtxt` method is missing, please first think defensively about + /// the method's compatibility with this solver, or if an existing one does + /// the job already. + infcx: &'a InferCtxt<'tcx>, + pub(super) var_values: CanonicalVarValues<'tcx>, /// The highest universe index nameable by the caller. /// @@ -548,4 +569,87 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { pub(super) fn universe(&self) -> ty::UniverseIndex { self.infcx.universe() } + + pub(super) fn create_next_universe(&self) -> ty::UniverseIndex { + self.infcx.create_next_universe() + } + + pub(super) fn instantiate_canonical_var( + &self, + cv_info: CanonicalVarInfo<'tcx>, + universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex, + ) -> ty::GenericArg<'tcx> { + self.infcx.instantiate_canonical_var(DUMMY_SP, cv_info, universe_map) + } + + pub(super) fn translate_substs( + &self, + param_env: ty::ParamEnv<'tcx>, + source_impl: DefId, + source_substs: ty::SubstsRef<'tcx>, + target_node: specialization_graph::Node, + ) -> ty::SubstsRef<'tcx> { + crate::traits::translate_substs( + self.infcx, + param_env, + source_impl, + source_substs, + target_node, + ) + } + + pub(super) fn register_ty_outlives(&self, ty: Ty<'tcx>, lt: ty::Region<'tcx>) { + self.infcx.register_region_obligation_with_cause(ty, lt, &ObligationCause::dummy()); + } + + pub(super) fn register_region_outlives(&self, a: ty::Region<'tcx>, b: ty::Region<'tcx>) { + // `b : a` ==> `a <= b` + // (inlined from `InferCtxt::region_outlives_predicate`) + self.infcx.sub_regions( + rustc_infer::infer::SubregionOrigin::RelateRegionParamBound(DUMMY_SP), + b, + a, + ); + } + + /// Computes the list of goals required for `arg` to be well-formed + pub(super) fn well_formed_goals( + &self, + param_env: ty::ParamEnv<'tcx>, + arg: ty::GenericArg<'tcx>, + ) -> Option>>> { + crate::traits::wf::unnormalized_obligations(self.infcx, param_env, arg) + .map(|obligations| obligations.into_iter().map(|obligation| obligation.into())) + } + + #[instrument(level = "debug", skip(self), ret)] + pub(super) fn compute_external_query_constraints( + &self, + ) -> Result, NoSolution> { + // Cannot use `take_registered_region_obligations` as we may compute the response + // inside of a `probe` whenever we have multiple choices inside of the solver. + let region_obligations = self.infcx.inner.borrow().region_obligations().to_owned(); + let region_constraints = self.infcx.with_region_constraints(|region_constraints| { + make_query_region_constraints( + self.tcx(), + region_obligations + .iter() + .map(|r_o| (r_o.sup_type, r_o.sub_region, r_o.origin.to_constraint_category())), + region_constraints, + ) + }); + let opaque_types = self.infcx.clone_opaque_types_for_query_response(); + Ok(self + .tcx() + .mk_external_constraints(ExternalConstraintsData { region_constraints, opaque_types })) + } + + pub(super) fn canonicalize>>( + &self, + canonicalize_mode: CanonicalizeMode, + variables: &mut Vec>, + value: T, + ) -> Canonical<'tcx, T> { + Canonicalizer::canonicalize(self.infcx, canonicalize_mode, variables, value) + } } diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index 6a64dfdedd4..7c01d5d2bef 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -15,16 +15,14 @@ use rustc_hir::def_id::DefId; use rustc_infer::infer::canonical::{Canonical, CanonicalVarValues}; use rustc_infer::traits::query::NoSolution; use rustc_middle::traits::solve::{ - CanonicalGoal, CanonicalResponse, Certainty, ExternalConstraints, ExternalConstraintsData, - Goal, QueryResult, Response, + CanonicalGoal, CanonicalResponse, Certainty, ExternalConstraintsData, Goal, QueryResult, + Response, }; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{ CoercePredicate, RegionOutlivesPredicate, SubtypePredicate, TypeOutlivesPredicate, }; -use crate::traits::ObligationCause; - mod assembly; mod canonical; mod eval_ctxt; @@ -68,7 +66,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { goal: Goal<'tcx, TypeOutlivesPredicate<'tcx>>, ) -> QueryResult<'tcx> { let ty::OutlivesPredicate(ty, lt) = goal.predicate; - self.infcx.register_region_obligation_with_cause(ty, lt, &ObligationCause::dummy()); + self.register_ty_outlives(ty, lt); self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } @@ -77,10 +75,8 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { &mut self, goal: Goal<'tcx, RegionOutlivesPredicate<'tcx>>, ) -> QueryResult<'tcx> { - self.infcx.region_outlives_predicate( - &ObligationCause::dummy(), - ty::Binder::dummy(goal.predicate), - ); + let ty::OutlivesPredicate(a, b) = goal.predicate; + self.register_region_outlives(a, b); self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } @@ -146,13 +142,9 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { &mut self, goal: Goal<'tcx, ty::GenericArg<'tcx>>, ) -> QueryResult<'tcx> { - match crate::traits::wf::unnormalized_obligations( - self.infcx, - goal.param_env, - goal.predicate, - ) { - Some(obligations) => { - self.add_goals(obligations.into_iter().map(|o| o.into())); + match self.well_formed_goals(goal.param_env, goal.predicate) { + Some(goals) => { + self.add_goals(goals); self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } None => self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS), diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index 525b3105538..4c61a2cb2cc 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -1,4 +1,4 @@ -use crate::traits::{specialization_graph, translate_substs}; +use crate::traits::specialization_graph; use super::assembly; use super::trait_goals::structural_traits; @@ -7,7 +7,6 @@ use rustc_errors::ErrorGuaranteed; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_hir::LangItem; -use rustc_infer::infer::InferCtxt; use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::specialization_graph::LeafDef; use rustc_infer::traits::Reveal; @@ -168,7 +167,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { // return ambiguity this would otherwise be incomplete, resulting in // unsoundness during coherence (#105782). let Some(assoc_def) = fetch_eligible_assoc_item_def( - ecx.infcx, + ecx, goal.param_env, goal_trait_ref, goal.predicate.def_id(), @@ -199,8 +198,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { goal_trait_ref.def_id, impl_substs, ); - let substs = translate_substs( - ecx.infcx, + let substs = ecx.translate_substs( goal.param_env, impl_def_id, impl_substs_with_gat, @@ -500,15 +498,15 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { /// /// FIXME: We should merge these 3 implementations as it's likely that they otherwise /// diverge. -#[instrument(level = "debug", skip(infcx, param_env), ret)] +#[instrument(level = "debug", skip(ecx, param_env), ret)] fn fetch_eligible_assoc_item_def<'tcx>( - infcx: &InferCtxt<'tcx>, + ecx: &EvalCtxt<'_, 'tcx>, param_env: ty::ParamEnv<'tcx>, goal_trait_ref: ty::TraitRef<'tcx>, trait_assoc_def_id: DefId, impl_def_id: DefId, ) -> Result, NoSolution> { - let node_item = specialization_graph::assoc_def(infcx.tcx, impl_def_id, trait_assoc_def_id) + let node_item = specialization_graph::assoc_def(ecx.tcx(), impl_def_id, trait_assoc_def_id) .map_err(|ErrorGuaranteed { .. }| NoSolution)?; let eligible = if node_item.is_final() { @@ -520,7 +518,7 @@ fn fetch_eligible_assoc_item_def<'tcx>( // transmute checking and polymorphic MIR optimizations could // get a result which isn't correct for all monomorphizations. if param_env.reveal() == Reveal::All { - let poly_trait_ref = infcx.resolve_vars_if_possible(goal_trait_ref); + let poly_trait_ref = ecx.resolve_vars_if_possible(goal_trait_ref); !poly_trait_ref.still_further_specializable() } else { debug!(?node_item.item.def_id, "not eligible due to default"); From a71b808d779d52cbddffe651eda761644cd9da70 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Fri, 24 Mar 2023 12:34:49 -0400 Subject: [PATCH 125/346] Use Vec::split_off --- compiler/rustc_mir_transform/src/check_alignment.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_mir_transform/src/check_alignment.rs b/compiler/rustc_mir_transform/src/check_alignment.rs index 694102388cf..ee5272749fe 100644 --- a/compiler/rustc_mir_transform/src/check_alignment.rs +++ b/compiler/rustc_mir_transform/src/check_alignment.rs @@ -111,7 +111,7 @@ fn split_block( // Drain every statement after this one and move the current terminator to a new basic block let new_block = BasicBlockData { - statements: block_data.statements.drain(location.statement_index..).collect(), + statements: block_data.statements.split_off(location.statement_index), terminator: block_data.terminator.take(), is_cleanup: block_data.is_cleanup, }; From 67540ec950b9bb5919c3c51dcf9fd6b3d380b7dc Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Fri, 24 Mar 2023 12:35:16 -0400 Subject: [PATCH 126/346] Skip checks for common types with alignment 1 --- compiler/rustc_mir_transform/src/check_alignment.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/compiler/rustc_mir_transform/src/check_alignment.rs b/compiler/rustc_mir_transform/src/check_alignment.rs index ee5272749fe..996416ef22e 100644 --- a/compiler/rustc_mir_transform/src/check_alignment.rs +++ b/compiler/rustc_mir_transform/src/check_alignment.rs @@ -99,6 +99,13 @@ impl<'tcx, 'a> Visitor<'tcx> for PointerFinder<'tcx, 'a> { return; } + if [self.tcx.types.bool, self.tcx.types.i8, self.tcx.types.u8, self.tcx.types.str_] + .contains(&pointee_ty) + { + debug!("Trivially aligned pointee type: {:?}", pointer_ty); + return; + } + self.pointers.push((pointer, pointee_ty)) } } From 910a5ad2dfbff6c29092b73e696349eb45eb1aa5 Mon Sep 17 00:00:00 2001 From: Mu001999 Date: Sat, 25 Mar 2023 01:00:49 +0800 Subject: [PATCH 127/346] Emits suggestions for expressions with parentheses or not separately --- compiler/rustc_lint/messages.ftl | 4 +++- compiler/rustc_lint/src/lints.rs | 33 +++++++++++++++++++++++++------ compiler/rustc_lint/src/types.rs | 28 ++++++++++++++++++-------- tests/ui/lint/issue-109529.rs | 5 ++--- tests/ui/lint/issue-109529.stderr | 23 ++++++++++++--------- 5 files changed, 66 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 68e62c9789a..5b7e994e035 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -197,7 +197,9 @@ lint_drop_glue = types that do not implement `Drop` can still have drop glue, consider instead using `{$needs_drop}` to detect whether a type is trivially dropped lint_range_endpoint_out_of_range = range endpoint is out of range for `{$ty}` - .suggestion = use an inclusive range instead + +lint_range_use_inclusive_range = use an inclusive range instead + lint_overflowing_bin_hex = literal out of range for `{$ty}` .negative_note = the literal `{$lit}` (decimal `{$dec}`) does not fit into the type `{$ty}` diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 925e9654f93..8ec4c2b3d46 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -1210,12 +1210,33 @@ impl<'a> DecorateLint<'a, ()> for DropGlue<'_> { #[diag(lint_range_endpoint_out_of_range)] pub struct RangeEndpointOutOfRange<'a> { pub ty: &'a str, - #[suggestion(code = "=", applicability = "machine-applicable")] - pub eq_suggestion: Span, - #[suggestion(code = "{literal}{suffix}", applicability = "machine-applicable")] - pub lit_suggestion: Span, - pub literal: u128, - pub suffix: &'a str, + #[subdiagnostic] + pub sub: UseInclusiveRange<'a>, +} + +#[derive(Subdiagnostic)] +pub enum UseInclusiveRange<'a> { + #[suggestion( + lint_range_use_inclusive_range, + code = "{start}..={literal}{suffix}", + applicability = "machine-applicable" + )] + WithoutParen { + #[primary_span] + sugg: Span, + start: String, + literal: u128, + suffix: &'a str, + }, + #[multipart_suggestion(lint_range_use_inclusive_range, applicability = "machine-applicable")] + WithParen { + #[suggestion_part(code = "=")] + eq_sugg: Span, + #[suggestion_part(code = "{literal}{suffix}")] + lit_sugg: Span, + literal: u128, + suffix: &'a str, + }, } #[derive(LintDiagnostic)] diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 1cc873c6de9..f6bca7045c8 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -4,7 +4,8 @@ use crate::{ AtomicOrderingFence, AtomicOrderingLoad, AtomicOrderingStore, ImproperCTypes, InvalidAtomicOrderingDiag, OnlyCastu8ToChar, OverflowingBinHex, OverflowingBinHexSign, OverflowingBinHexSub, OverflowingInt, OverflowingIntHelp, OverflowingLiteral, - OverflowingUInt, RangeEndpointOutOfRange, UnusedComparisons, VariantSizeDifferencesDiag, + OverflowingUInt, RangeEndpointOutOfRange, UnusedComparisons, UseInclusiveRange, + VariantSizeDifferencesDiag, }, }; use crate::{LateContext, LateLintPass, LintContext}; @@ -172,16 +173,27 @@ fn lint_overflowing_range_endpoint<'tcx>( _ => bug!(), }; + let sub_sugg = if expr.span.lo() == lit_span.lo() { + let Ok(start) = cx.sess().source_map().span_to_snippet(eps[0].span) else { return false }; + UseInclusiveRange::WithoutParen { + sugg: struct_expr.span.shrink_to_lo().to(lit_span.shrink_to_hi()), + start, + literal: lit_val - 1, + suffix, + } + } else { + UseInclusiveRange::WithParen { + eq_sugg: expr.span.shrink_to_lo(), + lit_sugg: lit_span, + literal: lit_val - 1, + suffix, + } + }; + cx.emit_spanned_lint( OVERFLOWING_LITERALS, struct_expr.span, - RangeEndpointOutOfRange { - ty, - eq_suggestion: expr.span.shrink_to_lo(), - lit_suggestion: lit_span, - literal: lit_val - 1, - suffix, - }, + RangeEndpointOutOfRange { ty, sub: sub_sugg }, ); // We've just emitted a lint, special cased for `(...)..MAX+1` ranges, diff --git a/tests/ui/lint/issue-109529.rs b/tests/ui/lint/issue-109529.rs index 36c6d4fdfe3..c9b4da4b26e 100644 --- a/tests/ui/lint/issue-109529.rs +++ b/tests/ui/lint/issue-109529.rs @@ -1,5 +1,4 @@ fn main() { - for i in 0..(256 as u8) { //~ ERROR range endpoint is out of range - println!("{}", i); - } + for _ in 0..256 as u8 {} //~ ERROR range endpoint is out of range + for _ in 0..(256 as u8) {} //~ ERROR range endpoint is out of range } diff --git a/tests/ui/lint/issue-109529.stderr b/tests/ui/lint/issue-109529.stderr index e9f6d546ac2..15b259ad55e 100644 --- a/tests/ui/lint/issue-109529.stderr +++ b/tests/ui/lint/issue-109529.stderr @@ -1,18 +1,23 @@ error: range endpoint is out of range for `u8` --> $DIR/issue-109529.rs:2:14 | -LL | for i in 0..(256 as u8) { - | ^^^^^^^^^^^^^^ +LL | for _ in 0..256 as u8 {} + | ------^^^^^^ + | | + | help: use an inclusive range instead: `0..=255` | = note: `#[deny(overflowing_literals)]` on by default + +error: range endpoint is out of range for `u8` + --> $DIR/issue-109529.rs:3:14 + | +LL | for _ in 0..(256 as u8) {} + | ^^^^^^^^^^^^^^ + | help: use an inclusive range instead | -LL | for i in 0..=(256 as u8) { - | + -help: use an inclusive range instead - | -LL | for i in 0..(255 as u8) { - | ~~~ +LL | for _ in 0..=(255 as u8) {} + | + ~~~ -error: aborting due to previous error +error: aborting due to 2 previous errors From 3e9ea5da6345d3f5fe88cbaaaa16637a8c59ec49 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 24 Mar 2023 18:53:36 +0000 Subject: [PATCH 128/346] Adjust documentation. --- compiler/rustc_attr/src/builtin.rs | 32 +++++++++++++++++------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index ccc5eedfe26..a29e389953e 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -226,8 +226,8 @@ impl UnstableReason { } } -/// Collects stability info from all stability attributes in `attrs`. -/// Returns `None` if no stability attributes are found. +/// Collects stability info from `stable`/`unstable`/`rustc_allowed_through_unstable_modules` +/// attributes in `attrs`. Returns `None` if no stability attributes are found. pub fn find_stability( sess: &Session, attrs: &[Attribute], @@ -280,8 +280,8 @@ pub fn find_stability( stab } -/// Collects stability info from all stability attributes in `attrs`. -/// Returns `None` if no stability attributes are found. +/// Collects stability info from `rustc_const_stable`/`rustc_const_unstable`/`rustc_promotable` +/// attributes in `attrs`. Returns `None` if no stability attributes are found. pub fn find_const_stability( sess: &Session, attrs: &[Attribute], @@ -329,7 +329,7 @@ pub fn find_const_stability( const_stab } -/// Collects stability info from all stability attributes in `attrs`. +/// Collects stability info from `rustc_default_body_unstable` attributes in `attrs`. /// Returns `None` if no stability attributes are found. pub fn find_body_stability( sess: &Session, @@ -353,10 +353,12 @@ pub fn find_body_stability( body_stab } +/// Read the content of a `stable`/`rustc_const_stable` attribute, and return the feature name and +/// its stability information. fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, StabilityLevel)> { let meta = attr.meta()?; let MetaItem { kind: MetaItemKind::List(ref metas), .. } = meta else { return None }; - let insert = |meta: &MetaItem, item: &mut Option| { + let insert_or_error = |meta: &MetaItem, item: &mut Option| { if item.is_some() { handle_errors( &sess.parse_sess, @@ -388,12 +390,12 @@ fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabilit match mi.name_or_empty() { sym::feature => { - if !insert(mi, &mut feature) { + if !insert_or_error(mi, &mut feature) { return None; } } sym::since => { - if !insert(mi, &mut since) { + if !insert_or_error(mi, &mut since) { return None; } } @@ -431,10 +433,12 @@ fn parse_stability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabilit } } +/// Read the content of a `unstable`/`rustc_const_unstable`/`rustc_default_body_unstable` +/// attribute, and return the feature name and its stability information. fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, StabilityLevel)> { let meta = attr.meta()?; let MetaItem { kind: MetaItemKind::List(ref metas), .. } = meta else { return None }; - let insert = |meta: &MetaItem, item: &mut Option| { + let insert_or_error = |meta: &MetaItem, item: &mut Option| { if item.is_some() { handle_errors( &sess.parse_sess, @@ -470,21 +474,21 @@ fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabil match mi.name_or_empty() { sym::feature => { - if !insert(mi, &mut feature) { + if !insert_or_error(mi, &mut feature) { return None; } } sym::reason => { - if !insert(mi, &mut reason) { + if !insert_or_error(mi, &mut reason) { return None; } } sym::issue => { - if !insert(mi, &mut issue) { + if !insert_or_error(mi, &mut issue) { return None; } - // These unwraps are safe because `insert` ensures the meta item + // These unwraps are safe because `insert_or_error` ensures the meta item // is a name/value pair string literal. issue_num = match issue.unwrap().as_str() { "none" => None, @@ -512,7 +516,7 @@ fn parse_unstability(sess: &Session, attr: &Attribute) -> Option<(Symbol, Stabil is_soft = true; } sym::implied_by => { - if !insert(mi, &mut implied_by) { + if !insert_or_error(mi, &mut implied_by) { return None; } } From badfb17d2fc9ff79a6064058c58dcea7526457f4 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Thu, 23 Mar 2023 20:16:14 -0400 Subject: [PATCH 129/346] Add #[inline] to the Into for From impl --- library/core/src/convert/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs index 805354be089..8a8d4caf96f 100644 --- a/library/core/src/convert/mod.rs +++ b/library/core/src/convert/mod.rs @@ -722,6 +722,7 @@ where /// /// That is, this conversion is whatever the implementation of /// [From]<T> for U chooses to do. + #[inline] fn into(self) -> U { U::from(self) } From a1f48047bf99b0cdc423924c9a09b0759193f9a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sun, 26 Feb 2023 04:06:26 +0100 Subject: [PATCH 130/346] Use Rayon's TLV directly --- compiler/rustc_middle/src/ty/context/tls.rs | 59 +++++---------------- 1 file changed, 14 insertions(+), 45 deletions(-) diff --git a/compiler/rustc_middle/src/ty/context/tls.rs b/compiler/rustc_middle/src/ty/context/tls.rs index 5426ac8d739..47e6b08cc99 100644 --- a/compiler/rustc_middle/src/ty/context/tls.rs +++ b/compiler/rustc_middle/src/ty/context/tls.rs @@ -4,6 +4,8 @@ use crate::dep_graph::TaskDepsRef; use crate::ty::query; use rustc_data_structures::sync::{self, Lock}; use rustc_errors::Diagnostic; +#[cfg(not(parallel_compiler))] +use std::cell::Cell; use std::mem; use std::ptr; use thin_vec::ThinVec; @@ -47,52 +49,15 @@ impl<'a, 'tcx> ImplicitCtxt<'a, 'tcx> { } } +// Import the thread-local variable from Rayon, which is preserved for Rayon jobs. #[cfg(parallel_compiler)] -mod tlv { - use rustc_rayon_core as rayon_core; - use std::ptr; - - /// Gets Rayon's thread-local variable, which is preserved for Rayon jobs. - /// This is used to get the pointer to the current `ImplicitCtxt`. - #[inline] - pub(super) fn get_tlv() -> *const () { - ptr::from_exposed_addr(rayon_core::tlv::get()) - } - - /// Sets Rayon's thread-local variable, which is preserved for Rayon jobs - /// to `value` during the call to `f`. It is restored to its previous value after. - /// This is used to set the pointer to the new `ImplicitCtxt`. - #[inline] - pub(super) fn with_tlv R, R>(value: *const (), f: F) -> R { - rayon_core::tlv::with(value.expose_addr(), f) - } -} +use rustc_rayon_core::tlv::TLV; +// Otherwise define our own #[cfg(not(parallel_compiler))] -mod tlv { - use std::cell::Cell; - use std::ptr; - - thread_local! { - /// A thread local variable that stores a pointer to the current `ImplicitCtxt`. - static TLV: Cell<*const ()> = const { Cell::new(ptr::null()) }; - } - - /// Gets the pointer to the current `ImplicitCtxt`. - #[inline] - pub(super) fn get_tlv() -> *const () { - TLV.with(|tlv| tlv.get()) - } - - /// Sets TLV to `value` during the call to `f`. - /// It is restored to its previous value after. - /// This is used to set the pointer to the new `ImplicitCtxt`. - #[inline] - pub(super) fn with_tlv R, R>(value: *const (), f: F) -> R { - let old = TLV.replace(value); - let _reset = rustc_data_structures::OnDrop(move || TLV.set(old)); - f() - } +thread_local! { + /// A thread local variable that stores a pointer to the current `ImplicitCtxt`. + static TLV: Cell<*const ()> = const { Cell::new(ptr::null()) }; } #[inline] @@ -111,7 +76,11 @@ pub fn enter_context<'a, 'tcx, F, R>(context: &ImplicitCtxt<'a, 'tcx>, f: F) -> where F: FnOnce() -> R, { - tlv::with_tlv(erase(context), f) + TLV.with(|tlv| { + let old = tlv.replace(erase(context)); + let _reset = rustc_data_structures::OnDrop(move || tlv.set(old)); + f() + }) } /// Allows access to the current `ImplicitCtxt` in a closure if one is available. @@ -120,7 +89,7 @@ pub fn with_context_opt(f: F) -> R where F: for<'a, 'tcx> FnOnce(Option<&ImplicitCtxt<'a, 'tcx>>) -> R, { - let context = tlv::get_tlv(); + let context = TLV.get(); if context.is_null() { f(None) } else { From 4d5501037a39a3c58421a02c45aec31a1d57300e Mon Sep 17 00:00:00 2001 From: Jon Gjengset Date: Fri, 24 Mar 2023 16:29:38 -0700 Subject: [PATCH 131/346] Allow long link names in tar files Without this, users trying to run `x.py dist` under a sufficiently long path run into problems when we build the resulting tarballs due to length limits in the original tar spec. The error looks like: Finished release [optimized + debuginfo] target(s) in 0.34s Copying stage0 std from stage0 (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu / x86_64-unknown-linux-musl) Building stage0 tool rust-installer (x86_64-unknown-linux-gnu) Finished release [optimized] target(s) in 0.35s Dist rust-std-1.67.1-x86_64-unknown-linux-musl Error: failed to generate installer Caused by: 0: failed to tar file '/home/AAAAAAAAAAAAAA/BBBBBB/CCCC/DDD/EEEEE/FFFFFFFFFFFF/GGGGGGGGGGGGGGGG/HHHHHHHHHH/IIIIIIIIIIIIIII/JJJJJ/KKKKKKK/src/build/tmp/tarball/rust-std/x86_64-unknown-linux-musl/rust-std-1.67.1-x86_64-unknown-linux-musl/rust-std-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/self-contained/libc.a' 1: provided value is too long when setting link name for Build completed unsuccessfully in 0:00:03 The fix is to make use of the widely-supported GNU tar extensions which lift this restriction. Switching to [`tar::Builder::append_link`] takes care of that for us. See also alexcrichton/tar-rs#273. [`tar::Builder::append_link`]: https://docs.rs/tar/0.4.38/tar/struct.Builder.html#method.append_link --- src/tools/rust-installer/Cargo.toml | 2 +- src/tools/rust-installer/src/tarballer.rs | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/tools/rust-installer/Cargo.toml b/src/tools/rust-installer/Cargo.toml index 38b81a1baac..788e556b0c6 100644 --- a/src/tools/rust-installer/Cargo.toml +++ b/src/tools/rust-installer/Cargo.toml @@ -13,7 +13,7 @@ path = "src/main.rs" anyhow = "1.0.19" flate2 = "1.0.1" rayon = "1.0" -tar = "0.4.13" +tar = "0.4.38" walkdir = "2" xz2 = "0.1.4" num_cpus = "1" diff --git a/src/tools/rust-installer/src/tarballer.rs b/src/tools/rust-installer/src/tarballer.rs index 592eba8f698..7353a49fe03 100644 --- a/src/tools/rust-installer/src/tarballer.rs +++ b/src/tools/rust-installer/src/tarballer.rs @@ -1,6 +1,6 @@ use anyhow::{bail, Context, Result}; use std::fs::{read_link, symlink_metadata}; -use std::io::{empty, BufWriter, Write}; +use std::io::{BufWriter, Write}; use std::path::Path; use tar::{Builder, Header}; use walkdir::WalkDir; @@ -93,8 +93,7 @@ fn append_path(builder: &mut Builder, src: &Path, path: &String) -> header.set_metadata(&stat); if stat.file_type().is_symlink() { let link = read_link(src)?; - header.set_link_name(&link)?; - builder.append_data(&mut header, path, &mut empty())?; + builder.append_link(&mut header, path, &link)?; } else { if cfg!(windows) { // Windows doesn't really have a mode, so `tar` never marks files executable. From 27c44d2e28d9e1e38526dd52ac2f07336aabe254 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 25 Mar 2023 02:12:13 +0100 Subject: [PATCH 132/346] Update indexmap and rayon crates --- Cargo.lock | 14 ++++++-------- compiler/rustc_codegen_cranelift/Cargo.lock | 4 ++-- compiler/rustc_codegen_cranelift/Cargo.toml | 2 +- compiler/rustc_data_structures/Cargo.toml | 8 ++++---- compiler/rustc_interface/Cargo.toml | 6 +++--- compiler/rustc_interface/src/util.rs | 2 +- compiler/rustc_middle/Cargo.toml | 4 ++-- compiler/rustc_middle/src/ty/context/tls.rs | 2 +- compiler/rustc_query_impl/Cargo.toml | 2 +- compiler/rustc_query_system/Cargo.toml | 2 +- compiler/rustc_query_system/src/query/job.rs | 2 +- compiler/rustc_serialize/Cargo.toml | 2 +- compiler/rustc_span/Cargo.toml | 2 +- 13 files changed, 25 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 449f0c73588..9f9fce34541 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2689,9 +2689,9 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" [[package]] name = "indexmap" -version = "1.9.2" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown 0.12.3", @@ -4160,21 +4160,19 @@ dependencies = [ [[package]] name = "rustc-rayon" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a79f0b0b2609e2eacf9758013f50e7176cb4b29fd6436a747b14a5362c8727a" +checksum = "eb81aadc8837ca6ecebe0fe1353f15df83b3b3cc2cf7a8afd571bc22aa121710" dependencies = [ - "autocfg", - "crossbeam-deque", "either", "rustc-rayon-core", ] [[package]] name = "rustc-rayon-core" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02269144a0db9bb55cf5d4a41a5a0e95b334b0b78b08269018ca9b0250718c30" +checksum = "67668daaf00e359c126f6dcb40d652d89b458a008c8afa727a42a2d20fca0b7f" dependencies = [ "crossbeam-channel", "crossbeam-deque", diff --git a/compiler/rustc_codegen_cranelift/Cargo.lock b/compiler/rustc_codegen_cranelift/Cargo.lock index 157ef4bf389..87e4ac26605 100644 --- a/compiler/rustc_codegen_cranelift/Cargo.lock +++ b/compiler/rustc_codegen_cranelift/Cargo.lock @@ -235,9 +235,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.9.2" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown", diff --git a/compiler/rustc_codegen_cranelift/Cargo.toml b/compiler/rustc_codegen_cranelift/Cargo.toml index 0e64fba6bec..5dadcaaec42 100644 --- a/compiler/rustc_codegen_cranelift/Cargo.toml +++ b/compiler/rustc_codegen_cranelift/Cargo.toml @@ -25,7 +25,7 @@ target-lexicon = "0.12.0" gimli = { version = "0.26.0", default-features = false, features = ["write"]} object = { version = "0.29.0", default-features = false, features = ["std", "read_core", "write", "archive", "coff", "elf", "macho", "pe"] } -indexmap = "1.9.1" +indexmap = "1.9.3" libloading = { version = "0.7.3", optional = true } once_cell = "1.10.0" smallvec = "1.8.1" diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml index 056ee1f63be..0b2b03da208 100644 --- a/compiler/rustc_data_structures/Cargo.toml +++ b/compiler/rustc_data_structures/Cargo.toml @@ -10,12 +10,12 @@ arrayvec = { version = "0.7", default-features = false } bitflags = "1.2.1" cfg-if = "1.0" ena = "0.14.2" -indexmap = { version = "1.9.1" } +indexmap = { version = "1.9.3" } jobserver_crate = { version = "0.1.13", package = "jobserver" } libc = "0.2" measureme = "10.0.0" -rayon-core = { version = "0.4.0", package = "rustc-rayon-core", optional = true } -rayon = { version = "0.4.0", package = "rustc-rayon", optional = true } +rustc-rayon-core = { version = "0.5.0", optional = true } +rustc-rayon = { version = "0.5.0", optional = true } rustc_graphviz = { path = "../rustc_graphviz" } rustc-hash = "1.1.0" rustc_index = { path = "../rustc_index", package = "rustc_index" } @@ -51,4 +51,4 @@ features = [ memmap2 = "0.2.1" [features] -rustc_use_parallel_compiler = ["indexmap/rustc-rayon", "rayon", "rayon-core"] +rustc_use_parallel_compiler = ["indexmap/rustc-rayon", "rustc-rayon", "rustc-rayon-core"] diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml index 96d6a1cb062..98d3ab87f9c 100644 --- a/compiler/rustc_interface/Cargo.toml +++ b/compiler/rustc_interface/Cargo.toml @@ -8,8 +8,8 @@ edition = "2021" [dependencies] libloading = "0.7.1" tracing = "0.1" -rustc-rayon-core = { version = "0.4.0", optional = true } -rayon = { version = "0.4.0", package = "rustc-rayon", optional = true } +rustc-rayon-core = { version = "0.5.0", optional = true } +rustc-rayon = { version = "0.5.0", optional = true } smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } rustc_ast = { path = "../rustc_ast" } rustc_attr = { path = "../rustc_attr" } @@ -52,4 +52,4 @@ rustc_ty_utils = { path = "../rustc_ty_utils" } [features] llvm = ['rustc_codegen_llvm'] -rustc_use_parallel_compiler = ['rayon', 'rustc-rayon-core', 'rustc_query_impl/rustc_use_parallel_compiler', 'rustc_errors/rustc_use_parallel_compiler'] +rustc_use_parallel_compiler = ['rustc-rayon', 'rustc-rayon-core', 'rustc_query_impl/rustc_use_parallel_compiler', 'rustc_errors/rustc_use_parallel_compiler'] diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 8abdcebb751..aa95c43ef71 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -183,7 +183,7 @@ pub(crate) fn run_in_thread_pool_with_globals R + Send, R: Send>( .try_collect_active_jobs() .expect("active jobs shouldn't be locked in deadlock handler") }); - let registry = rustc_rayon_core::Registry::current(); + let registry = rayon_core::Registry::current(); thread::spawn(move || deadlock(query_map, ®istry)); }); if let Some(size) = get_stack_size() { diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index a2b78cc2985..5b2ec9029b1 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -26,8 +26,8 @@ rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_query_system = { path = "../rustc_query_system" } -rustc-rayon-core = { version = "0.4.0", optional = true } -rustc-rayon = { version = "0.4.0", optional = true } +rustc-rayon-core = { version = "0.5.0", optional = true } +rustc-rayon = { version = "0.5.0", optional = true } rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } diff --git a/compiler/rustc_middle/src/ty/context/tls.rs b/compiler/rustc_middle/src/ty/context/tls.rs index 47e6b08cc99..fb0d909307e 100644 --- a/compiler/rustc_middle/src/ty/context/tls.rs +++ b/compiler/rustc_middle/src/ty/context/tls.rs @@ -51,7 +51,7 @@ impl<'a, 'tcx> ImplicitCtxt<'a, 'tcx> { // Import the thread-local variable from Rayon, which is preserved for Rayon jobs. #[cfg(parallel_compiler)] -use rustc_rayon_core::tlv::TLV; +use rayon_core::tlv::TLV; // Otherwise define our own #[cfg(not(parallel_compiler))] diff --git a/compiler/rustc_query_impl/Cargo.toml b/compiler/rustc_query_impl/Cargo.toml index 3e8a88c7e81..b107a3f03fe 100644 --- a/compiler/rustc_query_impl/Cargo.toml +++ b/compiler/rustc_query_impl/Cargo.toml @@ -16,7 +16,7 @@ rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } rustc_middle = { path = "../rustc_middle" } rustc_query_system = { path = "../rustc_query_system" } -rustc-rayon-core = { version = "0.4.0", optional = true } +rustc-rayon-core = { version = "0.5.0", optional = true } rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } diff --git a/compiler/rustc_query_system/Cargo.toml b/compiler/rustc_query_system/Cargo.toml index 7d8f75e2566..12b4a114313 100644 --- a/compiler/rustc_query_system/Cargo.toml +++ b/compiler/rustc_query_system/Cargo.toml @@ -15,7 +15,7 @@ rustc_feature = { path = "../rustc_feature" } rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_macros = { path = "../rustc_macros" } -rustc-rayon-core = { version = "0.4.0", optional = true } +rustc-rayon-core = { version = "0.5.0", optional = true } rustc_serialize = { path = "../rustc_serialize" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs index a5a2f0093ce..d56a5955aff 100644 --- a/compiler/rustc_query_system/src/query/job.rs +++ b/compiler/rustc_query_system/src/query/job.rs @@ -18,11 +18,11 @@ use std::num::NonZeroU64; #[cfg(parallel_compiler)] use { parking_lot::{Condvar, Mutex}, + rayon_core, rustc_data_structures::fx::FxHashSet, rustc_data_structures::sync::Lock, rustc_data_structures::sync::Lrc, rustc_data_structures::{jobserver, OnDrop}, - rustc_rayon_core as rayon_core, rustc_span::DUMMY_SP, std::iter, std::process, diff --git a/compiler/rustc_serialize/Cargo.toml b/compiler/rustc_serialize/Cargo.toml index c0446571905..e4dbb8a637c 100644 --- a/compiler/rustc_serialize/Cargo.toml +++ b/compiler/rustc_serialize/Cargo.toml @@ -4,7 +4,7 @@ version = "0.0.0" edition = "2021" [dependencies] -indexmap = "1.9.1" +indexmap = "1.9.3" smallvec = { version = "1.8.1", features = ["union", "may_dangle"] } thin-vec = "0.2.12" diff --git a/compiler/rustc_span/Cargo.toml b/compiler/rustc_span/Cargo.toml index 98d6e0ab117..a7c7575f392 100644 --- a/compiler/rustc_span/Cargo.toml +++ b/compiler/rustc_span/Cargo.toml @@ -18,4 +18,4 @@ tracing = "0.1" sha1 = "0.10.0" sha2 = "0.10.1" md5 = { package = "md-5", version = "0.10.0" } -indexmap = { version = "1.9.1" } +indexmap = { version = "1.9.3" } From 53ec4bc63182570d16baca886819a046b7e43c52 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 25 Mar 2023 01:51:19 +0000 Subject: [PATCH 133/346] Remove some stale FIXMEs in new solver --- compiler/rustc_trait_selection/src/solve/mod.rs | 4 ---- compiler/rustc_trait_selection/src/solve/search_graph/mod.rs | 2 -- 2 files changed, 6 deletions(-) diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index 6a64dfdedd4..65e7bcb7f01 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -9,8 +9,6 @@ //! FIXME(@lcnr): Write that section. If you read this before then ask me //! about it on zulip. -// FIXME: uses of `infcx.at` need to enable deferred projection equality once that's implemented. - use rustc_hir::def_id::DefId; use rustc_infer::infer::canonical::{Canonical, CanonicalVarValues}; use rustc_infer::traits::query::NoSolution; @@ -105,8 +103,6 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { goal: Goal<'tcx, SubtypePredicate<'tcx>>, ) -> QueryResult<'tcx> { if goal.predicate.a.is_ty_var() && goal.predicate.b.is_ty_var() { - // FIXME: Do we want to register a subtype relation between these vars? - // That won't actually reflect in the query response, so it seems moot. self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS) } else { self.sub(goal.param_env, goal.predicate.a, goal.predicate.b)?; diff --git a/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs b/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs index 219890b9dc4..9773a3eacd6 100644 --- a/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs @@ -78,8 +78,6 @@ impl<'tcx> SearchGraph<'tcx> { tcx: TyCtxt<'tcx>, goal: CanonicalGoal<'tcx>, ) -> Result<(), QueryResult<'tcx>> { - // FIXME: start by checking the global cache - // Look at the provisional cache to check for cycles. let cache = &mut self.provisional_cache; match cache.lookup_table.entry(goal) { From 8f294066b32c13fb9865aecfc1ce9cd30e956555 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sun, 19 Mar 2023 23:48:08 +0100 Subject: [PATCH 134/346] Optimize `incremental_verify_ich` --- compiler/rustc_middle/src/dep_graph/mod.rs | 6 ++ .../rustc_query_system/src/dep_graph/graph.rs | 25 ++++-- .../rustc_query_system/src/dep_graph/mod.rs | 4 + .../src/dep_graph/serialized.rs | 5 -- .../rustc_query_system/src/query/plumbing.rs | 83 +++++++++++-------- 5 files changed, 74 insertions(+), 49 deletions(-) diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs index 84510fe218c..6ecfda4a1bf 100644 --- a/compiler/rustc_middle/src/dep_graph/mod.rs +++ b/compiler/rustc_middle/src/dep_graph/mod.rs @@ -71,6 +71,7 @@ impl rustc_query_system::dep_graph::DepKind for DepKind { } impl<'tcx> DepContext for TyCtxt<'tcx> { + type Implicit<'a> = TyCtxt<'a>; type DepKind = DepKind; #[inline] @@ -78,6 +79,11 @@ impl<'tcx> DepContext for TyCtxt<'tcx> { TyCtxt::with_stable_hashing_context(self, f) } + #[inline] + fn with_context(f: impl FnOnce(TyCtxt<'_>) -> R) -> R { + ty::tls::with(|tcx| f(tcx)) + } + #[inline] fn dep_graph(&self) -> &DepGraph { &self.dep_graph diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 3dbcc4d2e8a..09b85010666 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -535,13 +535,14 @@ impl DepGraph { // value to an existing node. // // For sanity, we still check that the loaded stable hash and the new one match. - if let Some(dep_node_index) = data.dep_node_index_of_opt(&node) { - let _current_fingerprint = - crate::query::incremental_verify_ich(cx, data, result, &node, hash_result); + if let Some(prev_index) = data.previous.node_to_index_opt(&node) + && let Some(dep_node_index) = { data.current.prev_index_to_index.lock()[prev_index] } + { + crate::query::incremental_verify_ich(cx, data, result, prev_index, hash_result); #[cfg(debug_assertions)] if hash_result.is_some() { - data.current.record_edge(dep_node_index, node, _current_fingerprint); + data.current.record_edge(dep_node_index, node, data.prev_fingerprint_of(prev_index)); } return dep_node_index; @@ -626,13 +627,19 @@ impl DepGraphData { /// Returns true if the given node has been marked as green during the /// current compilation session. Used in various assertions - pub fn is_green(&self, dep_node: &DepNode) -> bool { - self.node_color(dep_node).map_or(false, |c| c.is_green()) + #[inline] + pub fn is_index_green(&self, prev_index: SerializedDepNodeIndex) -> bool { + self.colors.get(prev_index).map_or(false, |c| c.is_green()) } #[inline] - pub fn prev_fingerprint_of(&self, dep_node: &DepNode) -> Option { - self.previous.fingerprint_of(dep_node) + pub fn prev_fingerprint_of(&self, prev_index: SerializedDepNodeIndex) -> Fingerprint { + self.previous.fingerprint_by_index(prev_index) + } + + #[inline] + pub fn prev_node_of(&self, prev_index: SerializedDepNodeIndex) -> DepNode { + self.previous.index_to_node(prev_index) } pub fn mark_debug_loaded_from_disk(&self, dep_node: DepNode) { @@ -643,7 +650,7 @@ impl DepGraphData { impl DepGraph { #[inline] pub fn dep_node_exists(&self, dep_node: &DepNode) -> bool { - self.data.as_ref().and_then(|data| data.dep_node_index_of_opt(dep_node)).is_some() + self.data.as_ref().map_or(false, |data| data.dep_node_exists(dep_node)) } /// Checks whether a previous work product exists for `v` and, if diff --git a/compiler/rustc_query_system/src/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs index 40e7131987f..246ec994e57 100644 --- a/compiler/rustc_query_system/src/dep_graph/mod.rs +++ b/compiler/rustc_query_system/src/dep_graph/mod.rs @@ -23,11 +23,15 @@ use std::{fmt, panic}; use self::graph::{print_markframe_trace, MarkFrame}; pub trait DepContext: Copy { + type Implicit<'a>: DepContext; type DepKind: self::DepKind; /// Create a hashing context for hashing new results. fn with_stable_hashing_context(self, f: impl FnOnce(StableHashingContext<'_>) -> R) -> R; + /// Access the implicit context. + fn with_context(f: impl FnOnce(Self::Implicit<'_>) -> R) -> R; + /// Access the DepGraph. fn dep_graph(&self) -> &DepGraph; diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs index 29513df460f..3d19a84915a 100644 --- a/compiler/rustc_query_system/src/dep_graph/serialized.rs +++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs @@ -79,11 +79,6 @@ impl SerializedDepGraph { self.index.get(dep_node).cloned() } - #[inline] - pub fn fingerprint_of(&self, dep_node: &DepNode) -> Option { - self.index.get(dep_node).map(|&node_index| self.fingerprints[node_index]) - } - #[inline] pub fn fingerprint_by_index(&self, dep_node_index: SerializedDepNodeIndex) -> Fingerprint { self.fingerprints[dep_node_index] diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index ba2f859ff0f..e016d948db5 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -7,6 +7,7 @@ use crate::dep_graph::{DepGraphData, HasDepContext}; use crate::ich::StableHashingContext; use crate::query::caches::QueryCache; use crate::query::job::{report_cycle, QueryInfo, QueryJob, QueryJobId, QueryJobInfo}; +use crate::query::SerializedDepNodeIndex; use crate::query::{QueryContext, QueryMap, QuerySideEffects, QueryStackFrame}; use crate::values::Value; use crate::HandleCycleError; @@ -19,7 +20,6 @@ use rustc_data_structures::sharded::Sharded; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::sync::{Lock, LockGuard}; use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed, FatalError}; -use rustc_session::Session; use rustc_span::{Span, DUMMY_SP}; use std::cell::Cell; use std::collections::hash_map::Entry; @@ -537,7 +537,7 @@ where let (prev_dep_node_index, dep_node_index) = dep_graph_data.try_mark_green(qcx, &dep_node)?; - debug_assert!(dep_graph_data.is_green(dep_node)); + debug_assert!(dep_graph_data.is_index_green(prev_dep_node_index)); // First we try to load the result from the on-disk cache. // Some things are never cached on disk. @@ -561,8 +561,7 @@ where dep_graph_data.mark_debug_loaded_from_disk(*dep_node) } - let prev_fingerprint = - dep_graph_data.prev_fingerprint_of(dep_node).unwrap_or(Fingerprint::ZERO); + let prev_fingerprint = dep_graph_data.prev_fingerprint_of(prev_dep_node_index); // If `-Zincremental-verify-ich` is specified, re-hash results from // the cache and make sure that they have the expected fingerprint. // @@ -578,7 +577,7 @@ where *qcx.dep_context(), dep_graph_data, &result, - dep_node, + prev_dep_node_index, query.hash_result(), ); } @@ -623,7 +622,7 @@ where *qcx.dep_context(), dep_graph_data, &result, - dep_node, + prev_dep_node_index, query.hash_result(), ); @@ -636,32 +635,38 @@ pub(crate) fn incremental_verify_ich( tcx: Tcx, dep_graph_data: &DepGraphData, result: &V, - dep_node: &DepNode, + prev_index: SerializedDepNodeIndex, hash_result: Option, &V) -> Fingerprint>, -) -> Fingerprint -where +) where Tcx: DepContext, { - assert!( - dep_graph_data.is_green(dep_node), - "fingerprint for green query instance not loaded from cache: {dep_node:?}", - ); + if !dep_graph_data.is_index_green(prev_index) { + incremental_verify_ich_not_green::(prev_index) + } let new_hash = hash_result.map_or(Fingerprint::ZERO, |f| { tcx.with_stable_hashing_context(|mut hcx| f(&mut hcx, result)) }); - let old_hash = dep_graph_data.prev_fingerprint_of(dep_node); + let old_hash = dep_graph_data.prev_fingerprint_of(prev_index); - if Some(new_hash) != old_hash { - incremental_verify_ich_failed( - tcx.sess(), - DebugArg::from(&dep_node), - DebugArg::from(&result), - ); + if new_hash != old_hash { + incremental_verify_ich_failed::(prev_index, DebugArg::from(&result)); } +} - new_hash +#[cold] +#[inline(never)] +fn incremental_verify_ich_not_green(prev_index: SerializedDepNodeIndex) +where + Tcx: DepContext, +{ + Tcx::with_context(|tcx| { + panic!( + "fingerprint for green query instance not loaded from cache: {:?}", + tcx.dep_graph().data().unwrap().prev_node_of(prev_index) + ) + }) } // This DebugArg business is largely a mirror of std::fmt::ArgumentV1, which is @@ -706,7 +711,11 @@ impl std::fmt::Debug for DebugArg<'_> { // different implementations for LLVM to chew on (and filling up the final // binary, too). #[cold] -fn incremental_verify_ich_failed(sess: &Session, dep_node: DebugArg<'_>, result: DebugArg<'_>) { +#[inline(never)] +fn incremental_verify_ich_failed(prev_index: SerializedDepNodeIndex, result: DebugArg<'_>) +where + Tcx: DepContext, +{ // When we emit an error message and panic, we try to debug-print the `DepNode` // and query result. Unfortunately, this can cause us to run additional queries, // which may result in another fingerprint mismatch while we're in the middle @@ -719,21 +728,25 @@ fn incremental_verify_ich_failed(sess: &Session, dep_node: DebugArg<'_>, result: let old_in_panic = INSIDE_VERIFY_PANIC.with(|in_panic| in_panic.replace(true)); - if old_in_panic { - sess.emit_err(crate::error::Reentrant); - } else { - let run_cmd = if let Some(crate_name) = &sess.opts.crate_name { - format!("`cargo clean -p {crate_name}` or `cargo clean`") + Tcx::with_context(|tcx| { + if old_in_panic { + tcx.sess().emit_err(crate::error::Reentrant); } else { - "`cargo clean`".to_string() - }; + let run_cmd = if let Some(crate_name) = &tcx.sess().opts.crate_name { + format!("`cargo clean -p {crate_name}` or `cargo clean`") + } else { + "`cargo clean`".to_string() + }; - sess.emit_err(crate::error::IncrementCompilation { - run_cmd, - dep_node: format!("{dep_node:?}"), - }); - panic!("Found unstable fingerprints for {dep_node:?}: {result:?}"); - } + let dep_node = tcx.dep_graph().data().unwrap().prev_node_of(prev_index); + + let dep_node = tcx.sess().emit_err(crate::error::IncrementCompilation { + run_cmd, + dep_node: format!("{dep_node:?}"), + }); + panic!("Found unstable fingerprints for {dep_node:?}: {result:?}"); + } + }); INSIDE_VERIFY_PANIC.with(|in_panic| in_panic.set(old_in_panic)); } From dfae9c993dc6ab685bc63c684c1ce66dfa596809 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Mon, 20 Mar 2023 03:49:19 +0100 Subject: [PATCH 135/346] Remove `DebugArg` --- .../rustc_query_system/src/query/plumbing.rs | 48 ++----------------- 1 file changed, 5 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index e016d948db5..8465696d301 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -651,7 +651,7 @@ pub(crate) fn incremental_verify_ich( let old_hash = dep_graph_data.prev_fingerprint_of(prev_index); if new_hash != old_hash { - incremental_verify_ich_failed::(prev_index, DebugArg::from(&result)); + incremental_verify_ich_failed::(prev_index, result); } } @@ -669,50 +669,12 @@ where }) } -// This DebugArg business is largely a mirror of std::fmt::ArgumentV1, which is -// currently not exposed publicly. -// -// The PR which added this attempted to use `&dyn Debug` instead, but that -// showed statistically significant worse compiler performance. It's not -// actually clear what the cause there was -- the code should be cold. If this -// can be replaced with `&dyn Debug` with on perf impact, then it probably -// should be. -extern "C" { - type Opaque; -} - -struct DebugArg<'a> { - value: &'a Opaque, - fmt: fn(&Opaque, &mut std::fmt::Formatter<'_>) -> std::fmt::Result, -} - -impl<'a, T> From<&'a T> for DebugArg<'a> -where - T: std::fmt::Debug, -{ - fn from(value: &'a T) -> DebugArg<'a> { - DebugArg { - value: unsafe { std::mem::transmute(value) }, - fmt: unsafe { - std::mem::transmute(::fmt as fn(_, _) -> std::fmt::Result) - }, - } - } -} - -impl std::fmt::Debug for DebugArg<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - (self.fmt)(self.value, f) - } -} - -// Note that this is marked #[cold] and intentionally takes the equivalent of -// `dyn Debug` for its arguments, as we want to avoid generating a bunch of -// different implementations for LLVM to chew on (and filling up the final -// binary, too). +// Note that this is marked #[cold] and intentionally takes `dyn Debug` for `result`, +// as we want to avoid generating a bunch of different implementations for LLVM to +// chew on (and filling up the final binary, too). #[cold] #[inline(never)] -fn incremental_verify_ich_failed(prev_index: SerializedDepNodeIndex, result: DebugArg<'_>) +fn incremental_verify_ich_failed(prev_index: SerializedDepNodeIndex, result: &dyn Debug) where Tcx: DepContext, { From afe4c16b294312b7aeb920e9a988a3eaca580d3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 25 Mar 2023 03:12:41 +0100 Subject: [PATCH 136/346] Split the `if` to release the lock earlier --- .../rustc_query_system/src/dep_graph/graph.rs | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 09b85010666..80618fd1abe 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -535,17 +535,22 @@ impl DepGraph { // value to an existing node. // // For sanity, we still check that the loaded stable hash and the new one match. - if let Some(prev_index) = data.previous.node_to_index_opt(&node) - && let Some(dep_node_index) = { data.current.prev_index_to_index.lock()[prev_index] } - { - crate::query::incremental_verify_ich(cx, data, result, prev_index, hash_result); + if let Some(prev_index) = data.previous.node_to_index_opt(&node) { + let dep_node_index = data.current.prev_index_to_index.lock()[prev_index]; + if let Some(dep_node_index) = dep_node_index { + crate::query::incremental_verify_ich(cx, data, result, prev_index, hash_result); - #[cfg(debug_assertions)] - if hash_result.is_some() { - data.current.record_edge(dep_node_index, node, data.prev_fingerprint_of(prev_index)); + #[cfg(debug_assertions)] + if hash_result.is_some() { + data.current.record_edge( + dep_node_index, + node, + data.prev_fingerprint_of(prev_index), + ); + } + + return dep_node_index; } - - return dep_node_index; } let mut edges = SmallVec::new(); From 820e3a8d6aec53d8f5f451e43cd1ef87bd29dc0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Sat, 25 Mar 2023 03:13:05 +0100 Subject: [PATCH 137/346] Pass `tcx` directly --- compiler/rustc_middle/src/dep_graph/mod.rs | 6 --- .../rustc_query_system/src/dep_graph/mod.rs | 4 -- .../rustc_query_system/src/query/plumbing.rs | 53 +++++++++---------- 3 files changed, 26 insertions(+), 37 deletions(-) diff --git a/compiler/rustc_middle/src/dep_graph/mod.rs b/compiler/rustc_middle/src/dep_graph/mod.rs index 6ecfda4a1bf..84510fe218c 100644 --- a/compiler/rustc_middle/src/dep_graph/mod.rs +++ b/compiler/rustc_middle/src/dep_graph/mod.rs @@ -71,7 +71,6 @@ impl rustc_query_system::dep_graph::DepKind for DepKind { } impl<'tcx> DepContext for TyCtxt<'tcx> { - type Implicit<'a> = TyCtxt<'a>; type DepKind = DepKind; #[inline] @@ -79,11 +78,6 @@ impl<'tcx> DepContext for TyCtxt<'tcx> { TyCtxt::with_stable_hashing_context(self, f) } - #[inline] - fn with_context(f: impl FnOnce(TyCtxt<'_>) -> R) -> R { - ty::tls::with(|tcx| f(tcx)) - } - #[inline] fn dep_graph(&self) -> &DepGraph { &self.dep_graph diff --git a/compiler/rustc_query_system/src/dep_graph/mod.rs b/compiler/rustc_query_system/src/dep_graph/mod.rs index 246ec994e57..40e7131987f 100644 --- a/compiler/rustc_query_system/src/dep_graph/mod.rs +++ b/compiler/rustc_query_system/src/dep_graph/mod.rs @@ -23,15 +23,11 @@ use std::{fmt, panic}; use self::graph::{print_markframe_trace, MarkFrame}; pub trait DepContext: Copy { - type Implicit<'a>: DepContext; type DepKind: self::DepKind; /// Create a hashing context for hashing new results. fn with_stable_hashing_context(self, f: impl FnOnce(StableHashingContext<'_>) -> R) -> R; - /// Access the implicit context. - fn with_context(f: impl FnOnce(Self::Implicit<'_>) -> R) -> R; - /// Access the DepGraph. fn dep_graph(&self) -> &DepGraph; diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index 8465696d301..186417e862a 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -641,7 +641,7 @@ pub(crate) fn incremental_verify_ich( Tcx: DepContext, { if !dep_graph_data.is_index_green(prev_index) { - incremental_verify_ich_not_green::(prev_index) + incremental_verify_ich_not_green(tcx, prev_index) } let new_hash = hash_result.map_or(Fingerprint::ZERO, |f| { @@ -651,22 +651,20 @@ pub(crate) fn incremental_verify_ich( let old_hash = dep_graph_data.prev_fingerprint_of(prev_index); if new_hash != old_hash { - incremental_verify_ich_failed::(prev_index, result); + incremental_verify_ich_failed(tcx, prev_index, result); } } #[cold] #[inline(never)] -fn incremental_verify_ich_not_green(prev_index: SerializedDepNodeIndex) +fn incremental_verify_ich_not_green(tcx: Tcx, prev_index: SerializedDepNodeIndex) where Tcx: DepContext, { - Tcx::with_context(|tcx| { - panic!( - "fingerprint for green query instance not loaded from cache: {:?}", - tcx.dep_graph().data().unwrap().prev_node_of(prev_index) - ) - }) + panic!( + "fingerprint for green query instance not loaded from cache: {:?}", + tcx.dep_graph().data().unwrap().prev_node_of(prev_index) + ) } // Note that this is marked #[cold] and intentionally takes `dyn Debug` for `result`, @@ -674,8 +672,11 @@ where // chew on (and filling up the final binary, too). #[cold] #[inline(never)] -fn incremental_verify_ich_failed(prev_index: SerializedDepNodeIndex, result: &dyn Debug) -where +fn incremental_verify_ich_failed( + tcx: Tcx, + prev_index: SerializedDepNodeIndex, + result: &dyn Debug, +) where Tcx: DepContext, { // When we emit an error message and panic, we try to debug-print the `DepNode` @@ -690,25 +691,23 @@ where let old_in_panic = INSIDE_VERIFY_PANIC.with(|in_panic| in_panic.replace(true)); - Tcx::with_context(|tcx| { - if old_in_panic { - tcx.sess().emit_err(crate::error::Reentrant); + if old_in_panic { + tcx.sess().emit_err(crate::error::Reentrant); + } else { + let run_cmd = if let Some(crate_name) = &tcx.sess().opts.crate_name { + format!("`cargo clean -p {crate_name}` or `cargo clean`") } else { - let run_cmd = if let Some(crate_name) = &tcx.sess().opts.crate_name { - format!("`cargo clean -p {crate_name}` or `cargo clean`") - } else { - "`cargo clean`".to_string() - }; + "`cargo clean`".to_string() + }; - let dep_node = tcx.dep_graph().data().unwrap().prev_node_of(prev_index); + let dep_node = tcx.dep_graph().data().unwrap().prev_node_of(prev_index); - let dep_node = tcx.sess().emit_err(crate::error::IncrementCompilation { - run_cmd, - dep_node: format!("{dep_node:?}"), - }); - panic!("Found unstable fingerprints for {dep_node:?}: {result:?}"); - } - }); + let dep_node = tcx.sess().emit_err(crate::error::IncrementCompilation { + run_cmd, + dep_node: format!("{dep_node:?}"), + }); + panic!("Found unstable fingerprints for {dep_node:?}: {result:?}"); + } INSIDE_VERIFY_PANIC.with(|in_panic| in_panic.set(old_in_panic)); } From 49798605a0a9186fa6b30d9f219e099287024b8b Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Fri, 24 Mar 2023 20:36:59 -0700 Subject: [PATCH 138/346] Refactor: Separate `LocalRef` variant for not-evaluated-yet operands --- compiler/rustc_codegen_ssa/src/mir/block.rs | 12 ++++++------ compiler/rustc_codegen_ssa/src/mir/debuginfo.rs | 8 ++++---- compiler/rustc_codegen_ssa/src/mir/mod.rs | 11 +++++++---- compiler/rustc_codegen_ssa/src/mir/operand.rs | 4 ++-- compiler/rustc_codegen_ssa/src/mir/place.rs | 3 +++ compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 2 +- compiler/rustc_codegen_ssa/src/mir/statement.rs | 6 +++--- 7 files changed, 26 insertions(+), 20 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs index 5da0e826c56..2d647f5d7f2 100644 --- a/compiler/rustc_codegen_ssa/src/mir/block.rs +++ b/compiler/rustc_codegen_ssa/src/mir/block.rs @@ -397,8 +397,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { PassMode::Cast(cast_ty, _) => { let op = match self.locals[mir::RETURN_PLACE] { - LocalRef::Operand(Some(op)) => op, - LocalRef::Operand(None) => bug!("use of return before def"), + LocalRef::Operand(op) => op, + LocalRef::PendingOperand => bug!("use of return before def"), LocalRef::Place(cg_place) => OperandRef { val: Ref(cg_place.llval, None, cg_place.align), layout: cg_place.layout, @@ -1673,7 +1673,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { match self.locals[index] { LocalRef::Place(dest) => dest, LocalRef::UnsizedPlace(_) => bug!("return type must be sized"), - LocalRef::Operand(None) => { + LocalRef::PendingOperand => { // Handle temporary places, specifically `Operand` ones, as // they don't have `alloca`s. return if fn_ret.is_indirect() { @@ -1694,7 +1694,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ReturnDest::DirectOperand(index) }; } - LocalRef::Operand(Some(_)) => { + LocalRef::Operand(_) => { bug!("place local already assigned to"); } } @@ -1737,7 +1737,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { IndirectOperand(tmp, index) => { let op = bx.load_operand(tmp); tmp.storage_dead(bx); - self.locals[index] = LocalRef::Operand(Some(op)); + self.locals[index] = LocalRef::Operand(op); self.debug_introduce_local(bx, index); } DirectOperand(index) => { @@ -1752,7 +1752,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } else { OperandRef::from_immediate_or_packed_pair(bx, llval, ret_abi.layout) }; - self.locals[index] = LocalRef::Operand(Some(op)); + self.locals[index] = LocalRef::Operand(op); self.debug_introduce_local(bx, index); } } diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs index 6e32c28a42c..d15774696a5 100644 --- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs @@ -312,7 +312,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { LocalRef::Place(place) | LocalRef::UnsizedPlace(place) => { bx.set_var_name(place.llval, name); } - LocalRef::Operand(Some(operand)) => match operand.val { + LocalRef::Operand(operand) => match operand.val { OperandValue::Ref(x, ..) | OperandValue::Immediate(x) => { bx.set_var_name(x, name); } @@ -323,7 +323,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.set_var_name(b, &(name.clone() + ".1")); } }, - LocalRef::Operand(None) => {} + LocalRef::PendingOperand => {} } } @@ -332,9 +332,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } let base = match local_ref { - LocalRef::Operand(None) => return, + LocalRef::PendingOperand => return, - LocalRef::Operand(Some(operand)) => { + LocalRef::Operand(operand) => { // Don't spill operands onto the stack in naked functions. // See: https://github.com/rust-lang/rust/issues/42779 let attrs = bx.tcx().codegen_fn_attrs(self.instance.def_id()); diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs index 5cffca5230a..189549953d9 100644 --- a/compiler/rustc_codegen_ssa/src/mir/mod.rs +++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs @@ -123,7 +123,10 @@ enum LocalRef<'tcx, V> { /// Every time it is initialized, we have to reallocate the place /// and update the fat pointer. That's the reason why it is indirect. UnsizedPlace(PlaceRef<'tcx, V>), - Operand(Option>), + /// The backend [`OperandValue`] has already been generated. + Operand(OperandRef<'tcx, V>), + /// Will be a `Self::Operand` once we get to its definition. + PendingOperand, } impl<'a, 'tcx, V: CodegenObject> LocalRef<'tcx, V> { @@ -135,9 +138,9 @@ impl<'a, 'tcx, V: CodegenObject> LocalRef<'tcx, V> { // Zero-size temporaries aren't always initialized, which // doesn't matter because they don't contain data, but // we need something in the operand. - LocalRef::Operand(Some(OperandRef::new_zst(bx, layout))) + LocalRef::Operand(OperandRef::new_zst(bx, layout)) } else { - LocalRef::Operand(None) + LocalRef::PendingOperand } } } @@ -337,7 +340,7 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( // We don't have to cast or keep the argument in the alloca. // FIXME(eddyb): We should figure out how to use llvm.dbg.value instead // of putting everything in allocas just so we can use llvm.dbg.declare. - let local = |op| LocalRef::Operand(Some(op)); + let local = |op| LocalRef::Operand(op); match arg.mode { PassMode::Ignore => { return local(OperandRef::new_zst(bx, arg.layout)); diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs index 25721f75583..b45e7c834e7 100644 --- a/compiler/rustc_codegen_ssa/src/mir/operand.rs +++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs @@ -370,7 +370,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { debug!("maybe_codegen_consume_direct(place_ref={:?})", place_ref); match self.locals[place_ref.local] { - LocalRef::Operand(Some(mut o)) => { + LocalRef::Operand(mut o) => { // Moves out of scalar and scalar pair fields are trivial. for elem in place_ref.projection.iter() { match elem { @@ -395,7 +395,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { Some(o) } - LocalRef::Operand(None) => { + LocalRef::PendingOperand => { bug!("use of {:?} before def", place_ref); } LocalRef::Place(..) | LocalRef::UnsizedPlace(..) => { diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index f6523a448e3..1633cfef19d 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -558,6 +558,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bug!("using operand local {:?} as place", place_ref); } } + LocalRef::PendingOperand => { + bug!("using still-pending operand local {:?} as place", place_ref); + } }; for elem in place_ref.projection[base..].iter() { cg_base = match *elem { diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 14f57b63e97..fadf8b73231 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -545,7 +545,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { // ZST are passed as operands and require special handling // because codegen_place() panics if Local is operand. if let Some(index) = place.as_local() { - if let LocalRef::Operand(Some(op)) = self.locals[index] { + if let LocalRef::Operand(op) = self.locals[index] { if let ty::Array(_, n) = op.layout.ty.kind() { let n = n.eval_target_usize(bx.cx().tcx(), ty::ParamEnv::reveal_all()); return bx.cx().const_usize(n); diff --git a/compiler/rustc_codegen_ssa/src/mir/statement.rs b/compiler/rustc_codegen_ssa/src/mir/statement.rs index 41f585f7fcc..3fd7397ad38 100644 --- a/compiler/rustc_codegen_ssa/src/mir/statement.rs +++ b/compiler/rustc_codegen_ssa/src/mir/statement.rs @@ -18,12 +18,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { LocalRef::UnsizedPlace(cg_indirect_dest) => { self.codegen_rvalue_unsized(bx, cg_indirect_dest, rvalue) } - LocalRef::Operand(None) => { + LocalRef::PendingOperand => { let operand = self.codegen_rvalue_operand(bx, rvalue); - self.locals[index] = LocalRef::Operand(Some(operand)); + self.locals[index] = LocalRef::Operand(operand); self.debug_introduce_local(bx, index); } - LocalRef::Operand(Some(op)) => { + LocalRef::Operand(op) => { if !op.layout.is_zst() { span_bug!( statement.source_info.span, From 5e49f099a9a6a4bf9776315e19b58b09fb159f87 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 12 Mar 2023 10:10:12 +0000 Subject: [PATCH 139/346] Use an IndexVec to debug fingerprints. --- compiler/rustc_query_system/src/dep_graph/graph.rs | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs index 3dbcc4d2e8a..6c73135eb6a 100644 --- a/compiler/rustc_query_system/src/dep_graph/graph.rs +++ b/compiler/rustc_query_system/src/dep_graph/graph.rs @@ -1053,7 +1053,7 @@ pub(super) struct CurrentDepGraph { /// This is used to verify that fingerprints do not change between the creation of a node /// and its recomputation. #[cfg(debug_assertions)] - fingerprints: Lock, Fingerprint>>, + fingerprints: Lock>>, /// Used to trap when a specific edge is added to the graph. /// This is used for debug purposes and is only active with `debug_assertions`. @@ -1139,7 +1139,7 @@ impl CurrentDepGraph { #[cfg(debug_assertions)] forbidden_edge, #[cfg(debug_assertions)] - fingerprints: Lock::new(Default::default()), + fingerprints: Lock::new(IndexVec::from_elem_n(None, new_node_count_estimate)), total_read_count: AtomicU64::new(0), total_duplicate_read_count: AtomicU64::new(0), node_intern_event_id, @@ -1151,14 +1151,8 @@ impl CurrentDepGraph { if let Some(forbidden_edge) = &self.forbidden_edge { forbidden_edge.index_to_node.lock().insert(dep_node_index, key); } - match self.fingerprints.lock().entry(key) { - Entry::Vacant(v) => { - v.insert(fingerprint); - } - Entry::Occupied(o) => { - assert_eq!(*o.get(), fingerprint, "Unstable fingerprints for {:?}", key); - } - } + let previous = *self.fingerprints.lock().get_or_insert_with(dep_node_index, || fingerprint); + assert_eq!(previous, fingerprint, "Unstable fingerprints for {:?}", key); } /// Writes the node to the current dep-graph and allocates a `DepNodeIndex` for it. From 1491c6f3117749cbefd6d0dc9c425a64ecff4f8d Mon Sep 17 00:00:00 2001 From: Peter Kehl Date: Sat, 25 Mar 2023 06:19:52 -0700 Subject: [PATCH 140/346] Rustdoc Book refer to rustdoc::missing_doc_code_examples. Fixes #109592. --- src/doc/rustdoc/src/write-documentation/what-to-include.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustdoc/src/write-documentation/what-to-include.md b/src/doc/rustdoc/src/write-documentation/what-to-include.md index e1e09aa4a8a..cf1e6a8d3ca 100644 --- a/src/doc/rustdoc/src/write-documentation/what-to-include.md +++ b/src/doc/rustdoc/src/write-documentation/what-to-include.md @@ -39,7 +39,7 @@ warning: 1 warning emitted As a library author, adding the lint `#![deny(missing_docs)]` is a great way to ensure the project does not drift away from being documented well, and `#![warn(missing_docs)]` is a good way to move towards comprehensive -documentation. In addition to docs, `#![deny(missing_doc_code_examples)]` +documentation. In addition to docs, `#![deny(rustdoc::missing_doc_code_examples)]` ensures each function contains a usage example. In our example above, the warning is resolved by adding crate level documentation. From 16bb7196a8d354feebcee986a73dd465d1caa6d8 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 25 Mar 2023 15:28:18 +0100 Subject: [PATCH 141/346] Improve "Auto-hide trait implementation documentation" GUI test --- .../auto-hide-trait-implementations.goml | 13 ----- ...tting-auto-hide-trait-implementations.goml | 47 +++++++++++++++++++ 2 files changed, 47 insertions(+), 13 deletions(-) delete mode 100644 tests/rustdoc-gui/auto-hide-trait-implementations.goml create mode 100644 tests/rustdoc-gui/setting-auto-hide-trait-implementations.goml diff --git a/tests/rustdoc-gui/auto-hide-trait-implementations.goml b/tests/rustdoc-gui/auto-hide-trait-implementations.goml deleted file mode 100644 index 0a619c3524a..00000000000 --- a/tests/rustdoc-gui/auto-hide-trait-implementations.goml +++ /dev/null @@ -1,13 +0,0 @@ -// Checks that the setting "auto hide trait implementations" is working as expected. -goto: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html" - -// By default, the trait implementations are not collapsed. -assert-attribute: ("#trait-implementations-list > details", {"open": ""}, ALL) - -// We now set the setting to auto hide all trait implementations. -local-storage: {"rustdoc-auto-hide-trait-implementations": "true" } -// We reload to ensure the trait implementations are collapsed as expected. -reload: - -// We now check that all matching elements don't have the open attributes. -assert-attribute-false: ("#trait-implementations-list > details", {"open": ""}, ALL) diff --git a/tests/rustdoc-gui/setting-auto-hide-trait-implementations.goml b/tests/rustdoc-gui/setting-auto-hide-trait-implementations.goml new file mode 100644 index 00000000000..7355dddd39d --- /dev/null +++ b/tests/rustdoc-gui/setting-auto-hide-trait-implementations.goml @@ -0,0 +1,47 @@ +// Checks that the setting "auto hide trait implementations" is working as expected. + +define-function: ( + "check-setting", + (storage_value, setting_attribute_value, toggle_attribute_value), + block { + assert-local-storage: {"rustdoc-auto-hide-trait-implementations": |storage_value|} + click: "#settings-menu" + wait-for: "#settings" + assert-property: ("#auto-hide-trait-implementations", {"checked": |setting_attribute_value|}) + assert-attribute: ("#trait-implementations-list > details", {"open": |toggle_attribute_value|}, ALL) + } +) + +goto: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html" + +// By default, the trait implementations are not collapsed. +call-function: ("check-setting", { + "storage_value": null, + "setting_attribute_value": "false", + "toggle_attribute_value": "", +}) + +// Now we change its value. +click: "#auto-hide-trait-implementations" +assert-local-storage: {"rustdoc-auto-hide-trait-implementations": "true"} + +// We check that the changes were applied as expected. +reload: + +call-function: ("check-setting", { + "storage_value": "true", + "setting_attribute_value": "true", + "toggle_attribute_value": null, +}) + +// And now we re-disable the setting. +click: "#auto-hide-trait-implementations" +assert-local-storage: {"rustdoc-auto-hide-trait-implementations": "false"} + +// And we check everything is back the way it was before. +reload: +call-function: ("check-setting", { + "storage_value": "false", + "setting_attribute_value": "false", + "toggle_attribute_value": "", +}) From 9fe3a39e3467da1c8a291e7c16f498e3aacfd353 Mon Sep 17 00:00:00 2001 From: Veera Date: Sat, 25 Mar 2023 11:41:00 -0400 Subject: [PATCH 142/346] Improve documentation for str::replace() and str::replacen() Currently, to know what the function will return when the pattern doesn't match, the docs require the reader to understand the implementation detail and mentally evaluate or run the example code. It is not immediately clear. This PR makes it more explicit so the reader can quickly find the information. --- library/alloc/src/str.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs index afbe5cfaf8e..b87ef59f64a 100644 --- a/library/alloc/src/str.rs +++ b/library/alloc/src/str.rs @@ -256,7 +256,7 @@ impl str { /// assert_eq!("than an old", s.replace("is", "an")); /// ``` /// - /// When the pattern doesn't match: + /// When the pattern doesn't match, it returns this string slice as [`String`]: /// /// ``` /// let s = "this is old"; @@ -297,7 +297,7 @@ impl str { /// assert_eq!("foo foo new23 foo", s.replacen(char::is_numeric, "new", 1)); /// ``` /// - /// When the pattern doesn't match: + /// When the pattern doesn't match, it returns this string slice as [`String`]: /// /// ``` /// let s = "this is old"; From 88e78aba820c399fa1facc97604ef10497d3c4ca Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Sat, 25 Mar 2023 13:58:49 -0400 Subject: [PATCH 143/346] Explain how we get to skip checking for cleanup blocks in the visitor --- compiler/rustc_mir_transform/src/simplify.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs index c8474a455b5..5bdb8ab6bfc 100644 --- a/compiler/rustc_mir_transform/src/simplify.rs +++ b/compiler/rustc_mir_transform/src/simplify.rs @@ -273,6 +273,8 @@ pub fn remove_duplicate_unreachable_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut B fn visit_terminator(&mut self, terminator: &mut Terminator<'tcx>, location: Location) { for target in terminator.successors_mut() { + // We don't have to check whether `target` is a cleanup block, because have + // entirely excluded cleanup blocks in building the set of duplicates. if self.duplicates.contains(target) { *target = self.duplicates[0]; } From 08f3deb3d5a2164d8a601d37c87f2453b2f09eed Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Sat, 25 Mar 2023 22:27:24 +0100 Subject: [PATCH 144/346] fix type suggestions in match arms --- .../rustc_infer/src/infer/error_reporting/mod.rs | 3 ++- tests/ui/inference/char-as-str-single.fixed | 9 +++++++++ tests/ui/inference/char-as-str-single.rs | 9 +++++++++ tests/ui/inference/char-as-str-single.stderr | 15 ++++++++++++++- 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index fd16363a1db..75c3d9f641d 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -1942,7 +1942,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { escaped } let mut err = struct_span_err!(self.tcx.sess, span, E0308, "{}", failure_str); - if let Some((expected, found)) = trace.values.ty() { + let values = self.resolve_vars_if_possible(trace.values); + if let Some((expected, found)) = values.ty() { match (expected.kind(), found.kind()) { (ty::Tuple(_), ty::Tuple(_)) => {} // If a tuple of length one was expected and the found expression has diff --git a/tests/ui/inference/char-as-str-single.fixed b/tests/ui/inference/char-as-str-single.fixed index bab1854dc51..1621a279f03 100644 --- a/tests/ui/inference/char-as-str-single.fixed +++ b/tests/ui/inference/char-as-str-single.fixed @@ -10,3 +10,12 @@ fn main() { let _: char = '人'; //~ ERROR mismatched types let _: char = '\''; //~ ERROR mismatched types } + +// regression test for https://github.com/rust-lang/rust/issues/109586 +#[allow(dead_code)] +fn convert_c_to_str(c: char) { + match c { + 'A' => {} //~ ERROR mismatched types + _ => {} + } +} diff --git a/tests/ui/inference/char-as-str-single.rs b/tests/ui/inference/char-as-str-single.rs index 736920643b2..2903142f159 100644 --- a/tests/ui/inference/char-as-str-single.rs +++ b/tests/ui/inference/char-as-str-single.rs @@ -10,3 +10,12 @@ fn main() { let _: char = "人"; //~ ERROR mismatched types let _: char = "'"; //~ ERROR mismatched types } + +// regression test for https://github.com/rust-lang/rust/issues/109586 +#[allow(dead_code)] +fn convert_c_to_str(c: char) { + match c { + "A" => {} //~ ERROR mismatched types + _ => {} + } +} diff --git a/tests/ui/inference/char-as-str-single.stderr b/tests/ui/inference/char-as-str-single.stderr index 3375ec6ac32..9149efe3240 100644 --- a/tests/ui/inference/char-as-str-single.stderr +++ b/tests/ui/inference/char-as-str-single.stderr @@ -37,6 +37,19 @@ help: if you meant to write a `char` literal, use single quotes LL | let _: char = '\''; | ~~~~ -error: aborting due to 3 previous errors +error[E0308]: mismatched types + --> $DIR/char-as-str-single.rs:18:9 + | +LL | match c { + | - this expression has type `char` +LL | "A" => {} + | ^^^ expected `char`, found `&str` + | +help: if you meant to write a `char` literal, use single quotes + | +LL | 'A' => {} + | ~~~ + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0308`. From b93275198430e846715d0861111a55b672ca47e4 Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Sat, 25 Mar 2023 16:47:56 -0400 Subject: [PATCH 145/346] Ignore the unwrap_unchecked test on wasm32-unknown-unknown --- tests/mir-opt/inline/unwrap_unchecked.rs | 1 + .../inline/unwrap_unchecked.unwrap_unchecked.Inline.diff | 4 ++-- .../unwrap_unchecked.unwrap_unchecked.PreCodegen.after.mir | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/mir-opt/inline/unwrap_unchecked.rs b/tests/mir-opt/inline/unwrap_unchecked.rs index c3581093f66..5856f147941 100644 --- a/tests/mir-opt/inline/unwrap_unchecked.rs +++ b/tests/mir-opt/inline/unwrap_unchecked.rs @@ -1,5 +1,6 @@ #![crate_type = "lib"] +// ignore-wasm32-bare compiled with panic=abort by default // ignore-debug: the debug assertions prevent the inlining we are testing for // compile-flags: -Zmir-opt-level=2 -Zinline-mir diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.diff b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.diff index 7f73306a825..543ddcfc44c 100644 --- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.diff +++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.diff @@ -5,7 +5,7 @@ debug slf => _1; // in scope 0 at $DIR/unwrap_unchecked.rs:+0:35: +0:38 let mut _0: T; // return place in scope 0 at $DIR/unwrap_unchecked.rs:+0:54: +0:55 let mut _2: std::option::Option; // in scope 0 at $DIR/unwrap_unchecked.rs:+1:5: +1:8 -+ scope 1 (inlined #[track_caller] Option::::unwrap_unchecked) { // at $DIR/unwrap_unchecked.rs:9:9: 9:27 ++ scope 1 (inlined #[track_caller] Option::::unwrap_unchecked) { // at $DIR/unwrap_unchecked.rs:10:9: 10:27 + debug self => _2; // in scope 1 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _3: &std::option::Option; // in scope 1 at $SRC_DIR/core/src/option.rs:LL:COL + let mut _4: isize; // in scope 1 at $SRC_DIR/core/src/option.rs:LL:COL @@ -30,7 +30,7 @@ _2 = move _1; // scope 0 at $DIR/unwrap_unchecked.rs:+1:5: +1:8 - _0 = Option::::unwrap_unchecked(move _2) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/unwrap_unchecked.rs:+1:5: +1:27 - // mir::Constant -- // + span: $DIR/unwrap_unchecked.rs:9:9: 9:25 +- // + span: $DIR/unwrap_unchecked.rs:10:9: 10:25 - // + literal: Const { ty: unsafe fn(Option) -> T {Option::::unwrap_unchecked}, val: Value() } + StorageLive(_3); // scope 0 at $DIR/unwrap_unchecked.rs:+1:9: +1:27 + _4 = discriminant(_2); // scope 1 at $SRC_DIR/core/src/option.rs:LL:COL diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.mir b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.mir index 33cd3785336..c5e2469fc27 100644 --- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.mir +++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.mir @@ -3,7 +3,7 @@ fn unwrap_unchecked(_1: Option) -> T { debug slf => _1; // in scope 0 at $DIR/unwrap_unchecked.rs:+0:35: +0:38 let mut _0: T; // return place in scope 0 at $DIR/unwrap_unchecked.rs:+0:54: +0:55 - scope 1 (inlined #[track_caller] Option::::unwrap_unchecked) { // at $DIR/unwrap_unchecked.rs:9:9: 9:27 + scope 1 (inlined #[track_caller] Option::::unwrap_unchecked) { // at $DIR/unwrap_unchecked.rs:10:9: 10:27 debug self => _1; // in scope 1 at $SRC_DIR/core/src/option.rs:LL:COL let mut _2: &std::option::Option; // in scope 1 at $SRC_DIR/core/src/option.rs:LL:COL let mut _3: isize; // in scope 1 at $SRC_DIR/core/src/option.rs:LL:COL From 20679b11662908315bc2600b5103f60103a4b0ae Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 25 Mar 2023 23:34:49 +0000 Subject: [PATCH 146/346] Still-further-specializable projections are ambiguous --- .../src/solve/project_goals.rs | 2 +- .../specialization-unconstrained.rs | 22 ++++++++++++++++ .../specialization-unconstrained.stderr | 25 +++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 tests/ui/traits/new-solver/specialization-unconstrained.rs create mode 100644 tests/ui/traits/new-solver/specialization-unconstrained.stderr diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index 525b3105538..14c5b83c6ca 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -174,7 +174,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { goal.predicate.def_id(), impl_def_id )? else { - return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes); + return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS); }; if !assoc_def.item.defaultness(tcx).has_value() { diff --git a/tests/ui/traits/new-solver/specialization-unconstrained.rs b/tests/ui/traits/new-solver/specialization-unconstrained.rs new file mode 100644 index 00000000000..02150689ee5 --- /dev/null +++ b/tests/ui/traits/new-solver/specialization-unconstrained.rs @@ -0,0 +1,22 @@ +// compile-flags: -Ztrait-solver=next + +#![feature(specialization)] +//~^ WARN the feature `specialization` is incomplete + +// Do not treat the RHS of a projection-goal as an unconstrained `Certainty::Yes` response +// if the impl is still further specializable. + +trait Default { + type Id; +} + +impl Default for T { + default type Id = T; +} + +fn test, U>() {} + +fn main() { + test::(); + //~^ ERROR cannot satisfy `::Id == ()` +} diff --git a/tests/ui/traits/new-solver/specialization-unconstrained.stderr b/tests/ui/traits/new-solver/specialization-unconstrained.stderr new file mode 100644 index 00000000000..910925cbaeb --- /dev/null +++ b/tests/ui/traits/new-solver/specialization-unconstrained.stderr @@ -0,0 +1,25 @@ +warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/specialization-unconstrained.rs:3:12 + | +LL | #![feature(specialization)] + | ^^^^^^^^^^^^^^ + | + = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default + +error[E0284]: type annotations needed: cannot satisfy `::Id == ()` + --> $DIR/specialization-unconstrained.rs:20:5 + | +LL | test::(); + | ^^^^^^^^^^^^^^^ cannot satisfy `::Id == ()` + | +note: required by a bound in `test` + --> $DIR/specialization-unconstrained.rs:17:20 + | +LL | fn test, U>() {} + | ^^^^^^ required by this bound in `test` + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0284`. From 323551abb1e4a34a9e9e81ebcc49e5224af8a5cb Mon Sep 17 00:00:00 2001 From: Evie M <14899090+eievui5@users.noreply.github.com> Date: Sat, 25 Mar 2023 19:57:46 -0400 Subject: [PATCH 147/346] Correct typo (`back_box` -> `black_box`) --- library/core/src/hint.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs index ee13dae60b1..a205565773a 100644 --- a/library/core/src/hint.rs +++ b/library/core/src/hint.rs @@ -228,7 +228,7 @@ pub fn spin_loop() { /// This _immediately_ precludes any direct use of this function for cryptographic or security /// purposes. /// -/// While not suitable in those mission-critical cases, `back_box`'s functionality can generally be +/// While not suitable in those mission-critical cases, `black_box`'s functionality can generally be /// relied upon for benchmarking, and should be used there. It will try to ensure that the /// compiler doesn't optimize away part of the intended test code based on context. For /// example: From 3310f72db9205d23f7900d85055c5cd0eec17814 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 26 Mar 2023 00:02:24 +0000 Subject: [PATCH 148/346] transmute test --- compiler/rustc_middle/src/ty/mod.rs | 4 +-- .../new-solver/specialization-transmute.rs | 30 ++++++++++++++++++ .../specialization-transmute.stderr | 31 +++++++++++++++++++ 3 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 tests/ui/traits/new-solver/specialization-transmute.rs create mode 100644 tests/ui/traits/new-solver/specialization-transmute.stderr diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index e3cd5cca785..c6a56df5a5e 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -653,8 +653,8 @@ pub enum AliasRelationDirection { impl std::fmt::Display for AliasRelationDirection { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - AliasRelationDirection::Equate => write!(f, " == "), - AliasRelationDirection::Subtype => write!(f, " <: "), + AliasRelationDirection::Equate => write!(f, "=="), + AliasRelationDirection::Subtype => write!(f, "<:"), } } } diff --git a/tests/ui/traits/new-solver/specialization-transmute.rs b/tests/ui/traits/new-solver/specialization-transmute.rs new file mode 100644 index 00000000000..a54701df4ef --- /dev/null +++ b/tests/ui/traits/new-solver/specialization-transmute.rs @@ -0,0 +1,30 @@ +// compile-flags: -Ztrait-solver=next + +#![feature(specialization)] +//~^ WARN the feature `specialization` is incomplete + +trait Default { + type Id; + + fn intu(&self) -> &Self::Id; +} + +impl Default for T { + default type Id = T; + + fn intu(&self) -> &Self::Id { + self + //~^ ERROR cannot satisfy `T <: ::Id` + } +} + +fn transmute, U: Copy>(t: T) -> U { + *t.intu() +} + +use std::num::NonZeroU8; +fn main() { + let s = transmute::>(0); + //~^ ERROR cannot satisfy `::Id == Option + assert_eq!(s, None); +} diff --git a/tests/ui/traits/new-solver/specialization-transmute.stderr b/tests/ui/traits/new-solver/specialization-transmute.stderr new file mode 100644 index 00000000000..e67c56afc0d --- /dev/null +++ b/tests/ui/traits/new-solver/specialization-transmute.stderr @@ -0,0 +1,31 @@ +warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/specialization-transmute.rs:3:12 + | +LL | #![feature(specialization)] + | ^^^^^^^^^^^^^^ + | + = note: see issue #31844 for more information + = help: consider using `min_specialization` instead, which is more stable and complete + = note: `#[warn(incomplete_features)]` on by default + +error[E0284]: type annotations needed: cannot satisfy `T <: ::Id` + --> $DIR/specialization-transmute.rs:16:9 + | +LL | self + | ^^^^ cannot satisfy `T <: ::Id` + +error[E0284]: type annotations needed: cannot satisfy `::Id == Option` + --> $DIR/specialization-transmute.rs:27:13 + | +LL | let s = transmute::>(0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `::Id == Option` + | +note: required by a bound in `transmute` + --> $DIR/specialization-transmute.rs:21:25 + | +LL | fn transmute, U: Copy>(t: T) -> U { + | ^^^^^^ required by this bound in `transmute` + +error: aborting due to 2 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0284`. From 0439d131768081174fe4ed53a6f09d41a9e5629f Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 25 Mar 2023 18:43:03 -0700 Subject: [PATCH 149/346] Refactor: `VariantIdx::from_u32(0)` -> `FIRST_VARIANT` Since structs are always `VariantIdx(0)`, there's a bunch of files where the only reason they had `VariantIdx` or `vec::Idx` imported at all was to get the first variant. So this uses a constant for that, and adds some doc-comments to `VariantIdx` while I'm there, since it doesn't have any today. --- compiler/rustc_abi/src/layout.rs | 18 +++++++++--------- compiler/rustc_abi/src/lib.rs | 17 +++++++++++++++-- compiler/rustc_borrowck/src/type_check/mod.rs | 6 +++--- compiler/rustc_codegen_cranelift/src/base.rs | 2 +- compiler/rustc_codegen_cranelift/src/lib.rs | 2 +- compiler/rustc_codegen_cranelift/src/unsize.rs | 2 +- compiler/rustc_codegen_ssa/src/base.rs | 5 ++--- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 4 ++-- .../src/const_eval/valtrees.rs | 4 ++-- .../rustc_const_eval/src/interpret/place.rs | 4 ++-- .../rustc_const_eval/src/transform/validate.rs | 4 ++-- .../rustc_hir_typeck/src/expr_use_visitor.rs | 5 ++--- .../rustc_hir_typeck/src/mem_categorization.rs | 9 ++++----- compiler/rustc_hir_typeck/src/upvar.rs | 5 ++--- compiler/rustc_lint/src/builtin.rs | 5 ++--- compiler/rustc_middle/src/ty/adt.rs | 10 +++++----- compiler/rustc_middle/src/ty/sty.rs | 5 ++--- .../rustc_mir_build/src/build/expr/as_place.rs | 6 ++---- compiler/rustc_mir_build/src/thir/cx/expr.rs | 8 ++++---- .../src/thir/pattern/deconstruct_pat.rs | 4 ++-- .../rustc_mir_dataflow/src/elaborate_drops.rs | 6 +++--- compiler/rustc_mir_transform/src/inline.rs | 4 ++-- compiler/rustc_mir_transform/src/shim.rs | 9 +++------ compiler/rustc_ty_utils/src/consts.rs | 4 ++-- compiler/rustc_ty_utils/src/layout.rs | 10 +++++----- 25 files changed, 80 insertions(+), 78 deletions(-) diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 54858b52008..343f27326ad 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -43,7 +43,7 @@ pub trait LayoutCalculator { .max_by_key(|niche| niche.available(dl)); LayoutS { - variants: Variants::Single { index: VariantIdx::new(0) }, + variants: Variants::Single { index: FIRST_VARIANT }, fields: FieldsShape::Arbitrary { offsets: vec![Size::ZERO, b_offset], memory_index: vec![0, 1], @@ -264,7 +264,7 @@ pub trait LayoutCalculator { abi = Abi::Uninhabited; } Some(LayoutS { - variants: Variants::Single { index: VariantIdx::new(0) }, + variants: Variants::Single { index: FIRST_VARIANT }, fields: FieldsShape::Arbitrary { offsets, memory_index }, abi, largest_niche, @@ -277,7 +277,7 @@ pub trait LayoutCalculator { let dl = self.current_data_layout(); let dl = dl.borrow(); LayoutS { - variants: Variants::Single { index: VariantIdx::new(0) }, + variants: Variants::Single { index: FIRST_VARIANT }, fields: FieldsShape::Primitive, abi: Abi::Uninhabited, largest_niche: None, @@ -331,7 +331,7 @@ pub trait LayoutCalculator { } // If it's a struct, still compute a layout so that we can still compute the // field offsets. - None => VariantIdx::new(0), + None => FIRST_VARIANT, }; let is_struct = !is_enum || @@ -467,7 +467,7 @@ pub trait LayoutCalculator { .max_by_key(|(_i, layout)| layout.size.bytes()) .map(|(i, _layout)| i)?; - let all_indices = (0..=variants.len() - 1).map(VariantIdx::new); + let all_indices = variants.indices(); let needs_disc = |index: VariantIdx| index != largest_variant_index && !absent(&variants[index]); let niche_variants = all_indices.clone().find(|v| needs_disc(*v)).unwrap().index() @@ -896,8 +896,8 @@ pub trait LayoutCalculator { let optimize = !repr.inhibit_union_abi_opt(); let mut size = Size::ZERO; let mut abi = Abi::Aggregate { sized: true }; - let index = VariantIdx::new(0); - for field in &variants[index] { + let only_variant = &variants[FIRST_VARIANT]; + for field in only_variant { assert!(field.0.is_sized()); align = align.max(field.align()); @@ -930,8 +930,8 @@ pub trait LayoutCalculator { } Some(LayoutS { - variants: Variants::Single { index }, - fields: FieldsShape::Union(NonZeroUsize::new(variants[index].len())?), + variants: Variants::Single { index: FIRST_VARIANT }, + fields: FieldsShape::Union(NonZeroUsize::new(only_variant.len())?), abi, largest_niche: None, align, diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 39574ca558f..6740001c38b 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1380,8 +1380,21 @@ impl Niche { } rustc_index::newtype_index! { + /// The *source-order* index of a variant in a type. + /// + /// For enums, these are always `0..variant_count`, regardless of any + /// custom discriminants that may have been defined, and including any + /// variants that may end up uninhabited due to field types. (Some of the + /// variants may not be present in a monomorphized ABI [`Variants`], but + /// those skipped variants are always counted when determining the *index*.) + /// + /// `struct`s, `tuples`, and `unions`s are considered to have a single variant + /// with variant index zero, aka [`FIRST_VARIANT`]. #[derive(HashStable_Generic)] - pub struct VariantIdx {} + pub struct VariantIdx { + /// Equivalent to `VariantIdx(0)`. + const FIRST_VARIANT = 0; + } } #[derive(PartialEq, Eq, Hash, Clone)] @@ -1422,7 +1435,7 @@ impl LayoutS { let size = scalar.size(cx); let align = scalar.align(cx); LayoutS { - variants: Variants::Single { index: VariantIdx::new(0) }, + variants: Variants::Single { index: FIRST_VARIANT }, fields: FieldsShape::Primitive, abi: Abi::Scalar(scalar), largest_niche, diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index c2a426bea09..4b27d240985 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -14,7 +14,7 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_hir::lang_items::LangItem; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::vec::IndexVec; use rustc_infer::infer::canonical::QueryRegionConstraints; use rustc_infer::infer::outlives::env::RegionBoundPairs; use rustc_infer::infer::region_constraints::RegionConstraintData; @@ -36,7 +36,7 @@ use rustc_middle::ty::{ }; use rustc_span::def_id::CRATE_DEF_ID; use rustc_span::{Span, DUMMY_SP}; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::FIRST_VARIANT; use rustc_trait_selection::traits::query::type_op::custom::scrape_region_constraints; use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp; use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput}; @@ -812,7 +812,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { }, PlaceTy { ty, variant_index: None } => match *ty.kind() { ty::Adt(adt_def, substs) if !adt_def.is_enum() => { - (adt_def.variant(VariantIdx::new(0)), substs) + (adt_def.variant(FIRST_VARIANT), substs) } ty::Closure(_, substs) => { return match substs diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 2107ae147e9..1825fb8cb22 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -785,7 +785,7 @@ fn codegen_stmt<'tcx>( let variant_dest = lval.downcast_variant(fx, variant_index); (variant_index, variant_dest, active_field_index) } - _ => (VariantIdx::from_u32(0), lval, None), + _ => (FIRST_VARIANT, lval, None), }; if active_field_index.is_some() { assert_eq!(operands.len(), 1); diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index bed79859f51..1bd03403f24 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -86,7 +86,7 @@ mod prelude { self, FloatTy, Instance, InstanceDef, IntTy, ParamEnv, Ty, TyCtxt, TypeAndMut, TypeFoldable, TypeVisitableExt, UintTy, }; - pub(crate) use rustc_target::abi::{Abi, Scalar, Size, VariantIdx}; + pub(crate) use rustc_target::abi::{Abi, Scalar, Size, VariantIdx, FIRST_VARIANT}; pub(crate) use rustc_data_structures::fx::FxHashMap; diff --git a/compiler/rustc_codegen_cranelift/src/unsize.rs b/compiler/rustc_codegen_cranelift/src/unsize.rs index ecf187a0b0f..93eefd92342 100644 --- a/compiler/rustc_codegen_cranelift/src/unsize.rs +++ b/compiler/rustc_codegen_cranelift/src/unsize.rs @@ -146,7 +146,7 @@ pub(crate) fn coerce_unsized_into<'tcx>( (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => { assert_eq!(def_a, def_b); - for i in 0..def_a.variant(VariantIdx::new(0)).fields.len() { + for i in 0..def_a.variant(FIRST_VARIANT).fields.len() { let src_f = src.value_field(fx, mir::Field::new(i)); let dst_f = dst.place_field(fx, mir::Field::new(i)); diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index c3c8649dbff..6c4ca8f7fb1 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -24,7 +24,6 @@ use rustc_data_structures::sync::ParallelIterator; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::lang_items::LangItem; -use rustc_index::vec::Idx; use rustc_metadata::EncodedMetadata; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs; use rustc_middle::middle::exported_symbols; @@ -40,7 +39,7 @@ use rustc_session::Session; use rustc_span::symbol::sym; use rustc_span::Symbol; use rustc_span::{DebuggerVisualizerFile, DebuggerVisualizerType}; -use rustc_target::abi::{Align, VariantIdx}; +use rustc_target::abi::{Align, FIRST_VARIANT}; use std::collections::BTreeSet; use std::time::{Duration, Instant}; @@ -307,7 +306,7 @@ pub fn coerce_unsized_into<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => { assert_eq!(def_a, def_b); - for i in 0..def_a.variant(VariantIdx::new(0)).fields.len() { + for i in 0..def_a.variant(FIRST_VARIANT).fields.len() { let src_f = src.project_field(bx, i); let dst_f = dst.project_field(bx, i); diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 14f57b63e97..4bc4fdab59e 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -13,7 +13,7 @@ use rustc_middle::ty::cast::{CastTy, IntTy}; use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf}; use rustc_middle::ty::{self, adjustment::PointerCast, Instance, Ty, TyCtxt}; use rustc_span::source_map::{Span, DUMMY_SP}; -use rustc_target::abi::{self, VariantIdx}; +use rustc_target::abi::{self, FIRST_VARIANT}; impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { #[instrument(level = "trace", skip(self, bx))] @@ -118,7 +118,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let variant_dest = dest.project_downcast(bx, variant_index); (variant_index, variant_dest, active_field_index) } - _ => (VariantIdx::from_u32(0), dest, None), + _ => (FIRST_VARIANT, dest, None), }; if active_field_index.is_some() { assert_eq!(operands.len(), 1); diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index a73f778d4db..8e4454d7cec 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -8,7 +8,7 @@ use crate::interpret::{ use crate::interpret::{MPlaceTy, Value}; use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt}; use rustc_span::source_map::DUMMY_SP; -use rustc_target::abi::{Align, VariantIdx}; +use rustc_target::abi::{Align, VariantIdx, FIRST_VARIANT}; #[instrument(skip(ecx), level = "debug")] fn branches<'tcx>( @@ -412,7 +412,7 @@ fn valtree_into_mplace<'tcx>( let inner_ty = match ty.kind() { ty::Adt(def, substs) => { - def.variant(VariantIdx::from_u32(0)).fields[i].ty(tcx, substs) + def.variant(FIRST_VARIANT).fields[i].ty(tcx, substs) } ty::Tuple(inner_tys) => inner_tys[i], _ => bug!("unexpected unsized type {:?}", ty), diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index ff6db143ddf..a95bcaa3f99 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -8,7 +8,7 @@ use rustc_ast::Mutability; use rustc_middle::mir; use rustc_middle::ty; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; -use rustc_target::abi::{self, Abi, Align, HasDataLayout, Size, VariantIdx}; +use rustc_target::abi::{self, Abi, Align, HasDataLayout, Size, FIRST_VARIANT}; use super::{ alloc_range, mir_assign_valid_types, AllocId, AllocRef, AllocRefMut, CheckInAllocMsg, @@ -796,7 +796,7 @@ where let variant_dest = self.place_downcast(&dest, variant_index)?; (variant_index, variant_dest, active_field_index) } - _ => (VariantIdx::from_u32(0), dest.clone(), None), + _ => (FIRST_VARIANT, dest.clone(), None), }; if active_field_index.is_some() { assert_eq!(operands.len(), 1); diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 66fc1c07e20..2be385d551e 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -17,7 +17,7 @@ use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitableExt use rustc_mir_dataflow::impls::MaybeStorageLive; use rustc_mir_dataflow::storage::always_storage_live_locals; use rustc_mir_dataflow::{Analysis, ResultsCursor}; -use rustc_target::abi::{Size, VariantIdx}; +use rustc_target::abi::{Size, FIRST_VARIANT}; #[derive(Copy, Clone, Debug, PartialEq, Eq)] enum EdgeKind { @@ -359,7 +359,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { check_equal(self, location, *f_ty); } ty::Adt(adt_def, substs) => { - let var = parent_ty.variant_index.unwrap_or(VariantIdx::from_u32(0)); + let var = parent_ty.variant_index.unwrap_or(FIRST_VARIANT); let Some(field) = adt_def.variant(var).fields.get(f.as_usize()) else { fail_out_of_bounds(self, location); return; diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index c62c1553d6f..5ca4087cdd3 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -14,12 +14,11 @@ use rustc_hir as hir; use rustc_hir::def::Res; use rustc_hir::def_id::LocalDefId; use rustc_hir::PatKind; -use rustc_index::vec::Idx; use rustc_infer::infer::InferCtxt; use rustc_middle::hir::place::ProjectionKind; use rustc_middle::mir::FakeReadCause; use rustc_middle::ty::{self, adjustment, AdtKind, Ty, TyCtxt}; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::FIRST_VARIANT; use ty::BorrowKind::ImmBorrow; use crate::mem_categorization as mc; @@ -549,7 +548,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { &*with_expr, with_place.clone(), with_field.ty(self.tcx(), substs), - ProjectionKind::Field(f_index as u32, VariantIdx::new(0)), + ProjectionKind::Field(f_index as u32, FIRST_VARIANT), ); self.delegate_consume(&field_place, field_place.hir_id); } diff --git a/compiler/rustc_hir_typeck/src/mem_categorization.rs b/compiler/rustc_hir_typeck/src/mem_categorization.rs index 95e5483abf3..19c4146de89 100644 --- a/compiler/rustc_hir_typeck/src/mem_categorization.rs +++ b/compiler/rustc_hir_typeck/src/mem_categorization.rs @@ -59,10 +59,9 @@ use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::LocalDefId; use rustc_hir::pat_util::EnumerateAndAdjustIterator; use rustc_hir::PatKind; -use rustc_index::vec::Idx; use rustc_infer::infer::InferCtxt; use rustc_span::Span; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::{VariantIdx, FIRST_VARIANT}; use rustc_trait_selection::infer::InferCtxtExt; pub(crate) trait HirNode { @@ -331,7 +330,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { expr, base, expr_ty, - ProjectionKind::Field(field_idx as u32, VariantIdx::new(0)), + ProjectionKind::Field(field_idx as u32, FIRST_VARIANT), )) } @@ -561,7 +560,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => { // Structs and Unions have only have one variant. - Ok(VariantIdx::new(0)) + Ok(FIRST_VARIANT) } _ => bug!("expected ADT path, found={:?}", res), } @@ -675,7 +674,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { for (i, subpat) in subpats.iter().enumerate_and_adjust(total_fields, dots_pos) { let subpat_ty = self.pat_ty_adjusted(subpat)?; - let projection_kind = ProjectionKind::Field(i as u32, VariantIdx::new(0)); + let projection_kind = ProjectionKind::Field(i as u32, FIRST_VARIANT); let sub_place = self.cat_projection(pat, place_with_id.clone(), subpat_ty, projection_kind); self.cat_pattern_(sub_place, subpat, op)?; diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index eadc30a799b..8fe5a3cc789 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -49,8 +49,7 @@ use rustc_span::{BytePos, Pos, Span, Symbol}; use rustc_trait_selection::infer::InferCtxtExt; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_index::vec::Idx; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::FIRST_VARIANT; use std::iter; @@ -1406,7 +1405,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ProjectionKind::Field(..) )) ); - def.variants().get(VariantIdx::new(0)).unwrap().fields.iter().enumerate().any( + def.variants().get(FIRST_VARIANT).unwrap().fields.iter().enumerate().any( |(i, field)| { let paths_using_field = captured_by_move_projs .iter() diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 64c3ef45137..c1b247e3d61 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -58,7 +58,6 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdSet, CRATE_DEF_ID}; use rustc_hir::intravisit::FnKind as HirFnKind; use rustc_hir::{Body, FnDecl, ForeignItemKind, GenericParamKind, Node, PatKind, PredicateOrigin}; -use rustc_index::vec::Idx; use rustc_middle::lint::in_external_macro; use rustc_middle::ty::layout::{LayoutError, LayoutOf}; use rustc_middle::ty::print::with_no_trimmed_paths; @@ -69,7 +68,7 @@ use rustc_span::edition::Edition; use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{BytePos, InnerSpan, Span}; -use rustc_target::abi::{Abi, VariantIdx}; +use rustc_target::abi::{Abi, FIRST_VARIANT}; use rustc_trait_selection::infer::{InferCtxtExt, TyCtxtInferExt}; use rustc_trait_selection::traits::{self, misc::type_allowed_to_implement_copy}; @@ -2788,7 +2787,7 @@ impl ClashingExternDeclarations { ); if is_transparent && !is_non_null { debug_assert_eq!(def.variants().len(), 1); - let v = &def.variant(VariantIdx::new(0)); + let v = &def.variant(FIRST_VARIANT); // continue with `ty`'s non-ZST field, // otherwise `ty` is a ZST and we can return if let Some(field) = transparent_newtype_field(tcx, v) { diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index ec21030b302..50d7fb1813a 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -10,11 +10,11 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::DefId; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::vec::IndexVec; use rustc_query_system::ich::StableHashingContext; use rustc_session::DataTypeKind; use rustc_span::symbol::sym; -use rustc_target::abi::{ReprOptions, VariantIdx}; +use rustc_target::abi::{ReprOptions, VariantIdx, FIRST_VARIANT}; use std::cell::RefCell; use std::cmp::Ordering; @@ -228,7 +228,7 @@ impl AdtDefData { AdtKind::Struct => AdtFlags::IS_STRUCT, }; - if kind == AdtKind::Struct && variants[VariantIdx::new(0)].ctor.is_some() { + if kind == AdtKind::Struct && variants[FIRST_VARIANT].ctor.is_some() { flags |= AdtFlags::HAS_CTOR; } @@ -357,7 +357,7 @@ impl<'tcx> AdtDef<'tcx> { /// Asserts this is a struct or union and returns its unique variant. pub fn non_enum_variant(self) -> &'tcx VariantDef { assert!(self.is_struct() || self.is_union()); - &self.variant(VariantIdx::new(0)) + &self.variant(FIRST_VARIANT) } #[inline] @@ -493,7 +493,7 @@ impl<'tcx> AdtDef<'tcx> { #[inline] pub fn variant_range(self) -> Range { - VariantIdx::new(0)..VariantIdx::new(self.variants().len()) + FIRST_VARIANT..self.variants().next_index() } /// Computes the discriminant value used by a specific variant. diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 35a581d314c..d03cc324e51 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -22,7 +22,7 @@ use rustc_index::vec::Idx; use rustc_macros::HashStable; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::{VariantIdx, FIRST_VARIANT}; use rustc_target::spec::abi::{self, Abi}; use std::borrow::Cow; use std::cmp::Ordering; @@ -517,8 +517,7 @@ impl<'tcx> GeneratorSubsts<'tcx> { #[inline] pub fn variant_range(&self, def_id: DefId, tcx: TyCtxt<'tcx>) -> Range { // FIXME requires optimized MIR - let num_variants = tcx.generator_layout(def_id).unwrap().variant_fields.len(); - VariantIdx::new(0)..VariantIdx::new(num_variants) + FIRST_VARIANT..tcx.generator_layout(def_id).unwrap().variant_fields.next_index() } /// The discriminant for the given variant. Panics if the `variant_index` is diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs index 33200b80a57..e112bf9829b 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -13,9 +13,7 @@ use rustc_middle::thir::*; use rustc_middle::ty::AdtDef; use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, Variance}; use rustc_span::Span; -use rustc_target::abi::VariantIdx; - -use rustc_index::vec::Idx; +use rustc_target::abi::{VariantIdx, FIRST_VARIANT}; use std::assert_matches::assert_matches; use std::iter; @@ -91,7 +89,7 @@ fn convert_to_hir_projections_and_truncate_for_capture( let hir_projection = match mir_projection { ProjectionElem::Deref => HirProjectionKind::Deref, ProjectionElem::Field(field, _) => { - let variant = variant.unwrap_or(VariantIdx::new(0)); + let variant = variant.unwrap_or(FIRST_VARIANT); HirProjectionKind::Field(field.index() as u32, variant) } ProjectionElem::Downcast(.., idx) => { diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 6fd9b9dbb57..04e9273fc46 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -20,7 +20,7 @@ use rustc_middle::ty::{ self, AdtKind, InlineConstSubsts, InlineConstSubstsParts, ScalarInt, Ty, UpvarSubsts, UserType, }; use rustc_span::{sym, Span}; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::FIRST_VARIANT; impl<'tcx> Cx<'tcx> { pub(crate) fn mirror_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) -> ExprId { @@ -357,7 +357,7 @@ impl<'tcx> Cx<'tcx> { Res::Def(DefKind::Ctor(_, CtorKind::Fn), ctor_id) => { Some((adt_def, adt_def.variant_index_with_ctor_id(ctor_id))) } - Res::SelfCtor(..) => Some((adt_def, VariantIdx::new(0))), + Res::SelfCtor(..) => Some((adt_def, FIRST_VARIANT)), _ => None, }) } else { @@ -510,7 +510,7 @@ impl<'tcx> Cx<'tcx> { debug!("make_mirror_unadjusted: (struct/union) user_ty={:?}", user_ty); ExprKind::Adt(Box::new(AdtExpr { adt_def: *adt, - variant_index: VariantIdx::new(0), + variant_index: FIRST_VARIANT, substs, user_ty, fields: self.field_refs(fields), @@ -732,7 +732,7 @@ impl<'tcx> Cx<'tcx> { } hir::ExprKind::Field(ref source, ..) => ExprKind::Field { lhs: self.mirror_expr(source), - variant_index: VariantIdx::new(0), + variant_index: FIRST_VARIANT, name: Field::new(self.typeck_results.field_index(expr.hir_id)), }, hir::ExprKind::Cast(ref source, ref cast_ty) => { diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index e5b7d685c49..8a7b1fce51d 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -60,7 +60,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt, VariantDef}; use rustc_middle::{middle::stability::EvalResult, mir::interpret::ConstValue}; use rustc_session::lint; use rustc_span::{Span, DUMMY_SP}; -use rustc_target::abi::{Integer, Size, VariantIdx}; +use rustc_target::abi::{Integer, Size, VariantIdx, FIRST_VARIANT}; use self::Constructor::*; use self::SliceKind::*; @@ -706,7 +706,7 @@ impl<'tcx> Constructor<'tcx> { Variant(idx) => idx, Single => { assert!(!adt.is_enum()); - VariantIdx::new(0) + FIRST_VARIANT } _ => bug!("bad constructor {:?} for adt {:?}", self, adt), } diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index 486275570bd..fe6728fc76e 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -7,7 +7,7 @@ use rustc_middle::traits::Reveal; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::{VariantIdx, FIRST_VARIANT}; use std::{fmt, iter}; /// The value of an inserted drop flag. @@ -468,7 +468,7 @@ where let fields = self.move_paths_for_fields( self.place, self.path, - &adt.variant(VariantIdx::new(0)), + &adt.variant(FIRST_VARIANT), substs, ); self.drop_ladder(fields, succ, unwind) @@ -894,7 +894,7 @@ where let unit_temp = Place::from(self.new_temp(tcx.mk_unit())); let free_func = tcx.require_lang_item(LangItem::BoxFree, Some(self.source_info.span)); let args = adt - .variant(VariantIdx::new(0)) + .variant(FIRST_VARIANT) .fields .iter() .enumerate() diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 9cba8870f23..7136e42189a 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -10,7 +10,7 @@ use rustc_middle::mir::*; use rustc_middle::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt}; use rustc_session::config::OptLevel; use rustc_span::{hygiene::ExpnKind, ExpnData, LocalExpnId, Span}; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::FIRST_VARIANT; use rustc_target::spec::abi::Abi; use crate::simplify::{remove_dead_blocks, CfgSimplifier}; @@ -911,7 +911,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> { check_equal(self, *f_ty); } ty::Adt(adt_def, substs) => { - let var = parent_ty.variant_index.unwrap_or(VariantIdx::from_u32(0)); + let var = parent_ty.variant_index.unwrap_or(FIRST_VARIANT); let Some(field) = adt_def.variant(var).fields.get(f.as_usize()) else { self.validation = Err("malformed MIR"); return; diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index ebe63d6cb7e..970a0a8d4bf 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -5,7 +5,7 @@ use rustc_middle::mir::*; use rustc_middle::ty::query::Providers; use rustc_middle::ty::InternalSubsts; use rustc_middle::ty::{self, EarlyBinder, GeneratorSubsts, Ty, TyCtxt}; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::{VariantIdx, FIRST_VARIANT}; use rustc_index::vec::{Idx, IndexVec}; @@ -816,11 +816,8 @@ pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> { let source_info = SourceInfo::outermost(span); - let variant_index = if adt_def.is_enum() { - adt_def.variant_index_with_ctor_id(ctor_id) - } else { - VariantIdx::new(0) - }; + let variant_index = + if adt_def.is_enum() { adt_def.variant_index_with_ctor_id(ctor_id) } else { FIRST_VARIANT }; // Generate the following MIR: // diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index 4d0fd260de2..b67607a4db6 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -8,7 +8,7 @@ use rustc_middle::ty::abstract_const::CastKind; use rustc_middle::ty::{self, Expr, TyCtxt, TypeVisitableExt}; use rustc_middle::{mir, thir}; use rustc_span::Span; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::{VariantIdx, FIRST_VARIANT}; use std::iter; @@ -44,7 +44,7 @@ pub(crate) fn destructure_const<'tcx>( let (head, rest) = branches.split_first().unwrap(); (VariantIdx::from_u32(head.unwrap_leaf().try_to_u32().unwrap()), rest) } else { - (VariantIdx::from_u32(0), branches) + (FIRST_VARIANT, branches) }; let fields = &def.variant(variant_idx).fields; let mut field_consts = Vec::with_capacity(fields.len()); diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 1788f544a7f..380931742e3 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -1,7 +1,7 @@ use hir::def_id::DefId; use rustc_hir as hir; use rustc_index::bit_set::BitSet; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::vec::IndexVec; use rustc_middle::mir::{GeneratorLayout, GeneratorSavedLocal}; use rustc_middle::ty::layout::{ IntegerExt, LayoutCx, LayoutError, LayoutOf, TyAndLayout, MAX_SIMD_LANES, @@ -227,7 +227,7 @@ fn layout_of_uncached<'tcx>( let largest_niche = if count != 0 { element.largest_niche } else { None }; tcx.mk_layout(LayoutS { - variants: Variants::Single { index: VariantIdx::new(0) }, + variants: Variants::Single { index: FIRST_VARIANT }, fields: FieldsShape::Array { stride: element.size, count }, abi, largest_niche, @@ -238,7 +238,7 @@ fn layout_of_uncached<'tcx>( ty::Slice(element) => { let element = cx.layout_of(element)?; tcx.mk_layout(LayoutS { - variants: Variants::Single { index: VariantIdx::new(0) }, + variants: Variants::Single { index: FIRST_VARIANT }, fields: FieldsShape::Array { stride: element.size, count: 0 }, abi: Abi::Aggregate { sized: false }, largest_niche: None, @@ -247,7 +247,7 @@ fn layout_of_uncached<'tcx>( }) } ty::Str => tcx.mk_layout(LayoutS { - variants: Variants::Single { index: VariantIdx::new(0) }, + variants: Variants::Single { index: FIRST_VARIANT }, fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 }, abi: Abi::Aggregate { sized: false }, largest_niche: None, @@ -399,7 +399,7 @@ fn layout_of_uncached<'tcx>( }; tcx.mk_layout(LayoutS { - variants: Variants::Single { index: VariantIdx::new(0) }, + variants: Variants::Single { index: FIRST_VARIANT }, fields, abi: Abi::Vector { element: e_abi, count: e_len }, largest_niche: e_ly.largest_niche, From e0ec9c0b9c08677b967fb2f50978bcb4466152cd Mon Sep 17 00:00:00 2001 From: Ezra Shaw Date: Sat, 11 Mar 2023 21:22:42 +1300 Subject: [PATCH 150/346] rustdoc: tweak `some variants omitted` Don't display `// some variants omitted` if enum is marked `#[non_exhaustive]` --- src/librustdoc/html/render/print_item.rs | 2 +- tests/rustdoc/issue-108925.rs | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 tests/rustdoc/issue-108925.rs diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 579b5a9c723..674cd0d62d4 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1234,7 +1234,7 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean:: w.write_str(",\n"); } - if variants_stripped { + if variants_stripped && !it.is_non_exhaustive() { w.write_str(" // some variants omitted\n"); } if toggle { diff --git a/tests/rustdoc/issue-108925.rs b/tests/rustdoc/issue-108925.rs new file mode 100644 index 00000000000..88aeb3c7f75 --- /dev/null +++ b/tests/rustdoc/issue-108925.rs @@ -0,0 +1,11 @@ +// @has issue_108925/enum.MyThing.html +// @has - '//code' 'Shown' +// @!has - '//code' 'NotShown' +// @!has - '//code' '// some variants omitted' +#[non_exhaustive] +pub enum MyThing { + Shown, + #[doc(hidden)] + NotShown, +} + From b197f1ac2e455d9c39405cd1b70935a7da81f69d Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Fri, 27 Jan 2023 17:22:05 +0300 Subject: [PATCH 151/346] remove obsolete `givens` from regionck --- .../src/check/compare_impl_item.rs | 5 +- .../rustc_hir_analysis/src/check/wfcheck.rs | 4 +- .../src/impl_wf_check/min_specialization.rs | 2 +- compiler/rustc_hir_typeck/src/pat.rs | 9 +--- .../src/infer/canonical/query_response.rs | 4 +- .../src/infer/lexical_region_resolve/mod.rs | 47 +------------------ compiler/rustc_infer/src/infer/mod.rs | 4 -- .../rustc_infer/src/infer/outlives/env.rs | 46 +++++++----------- .../infer/region_constraints/leak_check.rs | 3 -- .../src/infer/region_constraints/mod.rs | 44 ++--------------- .../src/traits/coherence.rs | 1 - .../rustc_trait_selection/src/traits/misc.rs | 1 - 12 files changed, 26 insertions(+), 144 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs index 49665525967..34ffd2e6c8e 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs @@ -330,7 +330,6 @@ fn compare_method_predicate_entailment<'tcx>( // lifetime parameters. let outlives_env = OutlivesEnvironment::with_bounds( param_env, - Some(infcx), infcx.implied_bounds_tys(param_env, impl_m_def_id, wf_tys.clone()), ); infcx.process_registered_region_obligations( @@ -727,7 +726,6 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>( // lifetime parameters. let outlives_environment = OutlivesEnvironment::with_bounds( param_env, - Some(infcx), infcx.implied_bounds_tys(param_env, impl_m_def_id, wf_tys), ); infcx @@ -2068,8 +2066,7 @@ pub(super) fn check_type_bounds<'tcx>( // Finally, resolve all regions. This catches wily misuses of // lifetime parameters. let implied_bounds = infcx.implied_bounds_tys(param_env, impl_ty_def_id, assumed_wf_types); - let outlives_environment = - OutlivesEnvironment::with_bounds(param_env, Some(&infcx), implied_bounds); + let outlives_environment = OutlivesEnvironment::with_bounds(param_env, implied_bounds); infcx.err_ctxt().check_region_obligations_and_report_errors( impl_ty.def_id.expect_local(), diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 737532b98a4..c27da5fa899 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -114,8 +114,7 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>( return; } - let outlives_environment = - OutlivesEnvironment::with_bounds(param_env, Some(infcx), implied_bounds); + let outlives_environment = OutlivesEnvironment::with_bounds(param_env, implied_bounds); let _ = infcx .err_ctxt() @@ -675,7 +674,6 @@ fn resolve_regions_with_wf_tys<'tcx>( let infcx = tcx.infer_ctxt().build(); let outlives_environment = OutlivesEnvironment::with_bounds( param_env, - Some(&infcx), infcx.implied_bounds_tys(param_env, id, wf_tys.clone()), ); let region_bound_pairs = outlives_environment.region_bound_pairs(); diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index 91c64eeec1e..2c1b7f7efac 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -179,7 +179,7 @@ fn get_impl_substs( } let implied_bounds = infcx.implied_bounds_tys(param_env, impl1_def_id, assumed_wf_types); - let outlives_env = OutlivesEnvironment::with_bounds(param_env, Some(infcx), implied_bounds); + let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds); let _ = infcx.err_ctxt().check_region_obligations_and_report_errors(impl1_def_id, &outlives_env); let Ok(impl2_substs) = infcx.fully_resolve(impl2_substs) else { diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index c36c75e4443..11ff65d0c37 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -238,15 +238,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Note that there are two tests to check that this remains true // (`regions-reassign-{match,let}-bound-pointer.rs`). // - // 2. Things go horribly wrong if we use subtype. The reason for - // THIS is a fairly subtle case involving bound regions. See the - // `givens` field in `region_constraints`, as well as the test + // 2. An outdated issue related to the old HIR borrowck. See the test // `regions-relate-bound-regions-on-closures-to-inference-variables.rs`, - // for details. Short version is that we must sometimes detect - // relationships between specific region variables and regions - // bound in a closure signature, and that detection gets thrown - // off when we substitute fresh region variables here to enable - // subtyping. } /// Compute the new expected type and default binding mode from the old ones diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index 268896b671a..e98f68ae5a8 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -640,11 +640,9 @@ pub fn make_query_region_constraints<'tcx>( outlives_obligations: impl Iterator, ty::Region<'tcx>, ConstraintCategory<'tcx>)>, region_constraints: &RegionConstraintData<'tcx>, ) -> QueryRegionConstraints<'tcx> { - let RegionConstraintData { constraints, verifys, givens, member_constraints } = - region_constraints; + let RegionConstraintData { constraints, verifys, member_constraints } = region_constraints; assert!(verifys.is_empty()); - assert!(givens.is_empty()); debug!(?constraints); diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index 2c480355085..cf657756ff5 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -13,7 +13,7 @@ use rustc_data_structures::graph::implementation::{ Direction, Graph, NodeIndex, INCOMING, OUTGOING, }; use rustc_data_structures::intern::Interned; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::vec::IndexVec; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::PlaceholderRegion; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -132,7 +132,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } let graph = self.construct_graph(); - self.expand_givens(&graph); self.expansion(&mut var_data); self.collect_errors(&mut var_data, errors); self.collect_var_errors(&var_data, &graph, errors); @@ -164,38 +163,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { } } - fn expand_givens(&mut self, graph: &RegionGraph<'_>) { - // Givens are a kind of horrible hack to account for - // constraints like 'c <= '0 that are known to hold due to - // closure signatures (see the comment above on the `givens` - // field). They should go away. But until they do, the role - // of this fn is to account for the transitive nature: - // - // Given 'c <= '0 - // and '0 <= '1 - // then 'c <= '1 - - let seeds: Vec<_> = self.data.givens.iter().cloned().collect(); - for (r, vid) in seeds { - // While all things transitively reachable in the graph - // from the variable (`'0` in the example above). - let seed_index = NodeIndex(vid.index() as usize); - for succ_index in graph.depth_traverse(seed_index, OUTGOING) { - let succ_index = succ_index.0; - - // The first N nodes correspond to the region - // variables. Other nodes correspond to constant - // regions. - if succ_index < self.num_vars() { - let succ_vid = RegionVid::new(succ_index); - - // Add `'c <= '1`. - self.data.givens.insert((r, succ_vid)); - } - } - } - } - /// Gets the LUb of a given region and the empty region fn lub_empty(&self, a_region: Region<'tcx>) -> Result, PlaceholderRegion> { match *a_region { @@ -362,18 +329,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { ) -> bool { debug!("expand_node({:?}, {:?} == {:?})", a_region, b_vid, b_data); - match *a_region { - // Check if this relationship is implied by a given. - ty::ReEarlyBound(_) | ty::ReFree(_) => { - if self.data.givens.contains(&(a_region, b_vid)) { - debug!("given"); - return false; - } - } - - _ => {} - } - match *b_data { VarValue::Empty(empty_ui) => { let lub = match self.lub_empty(a_region) { diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index aeb4ddb4212..731559de67c 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -867,10 +867,6 @@ impl<'tcx> InferCtxt<'tcx> { self.inner.borrow().undo_log.opaque_types_in_snapshot(&snapshot.undo_snapshot) } - pub fn add_given(&self, sub: ty::Region<'tcx>, sup: ty::RegionVid) { - self.inner.borrow_mut().unwrap_region_constraints().add_given(sub, sup); - } - pub fn can_sub(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> bool where T: at::ToTrace<'tcx>, diff --git a/compiler/rustc_infer/src/infer/outlives/env.rs b/compiler/rustc_infer/src/infer/outlives/env.rs index 24e3c34dd94..95f8f05ab60 100644 --- a/compiler/rustc_infer/src/infer/outlives/env.rs +++ b/compiler/rustc_infer/src/infer/outlives/env.rs @@ -1,9 +1,9 @@ use crate::infer::free_regions::FreeRegionMap; -use crate::infer::{GenericKind, InferCtxt}; +use crate::infer::GenericKind; use crate::traits::query::OutlivesBound; use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::transitive_relation::TransitiveRelationBuilder; -use rustc_middle::ty::{self, ReEarlyBound, ReFree, ReVar, Region}; +use rustc_middle::ty::{self, Region}; use super::explicit_outlives_bounds; @@ -75,7 +75,7 @@ impl<'tcx> OutlivesEnvironment<'tcx> { region_bound_pairs: Default::default(), }; - builder.add_outlives_bounds(None, explicit_outlives_bounds(param_env)); + builder.add_outlives_bounds(explicit_outlives_bounds(param_env)); builder } @@ -89,11 +89,10 @@ impl<'tcx> OutlivesEnvironment<'tcx> { /// Create a new `OutlivesEnvironment` with extra outlives bounds. pub fn with_bounds( param_env: ty::ParamEnv<'tcx>, - infcx: Option<&InferCtxt<'tcx>>, extra_bounds: impl IntoIterator>, ) -> Self { let mut builder = Self::builder(param_env); - builder.add_outlives_bounds(infcx, extra_bounds); + builder.add_outlives_bounds(extra_bounds); builder.build() } @@ -120,12 +119,7 @@ impl<'tcx> OutlivesEnvironmentBuilder<'tcx> { } /// Processes outlives bounds that are known to hold, whether from implied or other sources. - /// - /// The `infcx` parameter is optional; if the implied bounds may - /// contain inference variables, it must be supplied, in which - /// case we will register "givens" on the inference context. (See - /// `RegionConstraintData`.) - fn add_outlives_bounds(&mut self, infcx: Option<&InferCtxt<'tcx>>, outlives_bounds: I) + fn add_outlives_bounds(&mut self, outlives_bounds: I) where I: IntoIterator>, { @@ -143,24 +137,18 @@ impl<'tcx> OutlivesEnvironmentBuilder<'tcx> { .insert(ty::OutlivesPredicate(GenericKind::Alias(alias_b), r_a)); } OutlivesBound::RegionSubRegion(r_a, r_b) => { - if let (ReEarlyBound(_) | ReFree(_), ReVar(vid_b)) = (r_a.kind(), r_b.kind()) { - infcx - .expect("no infcx provided but region vars found") - .add_given(r_a, vid_b); - } else { - // In principle, we could record (and take - // advantage of) every relationship here, but - // we are also free not to -- it simply means - // strictly less that we can successfully type - // check. Right now we only look for things - // relationships between free regions. (It may - // also be that we should revise our inference - // system to be more general and to make use - // of *every* relationship that arises here, - // but presently we do not.) - if r_a.is_free_or_static() && r_b.is_free() { - self.region_relation.add(r_a, r_b) - } + // In principle, we could record (and take + // advantage of) every relationship here, but + // we are also free not to -- it simply means + // strictly less that we can successfully type + // check. Right now we only look for things + // relationships between free regions. (It may + // also be that we should revise our inference + // system to be more general and to make use + // of *every* relationship that arises here, + // but presently we do not.) + if r_a.is_free_or_static() && r_b.is_free() { + self.region_relation.add(r_a, r_b) } } } diff --git a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs index e413b2bb570..89ada23c667 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/leak_check.rs @@ -424,9 +424,6 @@ impl<'tcx> MiniGraph<'tcx> { &AddConstraint(Constraint::RegSubReg(a, b)) => { each_edge(a, b); } - &AddGiven(a, b) => { - each_edge(a, tcx.mk_re_var(b)); - } &AddVerify(i) => span_bug!( verifys[i].origin.span(), "we never add verifications while doing higher-ranked things", diff --git a/compiler/rustc_infer/src/infer/region_constraints/mod.rs b/compiler/rustc_infer/src/infer/region_constraints/mod.rs index 0b86d9c1fb8..7b272dfd2a4 100644 --- a/compiler/rustc_infer/src/infer/region_constraints/mod.rs +++ b/compiler/rustc_infer/src/infer/region_constraints/mod.rs @@ -7,7 +7,7 @@ use super::{ InferCtxtUndoLogs, MiscVariable, RegionVariableOrigin, Rollback, Snapshot, SubregionOrigin, }; -use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; +use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::intern::Interned; use rustc_data_structures::sync::Lrc; use rustc_data_structures::undo_log::UndoLogs; @@ -104,26 +104,6 @@ pub struct RegionConstraintData<'tcx> { /// An example is a `A <= B` where neither `A` nor `B` are /// inference variables. pub verifys: Vec>, - - /// A "given" is a relationship that is known to hold. In - /// particular, we often know from closure fn signatures that a - /// particular free region must be a subregion of a region - /// variable: - /// - /// foo.iter().filter(<'a> |x: &'a &'b T| ...) - /// - /// In situations like this, `'b` is in fact a region variable - /// introduced by the call to `iter()`, and `'a` is a bound region - /// on the closure (as indicated by the `<'a>` prefix). If we are - /// naive, we wind up inferring that `'b` must be `'static`, - /// because we require that it be greater than `'a` and we do not - /// know what `'a` is precisely. - /// - /// This hashmap is used to avoid that naive scenario. Basically - /// we record the fact that `'a <= 'b` is implied by the fn - /// signature, and then ignore the constraint when solving - /// equations. This is a bit of a hack but seems to work. - pub givens: FxIndexSet<(Region<'tcx>, ty::RegionVid)>, } /// Represents a constraint that influences the inference process. @@ -297,9 +277,6 @@ pub(crate) enum UndoLog<'tcx> { /// We added the given `verify`. AddVerify(usize), - /// We added the given `given`. - AddGiven(Region<'tcx>, ty::RegionVid), - /// We added a GLB/LUB "combination variable". AddCombination(CombineMapType, TwoRegions<'tcx>), } @@ -348,9 +325,6 @@ impl<'tcx> RegionConstraintStorage<'tcx> { self.data.verifys.pop(); assert_eq!(self.data.verifys.len(), index); } - AddGiven(sub, sup) => { - self.data.givens.remove(&(sub, sup)); - } AddCombination(Glb, ref regions) => { self.glbs.remove(regions); } @@ -492,15 +466,6 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { self.undo_log.push(AddVerify(index)); } - pub(super) fn add_given(&mut self, sub: Region<'tcx>, sup: ty::RegionVid) { - // cannot add givens once regions are resolved - if self.data.givens.insert((sub, sup)) { - debug!("add_given({:?} <= {:?})", sub, sup); - - self.undo_log.push(AddGiven(sub, sup)); - } - } - pub(super) fn make_eqregion( &mut self, origin: SubregionOrigin<'tcx>, @@ -804,11 +769,8 @@ impl<'tcx> RegionConstraintData<'tcx> { /// Returns `true` if this region constraint data contains no constraints, and `false` /// otherwise. pub fn is_empty(&self) -> bool { - let RegionConstraintData { constraints, member_constraints, verifys, givens } = self; - constraints.is_empty() - && member_constraints.is_empty() - && verifys.is_empty() - && givens.is_empty() + let RegionConstraintData { constraints, member_constraints, verifys } = self; + constraints.is_empty() && member_constraints.is_empty() && verifys.is_empty() } } diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 572d20b5368..65feda56db4 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -396,7 +396,6 @@ fn resolve_negative_obligation<'tcx>( let wf_tys = ocx.assumed_wf_types(param_env, DUMMY_SP, body_def_id); let outlives_env = OutlivesEnvironment::with_bounds( param_env, - Some(&infcx), infcx.implied_bounds_tys(param_env, body_def_id, wf_tys), ); diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index 336db4fee6c..0bde43c54df 100644 --- a/compiler/rustc_trait_selection/src/traits/misc.rs +++ b/compiler/rustc_trait_selection/src/traits/misc.rs @@ -111,7 +111,6 @@ pub fn type_allowed_to_implement_copy<'tcx>( // Check regions assuming the self type of the impl is WF let outlives_env = OutlivesEnvironment::with_bounds( param_env, - Some(&infcx), infcx.implied_bounds_tys( param_env, parent_cause.body_id, From d1743c981704382b33b919379edd082ea9db4834 Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Wed, 1 Feb 2023 13:52:44 +0300 Subject: [PATCH 152/346] resolve regions before implied bounds --- .../src/traits/outlives_bounds.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs index bac02f2d383..6d2dc94845d 100644 --- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs @@ -3,7 +3,8 @@ use crate::traits::query::type_op::{self, TypeOp, TypeOpOutput}; use crate::traits::query::NoSolution; use crate::traits::{ObligationCause, ObligationCtxt}; use rustc_data_structures::fx::FxIndexSet; -use rustc_middle::ty::{self, ParamEnv, Ty}; +use rustc_infer::infer::resolve::OpportunisticRegionResolver; +use rustc_middle::ty::{self, ParamEnv, Ty, TypeFolder, TypeVisitableExt}; use rustc_span::def_id::LocalDefId; pub use rustc_middle::traits::query::OutlivesBound; @@ -52,6 +53,10 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> { body_id: LocalDefId, ty: Ty<'tcx>, ) -> Vec> { + let ty = self.resolve_vars_if_possible(ty); + let ty = OpportunisticRegionResolver::new(self).fold_ty(ty); + assert!(!ty.needs_infer()); + let span = self.tcx.def_span(body_id); let result = param_env .and(type_op::implied_outlives_bounds::ImpliedOutlivesBounds { ty }) @@ -106,10 +111,7 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> { tys: FxIndexSet>, ) -> Bounds<'a, 'tcx> { tys.into_iter() - .map(move |ty| { - let ty = self.resolve_vars_if_possible(ty); - self.implied_outlives_bounds(param_env, body_id, ty) - }) + .map(move |ty| self.implied_outlives_bounds(param_env, body_id, ty)) .flatten() } } From 9cfb5f73ba3c9b4c982ff4c0c54ab7ebd207408f Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Wed, 1 Feb 2023 14:57:17 +0300 Subject: [PATCH 153/346] add test --- tests/ui/implied-bounds/normalization.rs | 58 ++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 tests/ui/implied-bounds/normalization.rs diff --git a/tests/ui/implied-bounds/normalization.rs b/tests/ui/implied-bounds/normalization.rs new file mode 100644 index 00000000000..f776fc98a9e --- /dev/null +++ b/tests/ui/implied-bounds/normalization.rs @@ -0,0 +1,58 @@ +// Test that we get implied bounds from complex projections after normalization. + +// check-pass + +// implementations wil ensure that +// WF(>::Ty) implies T: 'a +trait Combine<'a> { + type Ty; +} + +impl<'a, T: 'a> Combine<'a> for Box { + type Ty = &'a T; +} + +// ======= Wrappers ====== + +// normalizes to a projection +struct WrapA(T); +impl<'a, T> Combine<'a> for WrapA +where + T: Combine<'a>, +{ + type Ty = T::Ty; +} + +// as Combine<'a>>::Ty normalizes to a type variable ?X +// with constraint `>::Ty == ?X` +struct WrapB(T); +impl<'a, X, T> Combine<'a> for WrapB +where + T: Combine<'a, Ty = X>, +{ + type Ty = X; +} + +// as Combine<'a>>::Ty normalizes to `&'a &'?x ()` +// with constraint `>::Ty == &'a &'?x ()` +struct WrapC(T); +impl<'a, 'x: 'a, T> Combine<'a> for WrapC +where + T: Combine<'a, Ty = &'a &'x ()>, +{ + type Ty = &'a &'x (); +} + +//==== Test implied bounds ====== + +fn test_wrap<'a, 'b, 'c1, 'c2, A, B>( + _: > as Combine<'a>>::Ty, // normalized: &'a A + _: > as Combine<'b>>::Ty, // normalized: &'b B + _: > as Combine<'c2>>::Ty, // normalized: &'c2 &'c1 () +) { + None::<&'a A>; + None::<&'b B>; + None::<&'c2 &'c1 ()>; +} + +fn main() {} From b20aa97d480fd6917f88f26b2b038bd1c06bd9da Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Thu, 9 Mar 2023 11:30:49 +0300 Subject: [PATCH 154/346] exhaustive match on implied bounds regions --- .../rustc_infer/src/infer/outlives/env.rs | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_infer/src/infer/outlives/env.rs b/compiler/rustc_infer/src/infer/outlives/env.rs index 95f8f05ab60..a480ee5429e 100644 --- a/compiler/rustc_infer/src/infer/outlives/env.rs +++ b/compiler/rustc_infer/src/infer/outlives/env.rs @@ -136,21 +136,14 @@ impl<'tcx> OutlivesEnvironmentBuilder<'tcx> { self.region_bound_pairs .insert(ty::OutlivesPredicate(GenericKind::Alias(alias_b), r_a)); } - OutlivesBound::RegionSubRegion(r_a, r_b) => { - // In principle, we could record (and take - // advantage of) every relationship here, but - // we are also free not to -- it simply means - // strictly less that we can successfully type - // check. Right now we only look for things - // relationships between free regions. (It may - // also be that we should revise our inference - // system to be more general and to make use - // of *every* relationship that arises here, - // but presently we do not.) - if r_a.is_free_or_static() && r_b.is_free() { - self.region_relation.add(r_a, r_b) - } - } + OutlivesBound::RegionSubRegion(r_a, r_b) => match (*r_a, *r_b) { + ( + ty::ReStatic | ty::ReEarlyBound(_) | ty::ReFree(_), + ty::ReStatic | ty::ReEarlyBound(_) | ty::ReFree(_), + ) => self.region_relation.add(r_a, r_b), + (ty::ReError(_), _) | (_, ty::ReError(_)) => {} + _ => bug!("add_outlives_bounds: unexpected regions"), + }, } } } From 2a3177a8bcc4c5a5285dc2908a0f1ce98e9a6377 Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Sun, 26 Mar 2023 14:37:24 +0300 Subject: [PATCH 155/346] tolerate region vars in implied bounds See https://github.com/rust-lang/rust/issues/109628. --- .../rustc_infer/src/infer/outlives/env.rs | 5 +++- .../implied-bounds/ice-unbound-region-vars.rs | 24 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 tests/ui/implied-bounds/ice-unbound-region-vars.rs diff --git a/compiler/rustc_infer/src/infer/outlives/env.rs b/compiler/rustc_infer/src/infer/outlives/env.rs index a480ee5429e..47e3dd762b0 100644 --- a/compiler/rustc_infer/src/infer/outlives/env.rs +++ b/compiler/rustc_infer/src/infer/outlives/env.rs @@ -142,7 +142,10 @@ impl<'tcx> OutlivesEnvironmentBuilder<'tcx> { ty::ReStatic | ty::ReEarlyBound(_) | ty::ReFree(_), ) => self.region_relation.add(r_a, r_b), (ty::ReError(_), _) | (_, ty::ReError(_)) => {} - _ => bug!("add_outlives_bounds: unexpected regions"), + // FIXME(#109628): We shouldn't have existential variables in implied bounds. + // Panic here once the linked issue is resolved! + (ty::ReVar(_), _) | (_, ty::ReVar(_)) => {} + _ => bug!("add_outlives_bounds: unexpected regions: ({r_a:?}, {r_b:?})"), }, } } diff --git a/tests/ui/implied-bounds/ice-unbound-region-vars.rs b/tests/ui/implied-bounds/ice-unbound-region-vars.rs new file mode 100644 index 00000000000..9e1e3feaeec --- /dev/null +++ b/tests/ui/implied-bounds/ice-unbound-region-vars.rs @@ -0,0 +1,24 @@ +// Because of #109628, we can have unbounded region vars in implied bounds. +// Make sure we don't ICE in this case! +// +// check-pass + +pub trait MapAccess { + type Error; + fn next_key_seed(&mut self) -> Option; +} + +struct Access<'a> { + _marker: std::marker::PhantomData<&'a ()>, +} + +// implied_bounds(Option) = ['?1: 'a, ] +// where '?1 is a fresh region var. +impl<'a, 'b: 'a> MapAccess for Access<'a> { + type Error = (); + fn next_key_seed(&mut self) -> Option { + unimplemented!() + } +} + +fn main() {} From 2fe4cad77f03e9eb323382e531d136f0e32b3645 Mon Sep 17 00:00:00 2001 From: Alex Huang Date: Sun, 26 Mar 2023 09:45:53 -0400 Subject: [PATCH 156/346] Allow passing the --nocapture flag to compiletest --- src/tools/compiletest/src/common.rs | 2 ++ src/tools/compiletest/src/main.rs | 15 +++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 7fe2e6257d9..ff9c40afeb8 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -384,6 +384,8 @@ pub struct Config { pub only_modified: bool, pub target_cfg: LazyCell, + + pub nocapture: bool, } impl Config { diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index 1760c29ec66..b9d53b7b07d 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -151,6 +151,7 @@ pub fn parse_config(args: Vec) -> Config { ) .optflag("", "force-rerun", "rerun tests even if the inputs are unchanged") .optflag("", "only-modified", "only run tests that result been modified") + .optflag("", "nocapture", "") .optflag("h", "help", "show this message") .reqopt("", "channel", "current Rust channel", "CHANNEL") .optopt("", "edition", "default Rust edition", "EDITION"); @@ -304,6 +305,8 @@ pub fn parse_config(args: Vec) -> Config { force_rerun: matches.opt_present("force-rerun"), target_cfg: LazyCell::new(), + + nocapture: matches.opt_present("nocapture"), } } @@ -496,6 +499,13 @@ fn configure_lldb(config: &Config) -> Option { } pub fn test_opts(config: &Config) -> test::TestOpts { + if env::var("RUST_TEST_NOCAPTURE").is_ok() { + eprintln!( + "WARNING: RUST_TEST_NOCAPTURE is no longer used. \ + Use the `--nocapture` flag instead." + ); + } + test::TestOpts { exclude_should_panic: false, filters: config.filters.clone(), @@ -505,10 +515,7 @@ pub fn test_opts(config: &Config) -> test::TestOpts { logfile: config.logfile.clone(), run_tests: true, bench_benchmarks: true, - nocapture: match env::var("RUST_TEST_NOCAPTURE") { - Ok(val) => &val != "0", - Err(_) => false, - }, + nocapture: config.nocapture, color: config.color, shuffle: false, shuffle_seed: None, From 28982a1e471e7dad82f3f1c1f0a9e9d15d3495d5 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 26 Mar 2023 17:50:02 +0200 Subject: [PATCH 157/346] Fix "Directly go to item in search if there is only one result" setting --- src/librustdoc/html/static/js/search.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 36ff20e299e..d764981c3cf 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -1888,11 +1888,7 @@ function initSearch(rawSearchIndex) { function showResults(results, go_to_first, filterCrates) { const search = searchState.outputElement(); if (go_to_first || (results.others.length === 1 - && getSettingValue("go-to-only-result") === "true" - // By default, the search DOM element is "empty" (meaning it has no children not - // text content). Once a search has been run, it won't be empty, even if you press - // ESC or empty the search input (which also "cancels" the search). - && (!search.firstChild || search.firstChild.innerText !== searchState.loadingText)) + && getSettingValue("go-to-only-result") === "true") ) { const elem = document.createElement("a"); elem.href = results.others[0].href; From bc9eec04b7e9713e7d0bde0ad4f8bfc8574082a6 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 26 Mar 2023 17:49:52 +0200 Subject: [PATCH 158/346] Add GUI test for "Directly go to item in search if there is only one result" setting --- .../setting-go-to-only-result.goml | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 tests/rustdoc-gui/setting-go-to-only-result.goml diff --git a/tests/rustdoc-gui/setting-go-to-only-result.goml b/tests/rustdoc-gui/setting-go-to-only-result.goml new file mode 100644 index 00000000000..3811011a64e --- /dev/null +++ b/tests/rustdoc-gui/setting-go-to-only-result.goml @@ -0,0 +1,63 @@ +// Checks that the setting "Directly go to item in search if there is only one result " is working as expected. + +define-function: ( + "check-setting", + (storage_value, setting_attribute_value), + block { + assert-local-storage: {"rustdoc-go-to-only-result": |storage_value|} + click: "#settings-menu" + wait-for: "#settings" + assert-property: ("#go-to-only-result", {"checked": |setting_attribute_value|}) + } +) + +goto: "file://" + |DOC_PATH| + "/lib2/index.html" + +call-function: ("check-setting", { + "storage_value": null, + "setting_attribute_value": "false", +}) + +// By default, the search doesn't automatically go to the page if there is only one result. +goto: "file://" + |DOC_PATH| + "/lib2/index.html?search=HasALongTraitWithParams" +// It will timeout if the setting isn't working. +wait-for: "#search" +assert-document-property: ({"URL": "/lib2/index.html"}, CONTAINS) + +// Now we change its value. +click: "#settings-menu" +wait-for: "#settings" +click: "#go-to-only-result" +assert-local-storage: {"rustdoc-go-to-only-result": "true"} + +goto: "file://" + |DOC_PATH| + "/lib2/index.html" +// We enter it into the search. +write: (".search-input", "HasALongTraitWithParams") +wait-for-document-property: {"title": "HasALongTraitWithParams in lib2 - Rust"} +assert-document-property: ({"URL": "/lib2/struct.HasALongTraitWithParams.html"}, ENDS_WITH) + +// We try again to see if it goes to the only result +goto: "file://" + |DOC_PATH| + "/lib2/index.html?search=HasALongTraitWithParams" +wait-for-document-property: {"title": "HasALongTraitWithParams in lib2 - Rust"} +assert-document-property: ({"URL": "/lib2/struct.HasALongTraitWithParams.html"}, ENDS_WITH) + +// We check the settings +call-function: ("check-setting", { + "storage_value": "true", + "setting_attribute_value": "true", +}) + +// And now we re-disable the setting. +click: "#go-to-only-result" +assert-local-storage: {"rustdoc-go-to-only-result": "false"} + +goto: "file://" + |DOC_PATH| + "/lib2/index.html?search=HasALongTraitWithParams" +// It will timeout if the setting isn't working. +wait-for: "#search" +assert-document-property: ({"URL": "/lib2/index.html"}, CONTAINS) + +// And we check everything is back the way it was before. +call-function: ("check-setting", { + "storage_value": "false", + "setting_attribute_value": "false", +}) From b874502a2064fef93cb25aebf31b8ea1c5a41621 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 6 Oct 2022 16:45:16 +0000 Subject: [PATCH 159/346] Remove unnecessary raw pointer in __rust_start_panic arg It is no longer necessary as __rust_start_panic switched to the Rust abi. --- library/panic_abort/src/android.rs | 4 ++-- library/panic_abort/src/lib.rs | 2 +- library/panic_unwind/src/lib.rs | 4 ++-- library/std/src/panicking.rs | 15 +++++---------- 4 files changed, 10 insertions(+), 15 deletions(-) diff --git a/library/panic_abort/src/android.rs b/library/panic_abort/src/android.rs index 0fd824f8a45..20b5b6b5146 100644 --- a/library/panic_abort/src/android.rs +++ b/library/panic_abort/src/android.rs @@ -15,7 +15,7 @@ type SetAbortMessageType = unsafe extern "C" fn(*const libc::c_char) -> (); // // Weakly resolve the symbol for android_set_abort_message. This function is only available // for API >= 21. -pub(crate) unsafe fn android_set_abort_message(payload: *mut &mut dyn BoxMeUp) { +pub(crate) unsafe fn android_set_abort_message(payload: &mut dyn BoxMeUp) { let func_addr = libc::dlsym(libc::RTLD_DEFAULT, ANDROID_SET_ABORT_MESSAGE.as_ptr() as *const libc::c_char) as usize; @@ -23,7 +23,7 @@ pub(crate) unsafe fn android_set_abort_message(payload: *mut &mut dyn BoxMeUp) { return; } - let payload = (*payload).get(); + let payload = payload.get(); let msg = match payload.downcast_ref::<&'static str>() { Some(msg) => msg.as_bytes(), None => match payload.downcast_ref::() { diff --git a/library/panic_abort/src/lib.rs b/library/panic_abort/src/lib.rs index a3cebf99c53..b193d79b0e1 100644 --- a/library/panic_abort/src/lib.rs +++ b/library/panic_abort/src/lib.rs @@ -29,7 +29,7 @@ pub unsafe extern "C" fn __rust_panic_cleanup(_: *mut u8) -> *mut (dyn Any + Sen // "Leak" the payload and shim to the relevant abort on the platform in question. #[rustc_std_internal_symbol] -pub unsafe fn __rust_start_panic(_payload: *mut &mut dyn BoxMeUp) -> u32 { +pub unsafe fn __rust_start_panic(_payload: &mut dyn BoxMeUp) -> u32 { // Android has the ability to attach a message as part of the abort. #[cfg(target_os = "android")] android::android_set_abort_message(_payload); diff --git a/library/panic_unwind/src/lib.rs b/library/panic_unwind/src/lib.rs index ea3c9a7a663..ce78ab82ef9 100644 --- a/library/panic_unwind/src/lib.rs +++ b/library/panic_unwind/src/lib.rs @@ -99,8 +99,8 @@ pub unsafe extern "C" fn __rust_panic_cleanup(payload: *mut u8) -> *mut (dyn Any // Entry point for raising an exception, just delegates to the platform-specific // implementation. #[rustc_std_internal_symbol] -pub unsafe fn __rust_start_panic(payload: *mut &mut dyn BoxMeUp) -> u32 { - let payload = Box::from_raw((*payload).take_box()); +pub unsafe fn __rust_start_panic(payload: &mut dyn BoxMeUp) -> u32 { + let payload = Box::from_raw(payload.take_box()); imp::panic(payload) } diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index e59f32af77d..e505466e535 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -46,12 +46,10 @@ extern "C" { fn __rust_panic_cleanup(payload: *mut u8) -> *mut (dyn Any + Send + 'static); } -#[allow(improper_ctypes)] extern "Rust" { - /// `payload` is passed through another layer of raw pointers as `&mut dyn Trait` is not - /// FFI-safe. `BoxMeUp` lazily performs allocation only when needed (this avoids allocations - /// when using the "abort" panic runtime). - fn __rust_start_panic(payload: *mut &mut dyn BoxMeUp) -> u32; + /// `BoxMeUp` lazily performs allocation only when needed (this avoids + /// allocations when using the "abort" panic runtime). + fn __rust_start_panic(payload: &mut dyn BoxMeUp) -> u32; } /// This function is called by the panic runtime if FFI code catches a Rust @@ -738,10 +736,7 @@ pub fn rust_panic_without_hook(payload: Box) -> ! { /// yer breakpoints. #[inline(never)] #[cfg_attr(not(test), rustc_std_internal_symbol)] -fn rust_panic(mut msg: &mut dyn BoxMeUp) -> ! { - let code = unsafe { - let obj = &mut msg as *mut &mut dyn BoxMeUp; - __rust_start_panic(obj) - }; +fn rust_panic(msg: &mut dyn BoxMeUp) -> ! { + let code = unsafe { __rust_start_panic(msg) }; rtabort!("failed to initiate panic, error {code}") } From e9815d663881d5b7122ebc59f12f279c79ea23da Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 26 Mar 2023 17:30:18 +0000 Subject: [PATCH 160/346] Add missing needs-asm-support annotation to ui/simple_global_asm.rs --- tests/ui/simple_global_asm.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/ui/simple_global_asm.rs b/tests/ui/simple_global_asm.rs index 3c69379ff14..c3b2f2e0bc4 100644 --- a/tests/ui/simple_global_asm.rs +++ b/tests/ui/simple_global_asm.rs @@ -1,4 +1,5 @@ // run-pass +// needs-asm-support #![feature(naked_functions)] #![allow(dead_code)] From 1ce4b37900cf0c7f5e146b866b5a8fae2b93f9fc Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 26 Mar 2023 20:33:54 +0000 Subject: [PATCH 161/346] Don't elaborate non-obligations into obligations --- .../rustc_hir_analysis/src/astconv/mod.rs | 9 +-- .../rustc_hir_analysis/src/check/wfcheck.rs | 7 +- .../src/collect/item_bounds.rs | 11 +-- .../src/impl_wf_check/min_specialization.rs | 34 ++++---- compiler/rustc_hir_typeck/src/closure.rs | 10 +-- .../rustc_hir_typeck/src/method/confirm.rs | 8 +- compiler/rustc_infer/src/traits/util.rs | 78 ++++++++++--------- compiler/rustc_lint/src/unused.rs | 4 +- .../rustc_mir_transform/src/const_prop.rs | 2 +- .../src/const_prop_lint.rs | 2 +- .../src/solve/assembly.rs | 2 +- .../src/traits/auto_trait.rs | 3 +- .../src/traits/coherence.rs | 4 +- .../src/traits/error_reporting/ambiguity.rs | 6 +- .../src/traits/error_reporting/mod.rs | 4 +- .../rustc_trait_selection/src/traits/mod.rs | 6 +- .../src/traits/object_safety.rs | 42 +++++----- .../rustc_trait_selection/src/traits/wf.rs | 6 +- .../src/needless_pass_by_value.rs | 4 +- src/tools/clippy/clippy_utils/src/lib.rs | 1 - 20 files changed, 112 insertions(+), 131 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 6d9dfe9697c..4ab6bb5908b 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -1427,13 +1427,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { for (base_trait_ref, span, constness) in regular_traits_refs_spans { assert_eq!(constness, ty::BoundConstness::NotConst); - for obligation in traits::elaborate_trait_ref(tcx, base_trait_ref) { - debug!( - "conv_object_ty_poly_trait_ref: observing object predicate `{:?}`", - obligation.predicate - ); + for pred in traits::elaborate_trait_ref(tcx, base_trait_ref) { + debug!("conv_object_ty_poly_trait_ref: observing object predicate `{:?}`", pred); - let bound_predicate = obligation.predicate.kind(); + let bound_predicate = pred.kind(); match bound_predicate.skip_binder() { ty::PredicateKind::Clause(ty::Clause::Trait(pred)) => { let pred = bound_predicate.rebind(pred); diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 491bd04f346..c912a8a640d 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1912,14 +1912,13 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { // Check elaborated bounds. let implied_obligations = traits::elaborate_predicates_with_span(tcx, predicates_with_span); - for obligation in implied_obligations { + for (pred, obligation_span) in implied_obligations { // We lower empty bounds like `Vec:` as // `WellFormed(Vec)`, which will later get checked by // regular WF checking - if let ty::PredicateKind::WellFormed(..) = obligation.predicate.kind().skip_binder() { + if let ty::PredicateKind::WellFormed(..) = pred.kind().skip_binder() { continue; } - let pred = obligation.predicate; // Match the existing behavior. if pred.is_global() && !pred.has_late_bound_vars() { let pred = self.normalize(span, None, pred); @@ -1930,8 +1929,6 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> { if let Some(hir::Generics { predicates, .. }) = hir_node.and_then(|node| node.generics()) { - let obligation_span = obligation.cause.span(); - span = predicates .iter() // There seems to be no better way to find out which predicate we are in diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs index aa66d7bb5ef..d2e45c28658 100644 --- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs +++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs @@ -130,12 +130,9 @@ pub(super) fn item_bounds( tcx: TyCtxt<'_>, def_id: DefId, ) -> ty::EarlyBinder<&'_ ty::List>> { - let bounds = tcx.mk_predicates_from_iter( - util::elaborate_predicates( - tcx, - tcx.explicit_item_bounds(def_id).iter().map(|&(bound, _span)| bound), - ) - .map(|obligation| obligation.predicate), - ); + let bounds = tcx.mk_predicates_from_iter(util::elaborate_predicates( + tcx, + tcx.explicit_item_bounds(def_id).iter().map(|&(bound, _span)| bound), + )); ty::EarlyBinder(bounds) } diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index 7f1e4ccc964..dfa9e6148aa 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -318,16 +318,8 @@ fn check_predicates<'tcx>( span: Span, ) { let instantiated = tcx.predicates_of(impl1_def_id).instantiate(tcx, impl1_substs); - let impl1_predicates: Vec<_> = traits::elaborate_predicates_with_span( - tcx, - std::iter::zip( - instantiated.predicates, - // Don't drop predicates (unsound!) because `spans` is too short - instantiated.spans.into_iter().chain(std::iter::repeat(span)), - ), - ) - .map(|obligation| (obligation.predicate, obligation.cause.span)) - .collect(); + let impl1_predicates: Vec<_> = + traits::elaborate_predicates_with_span(tcx, instantiated.into_iter()).collect(); let mut impl2_predicates = if impl2_node.is_from_trait() { // Always applicable traits have to be always applicable without any @@ -341,7 +333,6 @@ fn check_predicates<'tcx>( .predicates .into_iter(), ) - .map(|obligation| obligation.predicate) .collect() }; debug!(?impl1_predicates, ?impl2_predicates); @@ -361,12 +352,16 @@ fn check_predicates<'tcx>( // which is sound because we forbid impls like the following // // impl AlwaysApplicable for D { } - let always_applicable_traits = impl1_predicates.iter().copied().filter(|&(predicate, _)| { - matches!( - trait_predicate_kind(tcx, predicate), - Some(TraitSpecializationKind::AlwaysApplicable) - ) - }); + let always_applicable_traits = impl1_predicates + .iter() + .copied() + .filter(|&(predicate, _)| { + matches!( + trait_predicate_kind(tcx, predicate), + Some(TraitSpecializationKind::AlwaysApplicable) + ) + }) + .map(|(pred, _span)| pred); // Include the well-formed predicates of the type parameters of the impl. for arg in tcx.impl_trait_ref(impl1_def_id).unwrap().subst_identity().substs { @@ -380,10 +375,7 @@ fn check_predicates<'tcx>( traits::elaborate_obligations(tcx, obligations).map(|obligation| obligation.predicate), ) } - impl2_predicates.extend( - traits::elaborate_predicates_with_span(tcx, always_applicable_traits) - .map(|obligation| obligation.predicate), - ); + impl2_predicates.extend(traits::elaborate_predicates(tcx, always_applicable_traits)); for (predicate, span) in impl1_predicates { if !impl2_predicates.iter().any(|pred2| trait_predicates_eq(tcx, predicate, *pred2, span)) { diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs index ec391ea80f4..47a8b080166 100644 --- a/compiler/rustc_hir_typeck/src/closure.rs +++ b/compiler/rustc_hir_typeck/src/closure.rs @@ -204,15 +204,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut expected_sig = None; let mut expected_kind = None; - for obligation in traits::elaborate_predicates_with_span( + for (pred, span) in traits::elaborate_predicates_with_span( self.tcx, // Reverse the obligations here, since `elaborate_*` uses a stack, // and we want to keep inference generally in the same order of // the registered obligations. predicates.rev(), ) { - debug!(?obligation.predicate); - let bound_predicate = obligation.predicate.kind(); + debug!(?pred); + let bound_predicate = pred.kind(); // Given a Projection predicate, we can potentially infer // the complete signature. @@ -220,9 +220,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { && let ty::PredicateKind::Clause(ty::Clause::Projection(proj_predicate)) = bound_predicate.skip_binder() { let inferred_sig = self.normalize( - obligation.cause.span, + span, self.deduce_sig_from_projection( - Some(obligation.cause.span), + Some(span), bound_predicate.rebind(proj_predicate), ), ); diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index a0aa43deadc..2762e778591 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -576,17 +576,13 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { traits::elaborate_predicates(self.tcx, predicates.predicates.iter().copied()) // We don't care about regions here. - .filter_map(|obligation| match obligation.predicate.kind().skip_binder() { + .filter_map(|pred| match pred.kind().skip_binder() { ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)) if trait_pred.def_id() == sized_def_id => { let span = predicates .iter() - .find_map( - |(p, span)| { - if p == obligation.predicate { Some(span) } else { None } - }, - ) + .find_map(|(p, span)| if p == pred { Some(span) } else { None }) .unwrap_or(rustc_span::DUMMY_SP); Some((trait_pred, span)) } diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index 0d2faeba5fc..f3797499866 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -74,44 +74,58 @@ pub struct Elaborator<'tcx> { pub fn elaborate_trait_ref<'tcx>( tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>, -) -> Elaborator<'tcx> { +) -> impl Iterator> { elaborate_predicates(tcx, std::iter::once(trait_ref.without_const().to_predicate(tcx))) } pub fn elaborate_trait_refs<'tcx>( tcx: TyCtxt<'tcx>, trait_refs: impl Iterator>, -) -> Elaborator<'tcx> { - let predicates = trait_refs.map(|trait_ref| trait_ref.without_const().to_predicate(tcx)); +) -> impl Iterator> { + let predicates = trait_refs.map(move |trait_ref| trait_ref.without_const().to_predicate(tcx)); elaborate_predicates(tcx, predicates) } pub fn elaborate_predicates<'tcx>( tcx: TyCtxt<'tcx>, predicates: impl Iterator>, -) -> Elaborator<'tcx> { - let obligations = predicates - .map(|predicate| { - predicate_obligation(predicate, ty::ParamEnv::empty(), ObligationCause::dummy()) - }) - .collect(); - elaborate_obligations(tcx, obligations) +) -> impl Iterator> { + elaborate_obligations( + tcx, + predicates + .map(|predicate| { + Obligation::new( + tcx, + // We'll dump the cause/param-env later + ObligationCause::dummy(), + ty::ParamEnv::empty(), + predicate, + ) + }) + .collect(), + ) + .map(|obl| obl.predicate) } pub fn elaborate_predicates_with_span<'tcx>( tcx: TyCtxt<'tcx>, predicates: impl Iterator, Span)>, -) -> Elaborator<'tcx> { - let obligations = predicates - .map(|(predicate, span)| { - predicate_obligation( - predicate, - ty::ParamEnv::empty(), - ObligationCause::dummy_with_span(span), - ) - }) - .collect(); - elaborate_obligations(tcx, obligations) +) -> impl Iterator, Span)> { + elaborate_obligations( + tcx, + predicates + .map(|(predicate, span)| { + Obligation::new( + tcx, + // We'll dump the cause/param-env later + ObligationCause::dummy_with_span(span), + ty::ParamEnv::empty(), + predicate, + ) + }) + .collect(), + ) + .map(|obl| (obl.predicate, obl.cause.span)) } pub fn elaborate_obligations<'tcx>( @@ -141,10 +155,6 @@ impl<'tcx> Elaborator<'tcx> { self.stack.extend(obligations.into_iter().filter(|o| self.visited.insert(o.predicate))); } - pub fn filter_to_traits(self) -> FilterToTraits { - FilterToTraits::new(self) - } - fn elaborate(&mut self, obligation: &PredicateObligation<'tcx>) { let tcx = self.visited.tcx; @@ -325,20 +335,18 @@ impl<'tcx> Iterator for Elaborator<'tcx> { // Supertrait iterator /////////////////////////////////////////////////////////////////////////// -pub type Supertraits<'tcx> = FilterToTraits>; - pub fn supertraits<'tcx>( tcx: TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>, -) -> Supertraits<'tcx> { - elaborate_trait_ref(tcx, trait_ref).filter_to_traits() +) -> impl Iterator> { + FilterToTraits::new(elaborate_trait_ref(tcx, trait_ref)) } pub fn transitive_bounds<'tcx>( tcx: TyCtxt<'tcx>, - bounds: impl Iterator>, -) -> Supertraits<'tcx> { - elaborate_trait_refs(tcx, bounds).filter_to_traits() + trait_refs: impl Iterator>, +) -> impl Iterator> { + FilterToTraits::new(elaborate_trait_refs(tcx, trait_refs)) } /// A specialized variant of `elaborate_trait_refs` that only elaborates trait references that may @@ -393,12 +401,12 @@ impl FilterToTraits { } } -impl<'tcx, I: Iterator>> Iterator for FilterToTraits { +impl<'tcx, I: Iterator>> Iterator for FilterToTraits { type Item = ty::PolyTraitRef<'tcx>; fn next(&mut self) -> Option> { - while let Some(obligation) = self.base_iterator.next() { - if let Some(data) = obligation.predicate.to_opt_poly_trait_pred() { + while let Some(pred) = self.base_iterator.next() { + if let Some(data) = pred.to_opt_poly_trait_pred() { return Some(data.map_bound(|t| t.trait_ref)); } } diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs index faca61fc29b..42e59f92840 100644 --- a/compiler/rustc_lint/src/unused.rs +++ b/compiler/rustc_lint/src/unused.rs @@ -258,11 +258,11 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults { cx.tcx, cx.tcx.explicit_item_bounds(def).iter().cloned(), ) - .find_map(|obligation| { + .find_map(|(pred, _span)| { // We only look at the `DefId`, so it is safe to skip the binder here. if let ty::PredicateKind::Clause(ty::Clause::Trait( ref poly_trait_predicate, - )) = obligation.predicate.kind().skip_binder() + )) = pred.kind().skip_binder() { let def_id = poly_trait_predicate.trait_ref.def_id; diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index c1cf6ee0f9e..e7075d5e791 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -117,7 +117,7 @@ impl<'tcx> MirPass<'tcx> for ConstProp { .filter_map(|(p, _)| if p.is_global() { Some(*p) } else { None }); if traits::impossible_predicates( tcx, - traits::elaborate_predicates(tcx, predicates).map(|o| o.predicate).collect(), + traits::elaborate_predicates(tcx, predicates).collect(), ) { trace!("ConstProp skipped for {:?}: found unsatisfiable predicates", def_id); return; diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index 45bd98f39d2..60401b05492 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -93,7 +93,7 @@ impl<'tcx> MirLint<'tcx> for ConstProp { .filter_map(|(p, _)| if p.is_global() { Some(*p) } else { None }); if traits::impossible_predicates( tcx, - traits::elaborate_predicates(tcx, predicates).map(|o| o.predicate).collect(), + traits::elaborate_predicates(tcx, predicates).collect(), ) { trace!("ConstProp skipped for {:?}: found unsatisfiable predicates", def_id); return; diff --git a/compiler/rustc_trait_selection/src/solve/assembly.rs b/compiler/rustc_trait_selection/src/solve/assembly.rs index 995fec78c40..b2658614fd3 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly.rs @@ -470,7 +470,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { for assumption in elaborate_predicates(tcx, bounds.iter().map(|bound| bound.with_self_ty(tcx, self_ty))) { - match G::consider_object_bound_candidate(self, goal, assumption.predicate) { + match G::consider_object_bound_candidate(self, goal, assumption) { Ok(result) => { candidates.push(Candidate { source: CandidateSource::BuiltinImpl, result }) } diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index 6b3a59b1ed5..878c502655c 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -349,8 +349,7 @@ impl<'tcx> AutoTraitFinder<'tcx> { let normalized_preds = elaborate_predicates( tcx, computed_preds.clone().chain(user_computed_preds.iter().cloned()), - ) - .map(|o| o.predicate); + ); new_env = ty::ParamEnv::new( tcx.mk_predicates_from_iter(normalized_preds), param_env.reveal(), diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 98e00e8223b..03ba125cf2b 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -367,8 +367,8 @@ fn negative_impl_exists<'tcx>( } // Try to prove a negative obligation exists for super predicates - for o in util::elaborate_predicates(infcx.tcx, iter::once(o.predicate)) { - if resolve_negative_obligation(infcx.fork(), &o, body_def_id) { + for pred in util::elaborate_predicates(infcx.tcx, iter::once(o.predicate)) { + if resolve_negative_obligation(infcx.fork(), &o.with(infcx.tcx, pred), body_def_id) { return true; } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs index 84045c4d0ed..672b3365ff4 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs @@ -82,15 +82,15 @@ pub fn recompute_applicable_impls<'tcx>( let predicates = tcx.predicates_of(obligation.cause.body_id.to_def_id()).instantiate_identity(tcx); - for obligation in elaborate_predicates_with_span(tcx, predicates.into_iter()) { - let kind = obligation.predicate.kind(); + for (pred, span) in elaborate_predicates_with_span(tcx, predicates.into_iter()) { + let kind = pred.kind(); if let ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)) = kind.skip_binder() && param_env_candidate_may_apply(kind.rebind(trait_pred)) { if kind.rebind(trait_pred.trait_ref) == ty::TraitRef::identity(tcx, trait_pred.def_id()) { ambiguities.push(Ambiguity::ParamEnv(tcx.def_span(trait_pred.def_id()))) } else { - ambiguities.push(Ambiguity::ParamEnv(obligation.cause.span)) + ambiguities.push(Ambiguity::ParamEnv(span)) } } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 296fd1ed524..c19798213b7 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1624,8 +1624,8 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { } }; - for obligation in super::elaborate_predicates(self.tcx, std::iter::once(cond)) { - let bound_predicate = obligation.predicate.kind(); + for pred in super::elaborate_predicates(self.tcx, std::iter::once(cond)) { + let bound_predicate = pred.kind(); if let ty::PredicateKind::Clause(ty::Clause::Trait(implication)) = bound_predicate.skip_binder() { diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index e8970606704..8d831dca6e3 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -66,7 +66,7 @@ pub use self::util::{expand_trait_aliases, TraitAliasExpander}; pub use self::util::{get_vtable_index_of_object_method, impl_item_is_final, upcast_choices}; pub use self::util::{ supertrait_def_ids, supertraits, transitive_bounds, transitive_bounds_that_define_assoc_type, - SupertraitDefIds, Supertraits, + SupertraitDefIds, }; pub use self::chalk_fulfill::FulfillmentContext as ChalkFulfillmentContext; @@ -267,9 +267,7 @@ pub fn normalize_param_env_or_error<'tcx>( // and errors will get reported then; so outside of type inference we // can be sure that no errors should occur. let mut predicates: Vec<_> = - util::elaborate_predicates(tcx, unnormalized_env.caller_bounds().into_iter()) - .map(|obligation| obligation.predicate) - .collect(); + util::elaborate_predicates(tcx, unnormalized_env.caller_bounds().into_iter()).collect(); debug!("normalize_param_env_or_error: elaborated-predicates={:?}", predicates); diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 5d2af5ff33c..dbf6b78572a 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -379,26 +379,24 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool { // Search for a predicate like `Self : Sized` amongst the trait bounds. let predicates = tcx.predicates_of(def_id); let predicates = predicates.instantiate_identity(tcx).predicates; - elaborate_predicates(tcx, predicates.into_iter()).any(|obligation| { - match obligation.predicate.kind().skip_binder() { - ty::PredicateKind::Clause(ty::Clause::Trait(ref trait_pred)) => { - trait_pred.def_id() == sized_def_id && trait_pred.self_ty().is_param(0) - } - ty::PredicateKind::Clause(ty::Clause::Projection(..)) - | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) - | ty::PredicateKind::Subtype(..) - | ty::PredicateKind::Coerce(..) - | ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..)) - | ty::PredicateKind::WellFormed(..) - | ty::PredicateKind::ObjectSafe(..) - | ty::PredicateKind::ClosureKind(..) - | ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..)) - | ty::PredicateKind::ConstEvaluatable(..) - | ty::PredicateKind::ConstEquate(..) - | ty::PredicateKind::AliasRelate(..) - | ty::PredicateKind::Ambiguous - | ty::PredicateKind::TypeWellFormedFromEnv(..) => false, + elaborate_predicates(tcx, predicates.into_iter()).any(|pred| match pred.kind().skip_binder() { + ty::PredicateKind::Clause(ty::Clause::Trait(ref trait_pred)) => { + trait_pred.def_id() == sized_def_id && trait_pred.self_ty().is_param(0) } + ty::PredicateKind::Clause(ty::Clause::Projection(..)) + | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) + | ty::PredicateKind::Subtype(..) + | ty::PredicateKind::Coerce(..) + | ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..)) + | ty::PredicateKind::WellFormed(..) + | ty::PredicateKind::ObjectSafe(..) + | ty::PredicateKind::ClosureKind(..) + | ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..)) + | ty::PredicateKind::ConstEvaluatable(..) + | ty::PredicateKind::ConstEquate(..) + | ty::PredicateKind::AliasRelate(..) + | ty::PredicateKind::Ambiguous + | ty::PredicateKind::TypeWellFormedFromEnv(..) => false, }) } @@ -669,9 +667,9 @@ fn object_ty_for_trait<'tcx>( debug!(?trait_predicate); let mut elaborated_predicates: Vec<_> = elaborate_trait_ref(tcx, trait_ref) - .filter_map(|obligation| { - debug!(?obligation); - let pred = obligation.predicate.to_opt_poly_projection_pred()?; + .filter_map(|pred| { + debug!(?pred); + let pred = pred.to_opt_poly_projection_pred()?; Some(pred.map_bound(|p| { ty::ExistentialPredicate::Projection(ty::ExistentialProjection::erase_self_ty( tcx, p, diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index ec5bd982a3c..156674e33c3 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -921,9 +921,9 @@ pub(crate) fn required_region_bounds<'tcx>( assert!(!erased_self_ty.has_escaping_bound_vars()); traits::elaborate_predicates(tcx, predicates) - .filter_map(|obligation| { - debug!(?obligation); - match obligation.predicate.kind().skip_binder() { + .filter_map(|pred| { + debug!(?pred); + match pred.kind().skip_binder() { ty::PredicateKind::Clause(ty::Clause::Projection(..)) | ty::PredicateKind::Clause(ty::Clause::Trait(..)) | ty::PredicateKind::Clause(ty::Clause::ConstArgHasType(..)) diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index 1ab81aee7b8..327e090d38b 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -124,9 +124,9 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { let preds = traits::elaborate_predicates(cx.tcx, cx.param_env.caller_bounds().iter()) .filter(|p| !p.is_global()) - .filter_map(|obligation| { + .filter_map(|pred| { // Note that we do not want to deal with qualified predicates here. - match obligation.predicate.kind().no_bound_vars() { + match pred.kind().no_bound_vars() { Some(ty::PredicateKind::Clause(ty::Clause::Trait(pred))) if pred.def_id() != sized_trait => { Some(pred) }, diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 29830557a44..fd06c0b8677 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -2106,7 +2106,6 @@ pub fn fn_has_unsatisfiable_preds(cx: &LateContext<'_>, did: DefId) -> bool { traits::impossible_predicates( cx.tcx, traits::elaborate_predicates(cx.tcx, predicates) - .map(|o| o.predicate) .collect::>(), ) } From dd7db8b1df8fd0f83580f421895c803419365450 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sun, 26 Mar 2023 23:52:59 +0200 Subject: [PATCH 162/346] Limit to one job on mingw builders This is another attempt to work around https://github.com/rust-lang/rust/issues/108227. By limiting to one link job, we should be able to avoid file name clashes in mkstemp(). --- src/ci/run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/run.sh b/src/ci/run.sh index fc4ed57fb82..5f4e4a8e1b4 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -65,7 +65,7 @@ RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set dist.compression-profile=best" # This is an attempt to fix the spurious build error tracked by # https://github.com/rust-lang/rust/issues/108227. if isWindows && [[ ${CUSTOM_MINGW-0} -eq 1 ]]; then - RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set llvm.link-jobs=4" + RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set llvm.link-jobs=1" fi # Only produce xz tarballs on CI. gz tarballs will be generated by the release From 88b3ae96904312c7c0fe9b40357613f9fc29dbc8 Mon Sep 17 00:00:00 2001 From: Lenko Donchev Date: Sun, 26 Mar 2023 15:43:23 -0500 Subject: [PATCH 163/346] check for missing codegen backeng config --- src/bootstrap/compile.rs | 44 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 54971af644c..783061d8ee8 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -20,7 +20,7 @@ use serde_derive::Deserialize; use crate::builder::crate_description; use crate::builder::Cargo; -use crate::builder::{Builder, Kind, RunConfig, ShouldRun, Step}; +use crate::builder::{Builder, Kind, PathSet, RunConfig, ShouldRun, Step, TaskPath}; use crate::cache::{Interned, INTERNER}; use crate::config::{LlvmLibunwind, RustcLto, TargetSelection}; use crate::dist; @@ -995,6 +995,44 @@ pub struct CodegenBackend { pub backend: Interned, } +fn needs_codegen_config(run: &RunConfig<'_>) -> bool { + let mut needs_codegen_cfg = false; + for path_set in &run.paths { + needs_codegen_cfg = match path_set { + PathSet::Set(set) => set.iter().any(|p| is_codegen_cfg_needed(p, run)), + PathSet::Suite(suite) => is_codegen_cfg_needed(&suite, run), + } + } + needs_codegen_cfg +} + +const CODEGEN_BACKEND_PREFIX: &str = "rustc_codegen_"; + +fn is_codegen_cfg_needed(path: &TaskPath, run: &RunConfig<'_>) -> bool { + if path.path.to_str().unwrap().contains(&CODEGEN_BACKEND_PREFIX) { + let mut needs_codegen_backend_config = true; + for &backend in &run.builder.config.rust_codegen_backends { + if path + .path + .to_str() + .unwrap() + .ends_with(&(CODEGEN_BACKEND_PREFIX.to_owned() + &backend)) + { + needs_codegen_backend_config = false; + } + } + if needs_codegen_backend_config { + run.builder.info( + "Warning: no codegen-backends config matched the requested path to build a codegen backend. \ + Help: add backend to codegen-backends in config.toml.", + ); + return true; + } + } + + return false; +} + impl Step for CodegenBackend { type Output = (); const ONLY_HOSTS: bool = true; @@ -1006,6 +1044,10 @@ impl Step for CodegenBackend { } fn make_run(run: RunConfig<'_>) { + if needs_codegen_config(&run) { + return; + } + for &backend in &run.builder.config.rust_codegen_backends { if backend == "llvm" { continue; // Already built as part of rustc From dd5b690fc9fee33e1dd962f2938ad06a55f014ac Mon Sep 17 00:00:00 2001 From: nils <48135649+Nilstrieb@users.noreply.github.com> Date: Mon, 27 Mar 2023 08:26:29 +0200 Subject: [PATCH 164/346] Remove Nilstrieb from review rotation I currently don't have enough time to be on rotation. You can still request a review from me and I may still steal PRs sometimes though. --- triagebot.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/triagebot.toml b/triagebot.toml index 9ffe2e72cab..c86c1613fa9 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -498,7 +498,6 @@ compiler-team-contributors = [ "@eholk", "@jackh726", "@TaKO8Ki", - "@Nilstrieb", "@WaffleLapkin", "@b-naber", ] From 24369232cc93809768fcc376b43201d15914535b Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Mon, 27 Mar 2023 16:06:13 +0800 Subject: [PATCH 165/346] Update cargo 9 commits in 15d090969743630bff549a1b068bcaa8174e5ee3..145219a9f089f8b57c09f40525374fbade1e34ae 2023-03-21 17:54:28 +0000 to 2023-03-27 01:56:36 +0000 - doc(contrib): missing quotation mark (rust-lang/cargo#11894) - Update changelog for 1.68.2 (rust-lang/cargo#11893) - Add the old github keys as revoked (rust-lang/cargo#11889) - Update proptest (rust-lang/cargo#11886) - Added new GitHub RSA Host Key (rust-lang/cargo#11883) - doc: Fix registries.name.index for sparse (rust-lang/cargo#11880) - docs(contrib): Replace architecture with redirects (rust-lang/cargo#11876) - docs: fix typos in `cargo_compile/mod.rs` (rust-lang/cargo#11874) - docs(contrub): Remove unused file (rust-lang/cargo#11873) --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index 15d09096974..145219a9f08 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 15d090969743630bff549a1b068bcaa8174e5ee3 +Subproject commit 145219a9f089f8b57c09f40525374fbade1e34ae From 32189d3d1a499262f5e2af2f9f3cd34f2907dcbd Mon Sep 17 00:00:00 2001 From: Pietro Albini Date: Mon, 27 Mar 2023 13:03:04 +0200 Subject: [PATCH 166/346] backport 1.68.1 and 1.68.2 release notes to master --- RELEASES.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index a26dbbfa4f5..e453b8d6891 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,26 @@ +Version 1.68.2 (2023-03-28) +=========================== + +- [Update the GitHub RSA host key bundled within Cargo](https://github.com/rust-lang/cargo/pull/11883). + The key was [rotated by GitHub](https://github.blog/2023-03-23-we-updated-our-rsa-ssh-host-key/) + on 2023-03-24 after the old one leaked. +- [Mark the old GitHub RSA host key as revoked](https://github.com/rust-lang/cargo/pull/11889). + This will prevent Cargo from accepting the leaked key even when trusted by + the system. +- [Add support for `@revoked` and a better error message for `@cert-authority` in Cargo's SSH host key verification](https://github.com/rust-lang/cargo/pull/11635) + +Version 1.68.1 (2023-03-23) +=========================== + +- [Fix miscompilation in produced Windows MSVC artifacts](https://github.com/rust-lang/rust/pull/109094) + This was introduced by enabling ThinLTO for the distributed rustc which led + to miscompilations in the resulting binary. Currently this is believed to be + limited to the -Zdylib-lto flag used for rustc compilation, rather than a + general bug in ThinLTO, so only rustc artifacts should be affected. +- [Fix --enable-local-rust builds](https://github.com/rust-lang/rust/pull/109111/) +- [Treat `$prefix-clang` as `clang` in linker detection code](https://github.com/rust-lang/rust/pull/109156) +- [Fix panic in compiler code](https://github.com/rust-lang/rust/pull/108162) + Version 1.68.0 (2023-03-09) ========================== From 684e7a5461eda4dee03b9a12d908695ba2f9f27d Mon Sep 17 00:00:00 2001 From: Krasimir Georgiev Date: Mon, 27 Mar 2023 11:12:47 +0000 Subject: [PATCH 167/346] llvm-wrapper: adapt for LLVM API change Adapts the wrapper for the LLVM commit https://github.com/llvm/llvm-project/commit/377e1311d50c7e5b5aab3db081938e0d0ceebdfc. --- .../rustc_llvm/llvm-wrapper/PassWrapper.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index e604e44a715..f2dec8fe327 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -1158,13 +1158,6 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules, // Otherwise, we sometimes lose `static` values -- see #60184. computeDeadSymbolsWithConstProp(Ret->Index, Ret->GUIDPreservedSymbols, deadIsPrevailing, /* ImportEnabled = */ false); - ComputeCrossModuleImport( - Ret->Index, - Ret->ModuleToDefinedGVSummaries, - Ret->ImportLists, - Ret->ExportLists - ); - // Resolve LinkOnce/Weak symbols, this has to be computed early be cause it // impacts the caching. // @@ -1181,6 +1174,16 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules, return true; return Prevailing->second == S; }; + ComputeCrossModuleImport( + Ret->Index, + Ret->ModuleToDefinedGVSummaries, +#if LLVM_VERSION_GE(17, 0) + isPrevailing, +#endif + Ret->ImportLists, + Ret->ExportLists + ); + auto recordNewLinkage = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID, GlobalValue::LinkageTypes NewLinkage) { From 64927b973b6c82889231e54d90a58580d2392b54 Mon Sep 17 00:00:00 2001 From: Raoul Strackx Date: Mon, 27 Mar 2023 11:41:31 +0200 Subject: [PATCH 168/346] Fix LVI test post LLVM 16 update --- .../x86_64-fortanix-unknown-sgx-lvi/cc_plus_one_asm.checks | 2 +- .../x86_64-fortanix-unknown-sgx-lvi/cc_plus_one_c_asm.checks | 2 +- .../x86_64-fortanix-unknown-sgx-lvi/cc_plus_one_cxx_asm.checks | 2 +- .../x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_asm.checks | 2 +- .../x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_c_asm.checks | 2 +- .../cmake_plus_one_cxx_asm.checks | 2 +- .../x86_64-fortanix-unknown-sgx-lvi/unw_getcontext.checks | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/cc_plus_one_asm.checks b/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/cc_plus_one_asm.checks index af9bc8c1d62..d2e53bee08f 100644 --- a/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/cc_plus_one_asm.checks +++ b/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/cc_plus_one_asm.checks @@ -2,6 +2,6 @@ CHECK: cc_plus_one_asm CHECK-NEXT: movl CHECK-NEXT: lfence CHECK-NEXT: incl -CHECK-NEXT: shlq $0, (%rsp) +CHECK-NEXT: shlq $0x0, (%rsp) CHECK-NEXT: lfence CHECK-NEXT: retq diff --git a/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/cc_plus_one_c_asm.checks b/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/cc_plus_one_c_asm.checks index d1fae3d495f..0a3d1dced42 100644 --- a/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/cc_plus_one_c_asm.checks +++ b/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/cc_plus_one_c_asm.checks @@ -6,7 +6,7 @@ CHECK: lfence CHECK: lfence CHECK-NEXT: incl CHECK-NEXT: jmp -CHECK-NEXT: shlq $0, (%rsp) +CHECK-NEXT: shlq $0x0, (%rsp) CHECK-NEXT: lfence CHECK-NEXT: retq CHECK: popq diff --git a/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/cc_plus_one_cxx_asm.checks b/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/cc_plus_one_cxx_asm.checks index e704bf41724..0126cd8ee64 100644 --- a/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/cc_plus_one_cxx_asm.checks +++ b/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/cc_plus_one_cxx_asm.checks @@ -7,7 +7,7 @@ CHECK: lfence CHECK: lfence CHECK-NEXT: incl CHECK-NEXT: jmp 0x{{[[:xdigit:]]+}} -CHECK-NEXT: shlq $0, (%rsp) +CHECK-NEXT: shlq $0x0, (%rsp) CHECK-NEXT: lfence CHECK-NEXT: retq CHECK: popq diff --git a/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_asm.checks b/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_asm.checks index 78b18ccbfcb..61567548848 100644 --- a/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_asm.checks +++ b/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_asm.checks @@ -2,6 +2,6 @@ CHECK: cmake_plus_one_asm CHECK-NEXT: movl CHECK-NEXT: lfence CHECK-NEXT: incl -CHECK-NEXT: shlq $0, (%rsp) +CHECK-NEXT: shlq $0x0, (%rsp) CHECK-NEXT: lfence CHECK-NEXT: retq diff --git a/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_c_asm.checks b/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_c_asm.checks index 87c806f137a..17312b9126a 100644 --- a/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_c_asm.checks +++ b/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_c_asm.checks @@ -7,7 +7,7 @@ CHECK: movl CHECK: lfence CHECK-NEXT: incl CHECK-NEXT: jmp 0x{{[[:xdigit:]]+}} -CHECK-NEXT: shlq $0, (%rsp) +CHECK-NEXT: shlq $0x0, (%rsp) CHECK-NEXT: lfence CHECK-NEXT: retq CHECK: popq diff --git a/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_cxx_asm.checks b/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_cxx_asm.checks index 9cac8711ea8..222e4ef7983 100644 --- a/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_cxx_asm.checks +++ b/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/cmake_plus_one_cxx_asm.checks @@ -7,7 +7,7 @@ CHECK: movl CHECK: lfence CHECK-NEXT: incl CHECK-NEXT: jmp 0x{{[[:xdigit:]]+}} -CHECK-NEXT: shlq $0, (%rsp) +CHECK-NEXT: shlq $0x0, (%rsp) CHECK-NEXT: lfence CHECK-NEXT: retq CHECK: popq diff --git a/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/unw_getcontext.checks b/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/unw_getcontext.checks index 4b7615b115d..b46cf758384 100644 --- a/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/unw_getcontext.checks +++ b/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/unw_getcontext.checks @@ -1,6 +1,6 @@ CHECK: unw_getcontext CHECK: lfence CHECK: lfence -CHECK: shlq $0, (%rsp) +CHECK: shlq $0x0, (%rsp) CHECK-NEXT: lfence CHECK-NEXT: retq From 20ca24e3c59dff52f76f1566c121c134e3a9b287 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 2 Mar 2023 01:48:31 -0600 Subject: [PATCH 169/346] More config.toml.example cleanups - Link to more documentation - Move `changelog-seen` into the "Global Settings" section - Update incorrect comments on `llvm.link-shared` and `rust.debug-assertions` - Use the correct default in the commented-out example more often - Clarify that `docs` and `compiler-docs` only control the default, they're not a hard-off switch. - Document `-vvv` and `local-rebuild` - Minor improvements to doc-comments in config.toml.example This also sets `download-rustc = false`; that was already the default, but it will be helpful in case the default changes (https://jyn.dev/2023/01/12/Bootstrapping-Rust-in-2023.html). --- config.example.toml | 171 +++++++++++++----------- src/bootstrap/defaults/config.user.toml | 4 +- 2 files changed, 94 insertions(+), 81 deletions(-) diff --git a/config.example.toml b/config.example.toml index 32eab76b369..5ef83760aed 100644 --- a/config.example.toml +++ b/config.example.toml @@ -1,7 +1,7 @@ # Sample TOML configuration file for building Rust. # -# To configure rustbuild, copy this file to the directory from which you will be -# running the build, and name it config.toml. +# To configure rustbuild, run `./configure` or `./x.py setup`. +# See https://rustc-dev-guide.rust-lang.org/building/how-to-build-and-run.html#create-a-configtoml for more information. # # All options are commented out by default in this file, and they're commented # out with their default values. The build system by default looks for @@ -9,12 +9,6 @@ # a custom configuration file can also be specified with `--config` to the build # system. -# Keeps track of the last version of `x.py` used. -# If it does not match the version that is currently running, -# `x.py` will prompt you to update it and read the changelog. -# See `src/bootstrap/CHANGELOG.md` for more information. -changelog-seen = 2 - # ============================================================================= # Global Settings # ============================================================================= @@ -25,6 +19,12 @@ changelog-seen = 2 # Note that this has no default value (x.py uses the defaults in `config.toml.example`). #profile = +# Keeps track of the last version of `x.py` used. +# If `changelog-seen` does not match the version that is currently running, +# `x.py` will prompt you to update it and to read the changelog. +# See `src/bootstrap/CHANGELOG.md` for more information. +changelog-seen = 2 + # ============================================================================= # Tweaking how LLVM is compiled # ============================================================================= @@ -33,7 +33,7 @@ changelog-seen = 2 # Whether to use Rust CI built LLVM instead of locally building it. # # Unless you're developing for a target where Rust CI doesn't build a compiler -# toolchain or changing LLVM locally, you probably want to set this to true. +# toolchain or changing LLVM locally, you probably want to leave this enabled. # # All tier 1 targets are currently supported; set this to `"if-available"` if # you are not sure whether you're on a tier 1 target. @@ -42,9 +42,7 @@ changelog-seen = 2 # # Note that many of the LLVM options are not currently supported for # downloading. Currently only the "assertions" option can be toggled. -# -# Defaults to "if-available" when `channel = "dev"` and "false" otherwise. -#download-ci-llvm = "if-available" +#download-ci-llvm = if rust.channel == "dev" { "if-available" } else { false } # Indicates whether the LLVM build is a Release or Debug build #optimize = true @@ -59,6 +57,8 @@ changelog-seen = 2 #release-debuginfo = false # Indicates whether the LLVM assertions are enabled or not +# NOTE: When assertions are disabled, bugs in the integration between rustc and LLVM can lead to +# unsoundness (segfaults, etc.) in the rustc process itself, not just in the generated code. #assertions = false # Indicates whether the LLVM testsuite is enabled in the build or not. Does @@ -70,10 +70,9 @@ changelog-seen = 2 # Indicates whether the LLVM plugin is enabled or not #plugins = false -# Indicates whether ccache is used when building LLVM +# Indicates whether ccache is used when building LLVM. Set to `true` to use the first `ccache` in +# PATH, or set an absolute path to use a specific version. #ccache = false -# or alternatively ... -#ccache = "/path/to/ccache" # When true, link libstdc++ statically into the rustc_llvm. # This is useful if you don't want to use the dynamic version of that @@ -87,11 +86,8 @@ changelog-seen = 2 # Note: this is NOT related to Rust compilation targets. However, as Rust is # dependent on LLVM for code generation, turning targets off here WILL lead to # the resulting rustc being unable to compile for the disabled architectures. -# Also worth pointing out is that, in case support for new targets are added to -# LLVM, enabling them here doesn't mean Rust is automatically gaining said -# support. You'll need to write a target specification at least, and most -# likely, teach rustc about the C ABI of the target. Get in touch with the -# Rust team and file an issue if you need assistance in porting! +# +# To add support for new targets, see https://rustc-dev-guide.rust-lang.org/building/new-target.html. #targets = "AArch64;ARM;BPF;Hexagon;MSP430;Mips;NVPTX;PowerPC;RISCV;Sparc;SystemZ;WebAssembly;X86" # LLVM experimental targets to build support for. These targets are specified in @@ -104,19 +100,18 @@ changelog-seen = 2 # This can be useful when building LLVM with debug info, which significantly # increases the size of binaries and consequently the memory required by # each linker process. -# If absent or 0, linker invocations are treated like any other job and +# If set to 0, linker invocations are treated like any other job and # controlled by rustbuild's -j parameter. #link-jobs = 0 -# When invoking `llvm-config` this configures whether the `--shared` argument is -# passed to prefer linking to shared libraries. -# NOTE: `thin-lto = true` requires this to be `true` and will give an error otherwise. -#link-shared = false +# Whether to build LLVM as a dynamically linked library (as opposed to statically linked). +# Under the hood, this passes `--shared` to llvm-config. +# NOTE: To avoid performing LTO multiple times, we suggest setting this to `true` when `thin-lto` is enabled. +#link-shared = llvm.thin-lto # When building llvm, this configures what is being appended to the version. -# The default is "-rust-$version-$channel", except for dev channel where rustc -# version number is omitted. To use LLVM version as is, provide an empty string. -#version-suffix = "-rust-dev" +# To use LLVM version as is, provide an empty string. +#version-suffix = if rust.channel == "dev" { "-rust-dev" } else { "-rust-$version-$channel" } # On MSVC you can compile LLVM with clang-cl, but the test suite doesn't pass # with clang-cl, so this is special in that it only compiles LLVM with clang-cl. @@ -178,47 +173,58 @@ changelog-seen = 2 # The default stage to use for the `bench` subcommand #bench-stage = 2 -# Build triple for the original snapshot compiler. This must be a compiler that -# nightlies are already produced for. The current platform must be able to run -# binaries of this build triple and the nightly will be used to bootstrap the -# first compiler. +# Build triple for the pre-compiled snapshot compiler. If `rustc` is set, this must match its host +# triple (see `rustc --version --verbose`; cross-compiling the rust build system itself is NOT +# supported). If `rustc` is unset, this must be a platform with pre-compiled host tools +# (https://doc.rust-lang.org/nightly/rustc/platform-support.html). The current platform must be +# able to run binaries of this build triple. # -# Defaults to platform where `x.py` is run. +# If `rustc` is present in path, this defaults to the host it was compiled for. +# Otherwise, `x.py` will try to infer it from the output of `uname`. +# If `uname` is not found in PATH, we assume this is `x86_64-pc-windows-msvc`. +# This may be changed in the future. #build = "x86_64-unknown-linux-gnu" (as an example) -# Which triples to produce a compiler toolchain for. Each of these triples will -# be bootstrapped from the build triple themselves. +# Which triples to produce a compiler toolchain for. Each of these triples will be bootstrapped from +# the build triple themselves. In other words, this is the list of triples for which to build a +# compiler that can RUN on that triple. # -# Defaults to just the build triple. -#host = ["x86_64-unknown-linux-gnu"] (as an example) +# Defaults to just the `build` triple. +#host = [build.build] (list of triples) -# Which triples to build libraries (core/alloc/std/test/proc_macro) for. Each of -# these triples will be bootstrapped from the build triple themselves. +# Which triples to build libraries (core/alloc/std/test/proc_macro) for. Each of these triples will +# be bootstrapped from the build triple themselves. In other words, this is the list of triples for +# which to build a library that can CROSS-COMPILE to that triple. # # Defaults to `host`. If you set this explicitly, you likely want to add all # host triples to this list as well in order for those host toolchains to be # able to compile programs for their native target. -#target = ["x86_64-unknown-linux-gnu"] (as an example) +#target = build.host (list of triples) -# Use this directory to store build artifacts. -# You can use "$ROOT" to indicate the root of the git repository. +# Use this directory to store build artifacts. Paths are relative to the current directory, not to +# the root of the repository. #build-dir = "build" # Instead of downloading the src/stage0.json version of Cargo specified, use # this Cargo binary instead to build all Rust code +# If you set this, you likely want to set `rustc` as well. #cargo = "/path/to/cargo" # Instead of downloading the src/stage0.json version of the compiler # specified, use this rustc binary instead as the stage0 snapshot compiler. +# If you set this, you likely want to set `cargo` as well. #rustc = "/path/to/rustc" -# Instead of download the src/stage0.json version of rustfmt specified, +# Instead of downloading the src/stage0.json version of rustfmt specified, # use this rustfmt binary instead as the stage0 snapshot rustfmt. #rustfmt = "/path/to/rustfmt" -# Flag to specify whether any documentation is built. If false, rustdoc and +# Whether to build documentation by default. If false, rustdoc and # friends will still be compiled but they will not be used to generate any # documentation. +# +# You can still build documentation when this is disabled by explicitly passing paths, +# e.g. `x doc library`. #docs = true # Flag to specify whether CSS, JavaScript, and HTML are minified when @@ -229,8 +235,8 @@ changelog-seen = 2 # Flag to specify whether private items should be included in the library docs. #library-docs-private-items = false -# Indicate whether the compiler should be documented in addition to the standard -# library and facade crates. +# Indicate whether to build compiler documentation by default. +# You can still build documentation when this is disabled by explicitly passing a path: `x doc compiler`. #compiler-docs = false # Indicate whether git submodules are managed and updated automatically. @@ -247,14 +253,14 @@ changelog-seen = 2 # Python interpreter to use for various tasks throughout the build, notably # rustdoc tests, the lldb python interpreter, and some dist bits and pieces. # -# Defaults to the Python interpreter used to execute x.py +# Defaults to the Python interpreter used to execute x.py. #python = "python" # The path to the REUSE executable to use. Note that REUSE is not required in # most cases, as our tooling relies on a cached (and shrinked) copy of the # REUSE output present in the git repository and in our source tarballs. # -# REUSE is only needed if your changes caused the overral licensing of the +# REUSE is only needed if your changes caused the overall licensing of the # repository to change, and the cached copy has to be regenerated. # # Defaults to the "reuse" command in the system path. @@ -264,14 +270,19 @@ changelog-seen = 2 # set that all the Cargo.toml files create, instead of updating it. #locked-deps = false -# Indicate whether the vendored sources are used for Rust dependencies or not +# Indicate whether the vendored sources are used for Rust dependencies or not. +# +# Vendoring requires additional setup. We recommend using the pre-generated source tarballs if you +# want to use vendoring. See +# https://forge.rust-lang.org/infra/other-installation-methods.html#source-code. #vendor = false # Typically the build system will build the Rust compiler twice. The second # compiler, however, will simply use its own libraries to link against. If you # would rather to perform a full bootstrap, compiling the compiler three times, -# then you can set this option to true. You shouldn't ever need to set this -# option to true. +# then you can set this option to true. +# +# This is only useful for verifying that rustc generates reproducible builds. #full-bootstrap = false # Enable a build of the extended Rust tool set which is not only the compiler @@ -300,7 +311,7 @@ changelog-seen = 2 # "rust-demangler", # if profiler = true #] -# Verbosity level: 0 == not verbose, 1 == verbose, 2 == very verbose +# Verbosity level: 0 == not verbose, 1 == verbose, 2 == very verbose, 3 == print environment variables on each rustc invocation #verbose = 0 # Build the sanitizer runtimes @@ -320,11 +331,12 @@ changelog-seen = 2 # Arguments passed to the `./configure` script, used during distcheck. You # probably won't fill this in but rather it's filled in by the `./configure` -# script. +# script. Useful for debugging. #configure-args = [] # Indicates that a local rebuild is occurring instead of a full bootstrap, # essentially skipping stage0 as the local compiler is recompiling itself again. +# Useful for modifying only the stage2 compiler without having to pass `--keep-stage 0` each time. #local-rebuild = false # Print out how long each rustbuild step took (mostly intended for CI and @@ -354,10 +366,10 @@ changelog-seen = 2 # ============================================================================= [install] -# Instead of installing to /usr/local, install to this path instead. +# Where to install the generated toolchain. Must be an absolute path. #prefix = "/usr/local" -# Where to install system configuration files +# Where to install system configuration files. # If this is a relative path, it will get installed in `prefix` above #sysconfdir = "/etc" @@ -411,9 +423,10 @@ changelog-seen = 2 #debug = false # Whether to download the stage 1 and 2 compilers from CI. -# This is mostly useful for tools; if you have changes to `compiler/` they will be ignored. +# This is mostly useful for tools; if you have changes to `compiler/` or `library/` they will be ignored. # -# You can set this to "if-unchanged" to only download if `compiler/` has not been modified. +# Set this to "if-unchanged" to only download if the compiler and standard library have not been modified. +# Set this to `true` to download unconditionally (useful if e.g. you are only changing doc-comments). #download-rustc = false # Number of codegen units to use for each compiler invocation. A value of 0 @@ -429,10 +442,8 @@ changelog-seen = 2 # See https://github.com/rust-lang/rust/issues/83600. #codegen-units-std = codegen-units -# Whether or not debug assertions are enabled for the compiler and standard -# library. Debug assertions control the maximum log level used by rustc. When -# enabled calls to `trace!` and `debug!` macros are preserved in the compiled -# binary, otherwise they are omitted. +# Whether or not debug assertions are enabled for the compiler and standard library. +# These can help find bugs at the cost of a small runtime slowdown. # # Defaults to rust.debug value #debug-assertions = rust.debug (boolean) @@ -444,13 +455,11 @@ changelog-seen = 2 #debug-assertions-std = rust.debug-assertions (boolean) # Whether or not to leave debug! and trace! calls in the rust binary. -# Overrides the `debug-assertions` option, if defined. # # Defaults to rust.debug-assertions value # -# If you see a message from `tracing` saying -# `max_level_info` is enabled and means logging won't be shown, -# set this value to `true`. +# If you see a message from `tracing` saying "some trace filter directives would enable traces that +# are disabled statically" because `max_level_info` is enabled, set this value to `true`. #debug-logging = rust.debug-assertions (boolean) # Whether or not overflow checks are enabled for the compiler and standard @@ -477,18 +486,16 @@ changelog-seen = 2 # # Note that debuginfo-level = 2 generates several gigabytes of debuginfo # and will slow down the linking process significantly. -# -# Defaults to 1 if debug is true -#debuginfo-level = 0 +#debuginfo-level = if rust.debug { 1 } else { 0 } # Debuginfo level for the compiler. -#debuginfo-level-rustc = debuginfo-level +#debuginfo-level-rustc = rust.debuginfo-level # Debuginfo level for the standard library. -#debuginfo-level-std = debuginfo-level +#debuginfo-level-std = rust.debuginfo-level # Debuginfo level for the tools. -#debuginfo-level-tools = debuginfo-level +#debuginfo-level-tools = rust.debuginfo-level # Debuginfo level for the test suites run with compiletest. # FIXME(#61117): Some tests fail when this option is enabled. @@ -520,6 +527,7 @@ changelog-seen = 2 # Build a multi-threaded rustc # FIXME(#75760): Some UI tests fail when this option is enabled. +# NOTE: This option is NOT SUPPORTED. See #48685. #parallel-compiler = false # The default linker that will be hard-coded into the generated @@ -546,7 +554,7 @@ changelog-seen = 2 # upstream Rust you need to set this to "". However, note that if you are not # actually compatible -- for example if you've backported patches that change # behavior -- this may lead to miscompilations or other bugs. -#description = (string) +#description = "" # The root location of the musl installation directory. The library directory # will also need to contain libunwind.a for an unwinding implementation. Note @@ -575,14 +583,16 @@ changelog-seen = 2 # Flag indicating whether git info will be retrieved from .git automatically. # Having the git information can cause a lot of rebuilds during development. -# Note: If this attribute is not explicitly set (e.g. if left commented out) it -# will default to true if channel = "dev", but will default to false otherwise. -#ignore-git = if channel == "dev" { true } else { false } +# +# FIXME(#76720): this can causes bugs if different compilers reuse the same metadata cache. +#ignore-git = if rust.channel == "dev" { true } else { false } -# When creating source tarballs whether or not to create a source tarball. +# Whether to create a source tarball by default when running `x dist`. +# +# You can still build a source tarball when this is disabled by explicitly passing `x dist rustc-src`. #dist-src = true -# After building or testing extended tools (e.g. clippy and rustfmt), append the +# After building or testing an optional component (e.g. the nomicon or reference), append the # result (broken, compiling, testing) into this JSON file. #save-toolstates = (path) @@ -624,11 +634,12 @@ changelog-seen = 2 # will make code compile faster at the expense of lower runtime performance. #thin-lto-import-instr-limit = if incremental { 10 } else { LLVM default (currently 100) } -# Map debuginfo paths to `/rust/$sha/...`, generally only set for releases +# Map debuginfo paths to `/rust/$sha/...`. +# Useful for reproducible builds. Generally only set for releases #remap-debuginfo = false -# Link the compiler against `jemalloc`, where on Linux and OSX it should -# override the default allocator for rustc and LLVM. +# Link the compiler and LLVM against `jemalloc` instead of the default libc allocator. +# This option is only tested on Linux and OSX. #jemalloc = false # Run tests in various test suites with the "nll compare mode" in addition to diff --git a/src/bootstrap/defaults/config.user.toml b/src/bootstrap/defaults/config.user.toml index ee271c3fb51..25d9e649f23 100644 --- a/src/bootstrap/defaults/config.user.toml +++ b/src/bootstrap/defaults/config.user.toml @@ -8,9 +8,11 @@ doc-stage = 2 # When compiling from source, you usually want all tools. extended = true +# Most users installing from source want to build all parts of the project from source. [llvm] -# Most users installing from source want to build all parts of the project from source, not just rustc itself. download-ci-llvm = false +[rust] +download-rustc = false [dist] # Use better compression when preparing tarballs. From 69db91b8b25de51633ac9f089cd7fb10a58c2b2a Mon Sep 17 00:00:00 2001 From: The 8472 Date: Sun, 26 Dec 2021 03:21:54 +0100 Subject: [PATCH 170/346] Change advance(_back)_by to return `usize` instead of `Result<(), usize>` A successful advance is now signalled by returning `0` and other values now represent the remaining number of steps that couldn't be advanced as opposed to the amount of steps that have been advanced during a partial advance_by. This simplifies adapters a bit, replacing some `match`/`if` with arithmetic. Whether this is beneficial overall depends on whether `advance_by` is mostly used as a building-block for other iterator methods and adapters or whether we also see uses by users where `Result` might be more useful. --- .../src/collections/vec_deque/into_iter.rs | 12 ++--- .../alloc/src/collections/vec_deque/iter.rs | 25 +++++---- .../src/collections/vec_deque/iter_mut.rs | 25 +++++---- library/alloc/src/vec/into_iter.rs | 14 ++--- library/alloc/tests/vec.rs | 21 ++++---- library/core/src/array/iter.rs | 14 +++-- .../core/src/iter/adapters/by_ref_sized.rs | 4 +- library/core/src/iter/adapters/chain.rs | 54 ++++++++----------- library/core/src/iter/adapters/copied.rs | 4 +- library/core/src/iter/adapters/cycle.rs | 21 ++++---- library/core/src/iter/adapters/enumerate.rs | 17 ++---- library/core/src/iter/adapters/flatten.rs | 28 +++++----- library/core/src/iter/adapters/rev.rs | 4 +- library/core/src/iter/adapters/skip.rs | 47 ++++++---------- library/core/src/iter/adapters/take.rs | 29 ++++------ library/core/src/iter/range.rs | 24 ++++----- library/core/src/iter/sources/repeat.rs | 8 +-- library/core/src/iter/sources/repeat_n.rs | 8 +-- library/core/src/iter/traits/double_ended.rs | 28 +++++----- library/core/src/iter/traits/iterator.rs | 28 +++++----- library/core/src/ops/index_range.rs | 14 +++-- library/core/src/slice/iter/macros.rs | 8 +-- library/core/tests/array.rs | 34 ++++++------ library/core/tests/iter/adapters/chain.rs | 40 +++++++------- library/core/tests/iter/adapters/flatten.rs | 45 ++++++++-------- library/core/tests/iter/adapters/skip.rs | 15 +++--- library/core/tests/iter/adapters/take.rs | 22 ++++---- library/core/tests/iter/range.rs | 18 +++---- library/core/tests/iter/traits/iterator.rs | 32 +++++------ library/core/tests/slice.rs | 20 +++---- 30 files changed, 313 insertions(+), 350 deletions(-) diff --git a/library/alloc/src/collections/vec_deque/into_iter.rs b/library/alloc/src/collections/vec_deque/into_iter.rs index 34bc0ce9177..8ba963b790d 100644 --- a/library/alloc/src/collections/vec_deque/into_iter.rs +++ b/library/alloc/src/collections/vec_deque/into_iter.rs @@ -54,14 +54,14 @@ impl Iterator for IntoIter { } #[inline] - fn advance_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_by(&mut self, n: usize) -> usize { if self.inner.len < n { let len = self.inner.len; self.inner.clear(); - Err(len) + len - n } else { self.inner.drain(..n); - Ok(()) + 0 } } @@ -182,14 +182,14 @@ impl DoubleEndedIterator for IntoIter { } #[inline] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_back_by(&mut self, n: usize) -> usize { let len = self.inner.len; if len >= n { self.inner.truncate(len - n); - Ok(()) + 0 } else { self.inner.clear(); - Err(len) + n - len } } diff --git a/library/alloc/src/collections/vec_deque/iter.rs b/library/alloc/src/collections/vec_deque/iter.rs index d9f3937144d..5b91c1635f0 100644 --- a/library/alloc/src/collections/vec_deque/iter.rs +++ b/library/alloc/src/collections/vec_deque/iter.rs @@ -55,13 +55,13 @@ impl<'a, T> Iterator for Iter<'a, T> { } } - fn advance_by(&mut self, n: usize) -> Result<(), usize> { - let m = match self.i1.advance_by(n) { - Ok(_) => return Ok(()), - Err(m) => m, - }; + fn advance_by(&mut self, n: usize) -> usize { + let remaining = self.i1.advance_by(n); + if remaining == 0 { + return 0; + } mem::swap(&mut self.i1, &mut self.i2); - self.i1.advance_by(n - m).map_err(|o| o + m) + self.i1.advance_by(remaining) } #[inline] @@ -125,14 +125,13 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> { } } - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { - let m = match self.i2.advance_back_by(n) { - Ok(_) => return Ok(()), - Err(m) => m, - }; - + fn advance_back_by(&mut self, n: usize) -> usize { + let remaining = self.i2.advance_back_by(n); + if remaining == 0 { + return 0; + } mem::swap(&mut self.i1, &mut self.i2); - self.i2.advance_back_by(n - m).map_err(|o| m + o) + self.i2.advance_back_by(remaining) } fn rfold(self, accum: Acc, mut f: F) -> Acc diff --git a/library/alloc/src/collections/vec_deque/iter_mut.rs b/library/alloc/src/collections/vec_deque/iter_mut.rs index 2c59d95cd53..848cb3649c8 100644 --- a/library/alloc/src/collections/vec_deque/iter_mut.rs +++ b/library/alloc/src/collections/vec_deque/iter_mut.rs @@ -47,13 +47,13 @@ impl<'a, T> Iterator for IterMut<'a, T> { } } - fn advance_by(&mut self, n: usize) -> Result<(), usize> { - let m = match self.i1.advance_by(n) { - Ok(_) => return Ok(()), - Err(m) => m, - }; + fn advance_by(&mut self, n: usize) -> usize { + let remaining = self.i1.advance_by(n); + if remaining == 0 { + return 0; + } mem::swap(&mut self.i1, &mut self.i2); - self.i1.advance_by(n - m).map_err(|o| o + m) + self.i1.advance_by(remaining) } #[inline] @@ -117,14 +117,13 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, T> { } } - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { - let m = match self.i2.advance_back_by(n) { - Ok(_) => return Ok(()), - Err(m) => m, - }; - + fn advance_back_by(&mut self, n: usize) -> usize { + let remaining = self.i2.advance_back_by(n); + if remaining == 0 { + return 0; + } mem::swap(&mut self.i1, &mut self.i2); - self.i2.advance_back_by(n - m).map_err(|o| m + o) + self.i2.advance_back_by(remaining) } fn rfold(self, accum: Acc, mut f: F) -> Acc diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index f6525eb9003..504ca4333be 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -213,7 +213,7 @@ impl Iterator for IntoIter { } #[inline] - fn advance_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_by(&mut self, n: usize) -> usize { let step_size = self.len().min(n); let to_drop = ptr::slice_from_raw_parts_mut(self.ptr as *mut T, step_size); if T::IS_ZST { @@ -227,10 +227,7 @@ impl Iterator for IntoIter { unsafe { ptr::drop_in_place(to_drop); } - if step_size < n { - return Err(step_size); - } - Ok(()) + n - step_size } #[inline] @@ -313,7 +310,7 @@ impl DoubleEndedIterator for IntoIter { } #[inline] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_back_by(&mut self, n: usize) -> usize { let step_size = self.len().min(n); if T::IS_ZST { // SAFETY: same as for advance_by() @@ -327,10 +324,7 @@ impl DoubleEndedIterator for IntoIter { unsafe { ptr::drop_in_place(to_drop); } - if step_size < n { - return Err(step_size); - } - Ok(()) + n - step_size } } diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index 2f07c2911a5..e00af189fbf 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -1,4 +1,5 @@ use core::alloc::{Allocator, Layout}; +use core::assert_eq; use core::iter::IntoIterator; use core::ptr::NonNull; use std::alloc::System; @@ -1062,21 +1063,21 @@ fn test_into_iter_leak() { #[test] fn test_into_iter_advance_by() { - let mut i = [1, 2, 3, 4, 5].into_iter(); - i.advance_by(0).unwrap(); - i.advance_back_by(0).unwrap(); + let mut i = vec![1, 2, 3, 4, 5].into_iter(); + assert_eq!(i.advance_by(0), 0); + assert_eq!(i.advance_back_by(0), 0); assert_eq!(i.as_slice(), [1, 2, 3, 4, 5]); - i.advance_by(1).unwrap(); - i.advance_back_by(1).unwrap(); + assert_eq!(i.advance_by(1), 0); + assert_eq!(i.advance_back_by(1), 0); assert_eq!(i.as_slice(), [2, 3, 4]); - assert_eq!(i.advance_back_by(usize::MAX), Err(3)); + assert_eq!(i.advance_back_by(usize::MAX), usize::MAX - 3); - assert_eq!(i.advance_by(usize::MAX), Err(0)); + assert_eq!(i.advance_by(usize::MAX), usize::MAX); - i.advance_by(0).unwrap(); - i.advance_back_by(0).unwrap(); + assert_eq!(i.advance_by(0), 0); + assert_eq!(i.advance_back_by(0), 0); assert_eq!(i.len(), 0); } @@ -1124,7 +1125,7 @@ fn test_into_iter_zst() { for _ in vec![C; 5].into_iter().rev() {} let mut it = vec![C, C].into_iter(); - it.advance_by(1).unwrap(); + assert_eq!(it.advance_by(1), 0); drop(it); let mut it = vec![C, C].into_iter(); diff --git a/library/core/src/array/iter.rs b/library/core/src/array/iter.rs index 8259c087d22..2d853dd6684 100644 --- a/library/core/src/array/iter.rs +++ b/library/core/src/array/iter.rs @@ -284,12 +284,11 @@ impl Iterator for IntoIter { self.next_back() } - fn advance_by(&mut self, n: usize) -> Result<(), usize> { - let original_len = self.len(); - + fn advance_by(&mut self, n: usize) -> usize { // This also moves the start, which marks them as conceptually "dropped", // so if anything goes bad then our drop impl won't double-free them. let range_to_drop = self.alive.take_prefix(n); + let remaining = n - range_to_drop.len(); // SAFETY: These elements are currently initialized, so it's fine to drop them. unsafe { @@ -297,7 +296,7 @@ impl Iterator for IntoIter { ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(slice)); } - if n > original_len { Err(original_len) } else { Ok(()) } + remaining } } @@ -334,12 +333,11 @@ impl DoubleEndedIterator for IntoIter { }) } - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { - let original_len = self.len(); - + fn advance_back_by(&mut self, n: usize) -> usize { // This also moves the end, which marks them as conceptually "dropped", // so if anything goes bad then our drop impl won't double-free them. let range_to_drop = self.alive.take_suffix(n); + let remaining = n - range_to_drop.len(); // SAFETY: These elements are currently initialized, so it's fine to drop them. unsafe { @@ -347,7 +345,7 @@ impl DoubleEndedIterator for IntoIter { ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(slice)); } - if n > original_len { Err(original_len) } else { Ok(()) } + remaining } } diff --git a/library/core/src/iter/adapters/by_ref_sized.rs b/library/core/src/iter/adapters/by_ref_sized.rs index 477e7117c3e..ff28e5760d0 100644 --- a/library/core/src/iter/adapters/by_ref_sized.rs +++ b/library/core/src/iter/adapters/by_ref_sized.rs @@ -26,7 +26,7 @@ impl Iterator for ByRefSized<'_, I> { } #[inline] - fn advance_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_by(&mut self, n: usize) -> usize { I::advance_by(self.0, n) } @@ -62,7 +62,7 @@ impl DoubleEndedIterator for ByRefSized<'_, I> { } #[inline] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_back_by(&mut self, n: usize) -> usize { I::advance_back_by(self.0, n) } diff --git a/library/core/src/iter/adapters/chain.rs b/library/core/src/iter/adapters/chain.rs index d4b2640e81d..965a33de1cd 100644 --- a/library/core/src/iter/adapters/chain.rs +++ b/library/core/src/iter/adapters/chain.rs @@ -95,38 +95,33 @@ where } #[inline] - fn advance_by(&mut self, n: usize) -> Result<(), usize> { - let mut rem = n; - + fn advance_by(&mut self, mut n: usize) -> usize { if let Some(ref mut a) = self.a { - match a.advance_by(rem) { - Ok(()) => return Ok(()), - Err(k) => rem -= k, + n = a.advance_by(n); + if n == 0 { + return n; } self.a = None; } if let Some(ref mut b) = self.b { - match b.advance_by(rem) { - Ok(()) => return Ok(()), - Err(k) => rem -= k, - } + n = b.advance_by(n); // we don't fuse the second iterator } - if rem == 0 { Ok(()) } else { Err(n - rem) } + n } #[inline] fn nth(&mut self, mut n: usize) -> Option { if let Some(ref mut a) = self.a { - match a.advance_by(n) { - Ok(()) => match a.next() { - None => n = 0, + n = match a.advance_by(n) { + 0 => match a.next() { + None => 0, x => return x, }, - Err(k) => n -= k, - } + k => k, + }; self.a = None; } @@ -186,38 +181,33 @@ where } #[inline] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { - let mut rem = n; - + fn advance_back_by(&mut self, mut n: usize) -> usize { if let Some(ref mut b) = self.b { - match b.advance_back_by(rem) { - Ok(()) => return Ok(()), - Err(k) => rem -= k, + n = b.advance_back_by(n); + if n == 0 { + return n; } self.b = None; } if let Some(ref mut a) = self.a { - match a.advance_back_by(rem) { - Ok(()) => return Ok(()), - Err(k) => rem -= k, - } + n = a.advance_back_by(n); // we don't fuse the second iterator } - if rem == 0 { Ok(()) } else { Err(n - rem) } + n } #[inline] fn nth_back(&mut self, mut n: usize) -> Option { if let Some(ref mut b) = self.b { - match b.advance_back_by(n) { - Ok(()) => match b.next_back() { - None => n = 0, + n = match b.advance_back_by(n) { + 0 => match b.next_back() { + None => 0, x => return x, }, - Err(k) => n -= k, - } + k => k, + }; self.b = None; } diff --git a/library/core/src/iter/adapters/copied.rs b/library/core/src/iter/adapters/copied.rs index a076ab925e3..7533de588db 100644 --- a/library/core/src/iter/adapters/copied.rs +++ b/library/core/src/iter/adapters/copied.rs @@ -89,7 +89,7 @@ where } #[inline] - fn advance_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_by(&mut self, n: usize) -> usize { self.it.advance_by(n) } @@ -130,7 +130,7 @@ where } #[inline] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_back_by(&mut self, n: usize) -> usize { self.it.advance_back_by(n) } } diff --git a/library/core/src/iter/adapters/cycle.rs b/library/core/src/iter/adapters/cycle.rs index 02b5939072e..2d1fcf667bf 100644 --- a/library/core/src/iter/adapters/cycle.rs +++ b/library/core/src/iter/adapters/cycle.rs @@ -81,23 +81,22 @@ where #[inline] #[rustc_inherit_overflow_checks] - fn advance_by(&mut self, n: usize) -> Result<(), usize> { - let mut rem = n; - match self.iter.advance_by(rem) { - ret @ Ok(_) => return ret, - Err(advanced) => rem -= advanced, + fn advance_by(&mut self, n: usize) -> usize { + let mut n = self.iter.advance_by(n); + if n == 0 { + return n; } - while rem > 0 { + while n > 0 { self.iter = self.orig.clone(); - match self.iter.advance_by(rem) { - ret @ Ok(_) => return ret, - Err(0) => return Err(n - rem), - Err(advanced) => rem -= advanced, + let rem = self.iter.advance_by(n); + if rem == n { + return n; } + n = rem; } - Ok(()) + 0 } // No `fold` override, because `fold` doesn't make much sense for `Cycle`, diff --git a/library/core/src/iter/adapters/enumerate.rs b/library/core/src/iter/adapters/enumerate.rs index 8c32a35a12f..30017d13a6c 100644 --- a/library/core/src/iter/adapters/enumerate.rs +++ b/library/core/src/iter/adapters/enumerate.rs @@ -114,17 +114,10 @@ where #[inline] #[rustc_inherit_overflow_checks] - fn advance_by(&mut self, n: usize) -> Result<(), usize> { - match self.iter.advance_by(n) { - ret @ Ok(_) => { - self.count += n; - ret - } - ret @ Err(advanced) => { - self.count += advanced; - ret - } - } + fn advance_by(&mut self, n: usize) -> usize { + let n = self.iter.advance_by(n); + self.count += n; + n } #[rustc_inherit_overflow_checks] @@ -208,7 +201,7 @@ where } #[inline] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_back_by(&mut self, n: usize) -> usize { // we do not need to update the count since that only tallies the number of items // consumed from the front. consuming items from the back can never reduce that. self.iter.advance_back_by(n) diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs index e4020c45f71..980c4bebc97 100644 --- a/library/core/src/iter/adapters/flatten.rs +++ b/library/core/src/iter/adapters/flatten.rs @@ -75,7 +75,7 @@ where } #[inline] - fn advance_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_by(&mut self, n: usize) -> usize { self.inner.advance_by(n) } @@ -120,7 +120,7 @@ where } #[inline] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_back_by(&mut self, n: usize) -> usize { self.inner.advance_back_by(n) } } @@ -236,7 +236,7 @@ where } #[inline] - fn advance_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_by(&mut self, n: usize) -> usize { self.inner.advance_by(n) } @@ -281,7 +281,7 @@ where } #[inline] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_back_by(&mut self, n: usize) -> usize { self.inner.advance_back_by(n) } } @@ -552,19 +552,19 @@ where #[inline] #[rustc_inherit_overflow_checks] - fn advance_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_by(&mut self, n: usize) -> usize { #[inline] #[rustc_inherit_overflow_checks] fn advance(n: usize, iter: &mut U) -> ControlFlow<(), usize> { match iter.advance_by(n) { - Ok(()) => ControlFlow::Break(()), - Err(advanced) => ControlFlow::Continue(n - advanced), + 0 => ControlFlow::Break(()), + remaining => ControlFlow::Continue(remaining), } } match self.iter_try_fold(n, advance) { - ControlFlow::Continue(remaining) if remaining > 0 => Err(n - remaining), - _ => Ok(()), + ControlFlow::Continue(remaining) => remaining, + _ => 0, } } @@ -642,19 +642,19 @@ where #[inline] #[rustc_inherit_overflow_checks] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_back_by(&mut self, n: usize) -> usize { #[inline] #[rustc_inherit_overflow_checks] fn advance(n: usize, iter: &mut U) -> ControlFlow<(), usize> { match iter.advance_back_by(n) { - Ok(()) => ControlFlow::Break(()), - Err(advanced) => ControlFlow::Continue(n - advanced), + 0 => ControlFlow::Break(()), + remaining => ControlFlow::Continue(remaining), } } match self.iter_try_rfold(n, advance) { - ControlFlow::Continue(remaining) if remaining > 0 => Err(n - remaining), - _ => Ok(()), + ControlFlow::Continue(remaining) => remaining, + _ => 0, } } } diff --git a/library/core/src/iter/adapters/rev.rs b/library/core/src/iter/adapters/rev.rs index 8ae6d96fde4..b64baf838a2 100644 --- a/library/core/src/iter/adapters/rev.rs +++ b/library/core/src/iter/adapters/rev.rs @@ -38,7 +38,7 @@ where } #[inline] - fn advance_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_by(&mut self, n: usize) -> usize { self.iter.advance_back_by(n) } @@ -83,7 +83,7 @@ where } #[inline] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_back_by(&mut self, n: usize) -> usize { self.iter.advance_by(n) } diff --git a/library/core/src/iter/adapters/skip.rs b/library/core/src/iter/adapters/skip.rs index c6334880db5..bb32e19b542 100644 --- a/library/core/src/iter/adapters/skip.rs +++ b/library/core/src/iter/adapters/skip.rs @@ -128,34 +128,21 @@ where #[inline] #[rustc_inherit_overflow_checks] - fn advance_by(&mut self, n: usize) -> Result<(), usize> { - let mut rem = n; - let step_one = self.n.saturating_add(rem); + fn advance_by(&mut self, mut n: usize) -> usize { + let skip_inner = self.n; + let skip_and_advance = skip_inner.saturating_add(n); - match self.iter.advance_by(step_one) { - Ok(_) => { - rem -= step_one - self.n; - self.n = 0; - } - Err(advanced) => { - let advanced_without_skip = advanced.saturating_sub(self.n); - self.n = self.n.saturating_sub(advanced); - return if n == 0 { Ok(()) } else { Err(advanced_without_skip) }; - } + let remainder = self.iter.advance_by(skip_and_advance); + let advanced_inner = skip_and_advance - remainder; + n -= advanced_inner.saturating_sub(skip_inner); + self.n = self.n.saturating_sub(advanced_inner); + + // skip_and_advance may have saturated + if unlikely(remainder == 0 && n > 0) { + n = self.iter.advance_by(n); } - // step_one calculation may have saturated - if unlikely(rem > 0) { - return match self.iter.advance_by(rem) { - ret @ Ok(_) => ret, - Err(advanced) => { - rem -= advanced; - Err(n - rem) - } - }; - } - - Ok(()) + n } } @@ -209,13 +196,13 @@ where impl_fold_via_try_fold! { rfold -> try_rfold } #[inline] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_back_by(&mut self, n: usize) -> usize { let min = crate::cmp::min(self.len(), n); - return match self.iter.advance_back_by(min) { - ret @ Ok(_) if n <= min => ret, - Ok(_) => Err(min), - _ => panic!("ExactSizeIterator contract violation"), + let rem = self.iter.advance_back_by(min); + if rem != 0 { + panic!("ExactSizeIterator contract violation"); }; + n - min } } diff --git a/library/core/src/iter/adapters/take.rs b/library/core/src/iter/adapters/take.rs index d947c7b0e30..12e2395fe68 100644 --- a/library/core/src/iter/adapters/take.rs +++ b/library/core/src/iter/adapters/take.rs @@ -121,18 +121,12 @@ where #[inline] #[rustc_inherit_overflow_checks] - fn advance_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_by(&mut self, n: usize) -> usize { let min = self.n.min(n); - match self.iter.advance_by(min) { - Ok(_) => { - self.n -= min; - if min < n { Err(min) } else { Ok(()) } - } - ret @ Err(advanced) => { - self.n -= advanced; - ret - } - } + let rem = self.iter.advance_by(min); + let advanced = min - rem; + self.n -= advanced; + n - advanced } } @@ -223,7 +217,7 @@ where #[inline] #[rustc_inherit_overflow_checks] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_back_by(&mut self, n: usize) -> usize { // The amount by which the inner iterator needs to be shortened for it to be // at most as long as the take() amount. let trim_inner = self.iter.len().saturating_sub(self.n); @@ -232,12 +226,11 @@ where // about having to advance more than usize::MAX here. let advance_by = trim_inner.saturating_add(n); - let advanced = match self.iter.advance_back_by(advance_by) { - Ok(_) => advance_by - trim_inner, - Err(advanced) => advanced - trim_inner, - }; - self.n -= advanced; - return if advanced < n { Err(advanced) } else { Ok(()) }; + let remainder = self.iter.advance_back_by(advance_by); + let advanced_by_inner = advance_by - remainder; + let advanced_by = advanced_by_inner - trim_inner; + self.n -= advanced_by; + n - advanced_by } } diff --git a/library/core/src/iter/range.rs b/library/core/src/iter/range.rs index f19636fba5d..63c719f8b3a 100644 --- a/library/core/src/iter/range.rs +++ b/library/core/src/iter/range.rs @@ -530,12 +530,12 @@ trait RangeIteratorImpl { // Iterator fn spec_next(&mut self) -> Option; fn spec_nth(&mut self, n: usize) -> Option; - fn spec_advance_by(&mut self, n: usize) -> Result<(), usize>; + fn spec_advance_by(&mut self, n: usize) -> usize; // DoubleEndedIterator fn spec_next_back(&mut self) -> Option; fn spec_nth_back(&mut self, n: usize) -> Option; - fn spec_advance_back_by(&mut self, n: usize) -> Result<(), usize>; + fn spec_advance_back_by(&mut self, n: usize) -> usize; } impl const RangeIteratorImpl for ops::Range { @@ -567,7 +567,7 @@ impl const RangeIteratorImpl for ops::Range } #[inline] - default fn spec_advance_by(&mut self, n: usize) -> Result<(), usize> { + default fn spec_advance_by(&mut self, n: usize) -> usize { let available = if self.start <= self.end { Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX) } else { @@ -579,7 +579,7 @@ impl const RangeIteratorImpl for ops::Range self.start = Step::forward_checked(self.start.clone(), taken).expect("`Step` invariants not upheld"); - if taken < n { Err(taken) } else { Ok(()) } + n - taken } #[inline] @@ -608,7 +608,7 @@ impl const RangeIteratorImpl for ops::Range } #[inline] - default fn spec_advance_back_by(&mut self, n: usize) -> Result<(), usize> { + default fn spec_advance_back_by(&mut self, n: usize) -> usize { let available = if self.start <= self.end { Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX) } else { @@ -620,7 +620,7 @@ impl const RangeIteratorImpl for ops::Range self.end = Step::backward_checked(self.end.clone(), taken).expect("`Step` invariants not upheld"); - if taken < n { Err(taken) } else { Ok(()) } + n - taken } } @@ -651,7 +651,7 @@ impl const RangeIteratorImpl for ops::R } #[inline] - fn spec_advance_by(&mut self, n: usize) -> Result<(), usize> { + fn spec_advance_by(&mut self, n: usize) -> usize { let available = if self.start <= self.end { Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX) } else { @@ -666,7 +666,7 @@ impl const RangeIteratorImpl for ops::R // Otherwise 0 is returned which always safe to use. self.start = unsafe { Step::forward_unchecked(self.start.clone(), taken) }; - if taken < n { Err(taken) } else { Ok(()) } + n - taken } #[inline] @@ -695,7 +695,7 @@ impl const RangeIteratorImpl for ops::R } #[inline] - fn spec_advance_back_by(&mut self, n: usize) -> Result<(), usize> { + fn spec_advance_back_by(&mut self, n: usize) -> usize { let available = if self.start <= self.end { Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX) } else { @@ -707,7 +707,7 @@ impl const RangeIteratorImpl for ops::R // SAFETY: same as the spec_advance_by() implementation self.end = unsafe { Step::backward_unchecked(self.end.clone(), taken) }; - if taken < n { Err(taken) } else { Ok(()) } + n - taken } } @@ -757,7 +757,7 @@ impl const Iterator for ops::Range { } #[inline] - fn advance_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_by(&mut self, n: usize) -> usize { self.spec_advance_by(n) } @@ -836,7 +836,7 @@ impl const DoubleEndedIterator for ops::Range< } #[inline] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_back_by(&mut self, n: usize) -> usize { self.spec_advance_back_by(n) } } diff --git a/library/core/src/iter/sources/repeat.rs b/library/core/src/iter/sources/repeat.rs index 733142ed011..56a6d973705 100644 --- a/library/core/src/iter/sources/repeat.rs +++ b/library/core/src/iter/sources/repeat.rs @@ -80,10 +80,10 @@ impl Iterator for Repeat { } #[inline] - fn advance_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_by(&mut self, n: usize) -> usize { // Advancing an infinite iterator of a single element is a no-op. let _ = n; - Ok(()) + 0 } #[inline] @@ -109,10 +109,10 @@ impl DoubleEndedIterator for Repeat { } #[inline] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_back_by(&mut self, n: usize) -> usize { // Advancing an infinite iterator of a single element is a no-op. let _ = n; - Ok(()) + 0 } #[inline] diff --git a/library/core/src/iter/sources/repeat_n.rs b/library/core/src/iter/sources/repeat_n.rs index dc61d6065b8..918f2a36ed0 100644 --- a/library/core/src/iter/sources/repeat_n.rs +++ b/library/core/src/iter/sources/repeat_n.rs @@ -137,7 +137,7 @@ impl Iterator for RepeatN { } #[inline] - fn advance_by(&mut self, skip: usize) -> Result<(), usize> { + fn advance_by(&mut self, skip: usize) -> usize { let len = self.count; if skip >= len { @@ -145,10 +145,10 @@ impl Iterator for RepeatN { } if skip > len { - Err(len) + skip - len } else { self.count = len - skip; - Ok(()) + 0 } } @@ -178,7 +178,7 @@ impl DoubleEndedIterator for RepeatN { } #[inline] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_back_by(&mut self, n: usize) -> usize { self.advance_by(n) } diff --git a/library/core/src/iter/traits/double_ended.rs b/library/core/src/iter/traits/double_ended.rs index 7a10dea500a..06538d61aa0 100644 --- a/library/core/src/iter/traits/double_ended.rs +++ b/library/core/src/iter/traits/double_ended.rs @@ -100,10 +100,10 @@ pub trait DoubleEndedIterator: Iterator { /// eagerly skip `n` elements starting from the back by calling [`next_back`] up /// to `n` times until [`None`] is encountered. /// - /// `advance_back_by(n)` will return [`Ok(())`] if the iterator successfully advances by - /// `n` elements, or [`Err(k)`] if [`None`] is encountered, where `k` is the number of - /// elements the iterator is advanced by before running out of elements (i.e. the length - /// of the iterator). Note that `k` is always less than `n`. + /// `advance_back_by(n)` will return `0` if the iterator successfully advances by + /// `n` elements, or an usize `k` if [`None`] is encountered, where `k` is remaining number + /// of steps that could not be advanced because the iterator ran out. + /// Note that `k` is always less than `n`. /// /// Calling `advance_back_by(0)` can do meaningful work, for example [`Flatten`] can advance its /// outer iterator until it finds an inner iterator that is not empty, which then often @@ -123,24 +123,26 @@ pub trait DoubleEndedIterator: Iterator { /// let a = [3, 4, 5, 6]; /// let mut iter = a.iter(); /// - /// assert_eq!(iter.advance_back_by(2), Ok(())); + /// assert_eq!(iter.advance_back_by(2), 0); /// assert_eq!(iter.next_back(), Some(&4)); - /// assert_eq!(iter.advance_back_by(0), Ok(())); - /// assert_eq!(iter.advance_back_by(100), Err(1)); // only `&3` was skipped + /// assert_eq!(iter.advance_back_by(0), 0); + /// assert_eq!(iter.advance_back_by(100), 99); // only `&3` was skipped /// ``` /// /// [`Ok(())`]: Ok /// [`Err(k)`]: Err #[inline] #[unstable(feature = "iter_advance_by", reason = "recently added", issue = "77404")] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> + fn advance_back_by(&mut self, n: usize) -> usize where Self::Item: ~const Destruct, { for i in 0..n { - self.next_back().ok_or(i)?; + if self.next_back().is_none() { + return n - i; + } } - Ok(()) + 0 } /// Returns the `n`th element from the end of the iterator. @@ -188,7 +190,9 @@ pub trait DoubleEndedIterator: Iterator { #[stable(feature = "iter_nth_back", since = "1.37.0")] #[rustc_do_not_const_check] fn nth_back(&mut self, n: usize) -> Option { - self.advance_back_by(n).ok()?; + if self.advance_back_by(n) > 0 { + return None; + } self.next_back() } @@ -374,7 +378,7 @@ impl<'a, I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for &'a mut I { fn next_back(&mut self) -> Option { (**self).next_back() } - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_back_by(&mut self, n: usize) -> usize { (**self).advance_back_by(n) } fn nth_back(&mut self, n: usize) -> Option { diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 16c9f668b8e..f2de040c635 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -308,10 +308,10 @@ pub trait Iterator { /// This method will eagerly skip `n` elements by calling [`next`] up to `n` /// times until [`None`] is encountered. /// - /// `advance_by(n)` will return [`Ok(())`][Ok] if the iterator successfully advances by - /// `n` elements, or [`Err(k)`][Err] if [`None`] is encountered, where `k` is the number - /// of elements the iterator is advanced by before running out of elements (i.e. the - /// length of the iterator). Note that `k` is always less than `n`. + /// `advance_by(n)` will return `0` if the iterator successfully advances by + /// `n` elements, or an usize `k` if [`None`] is encountered, where `k` is remaining number + /// of steps that could not be advanced because the iterator ran out. + /// Note that `k` is always less than `n`. /// /// Calling `advance_by(0)` can do meaningful work, for example [`Flatten`] /// can advance its outer iterator until it finds an inner iterator that is not empty, which @@ -330,21 +330,23 @@ pub trait Iterator { /// let a = [1, 2, 3, 4]; /// let mut iter = a.iter(); /// - /// assert_eq!(iter.advance_by(2), Ok(())); + /// assert_eq!(iter.advance_by(2), 0); /// assert_eq!(iter.next(), Some(&3)); - /// assert_eq!(iter.advance_by(0), Ok(())); - /// assert_eq!(iter.advance_by(100), Err(1)); // only `&4` was skipped + /// assert_eq!(iter.advance_by(0), 0); + /// assert_eq!(iter.advance_by(100), 99); // only `&4` was skipped /// ``` #[inline] #[unstable(feature = "iter_advance_by", reason = "recently added", issue = "77404")] - fn advance_by(&mut self, n: usize) -> Result<(), usize> + fn advance_by(&mut self, n: usize) -> usize where Self::Item: ~const Destruct, { for i in 0..n { - self.next().ok_or(i)?; + if self.next().is_none() { + return n - i; + } } - Ok(()) + 0 } /// Returns the `n`th element of the iterator. @@ -392,7 +394,9 @@ pub trait Iterator { where Self::Item: ~const Destruct, { - self.advance_by(n).ok()?; + if self.advance_by(n) > 0 { + return None; + } self.next() } @@ -4013,7 +4017,7 @@ impl Iterator for &mut I { fn size_hint(&self) -> (usize, Option) { (**self).size_hint() } - fn advance_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_by(&mut self, n: usize) -> usize { (**self).advance_by(n) } fn nth(&mut self, n: usize) -> Option { diff --git a/library/core/src/ops/index_range.rs b/library/core/src/ops/index_range.rs index 3e06776d2c6..744ec3b0245 100644 --- a/library/core/src/ops/index_range.rs +++ b/library/core/src/ops/index_range.rs @@ -132,10 +132,9 @@ impl Iterator for IndexRange { } #[inline] - fn advance_by(&mut self, n: usize) -> Result<(), usize> { - let original_len = self.len(); - self.take_prefix(n); - if n > original_len { Err(original_len) } else { Ok(()) } + fn advance_by(&mut self, n: usize) -> usize { + let taken = self.take_prefix(n); + n - taken.len() } } @@ -151,10 +150,9 @@ impl DoubleEndedIterator for IndexRange { } #[inline] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { - let original_len = self.len(); - self.take_suffix(n); - if n > original_len { Err(original_len) } else { Ok(()) } + fn advance_back_by(&mut self, n: usize) -> usize { + let taken = self.take_suffix(n); + n - taken.len() } } diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs index a800da546b4..d3e9b9c2b22 100644 --- a/library/core/src/slice/iter/macros.rs +++ b/library/core/src/slice/iter/macros.rs @@ -176,11 +176,11 @@ macro_rules! iterator { } #[inline] - fn advance_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_by(&mut self, n: usize) -> usize { let advance = cmp::min(len!(self), n); // SAFETY: By construction, `advance` does not exceed `self.len()`. unsafe { self.post_inc_start(advance) }; - if advance == n { Ok(()) } else { Err(advance) } + n - advance } #[inline] @@ -371,11 +371,11 @@ macro_rules! iterator { } #[inline] - fn advance_back_by(&mut self, n: usize) -> Result<(), usize> { + fn advance_back_by(&mut self, n: usize) -> usize { let advance = cmp::min(len!(self), n); // SAFETY: By construction, `advance` does not exceed `self.len()`. unsafe { self.pre_dec_end(advance) }; - if advance == n { Ok(()) } else { Err(advance) } + n - advance } } diff --git a/library/core/tests/array.rs b/library/core/tests/array.rs index 5327e4f8139..9b90c77e151 100644 --- a/library/core/tests/array.rs +++ b/library/core/tests/array.rs @@ -1,4 +1,4 @@ -use core::array; +use core::{array, assert_eq}; use core::convert::TryFrom; use core::sync::atomic::{AtomicUsize, Ordering}; @@ -535,17 +535,17 @@ fn array_intoiter_advance_by() { let mut it = IntoIterator::into_iter(a); let r = it.advance_by(1); - assert_eq!(r, Ok(())); + assert_eq!(r, 0); assert_eq!(it.len(), 99); assert_eq!(counter.get(), 1); let r = it.advance_by(0); - assert_eq!(r, Ok(())); + assert_eq!(r, 0); assert_eq!(it.len(), 99); assert_eq!(counter.get(), 1); let r = it.advance_by(11); - assert_eq!(r, Ok(())); + assert_eq!(r, 0); assert_eq!(it.len(), 88); assert_eq!(counter.get(), 12); @@ -557,17 +557,17 @@ fn array_intoiter_advance_by() { assert_eq!(counter.get(), 13); let r = it.advance_by(123456); - assert_eq!(r, Err(87)); + assert_eq!(r, 123456 - 87); assert_eq!(it.len(), 0); assert_eq!(counter.get(), 100); let r = it.advance_by(0); - assert_eq!(r, Ok(())); + assert_eq!(r, 0); assert_eq!(it.len(), 0); assert_eq!(counter.get(), 100); let r = it.advance_by(10); - assert_eq!(r, Err(0)); + assert_eq!(r, 10); assert_eq!(it.len(), 0); assert_eq!(counter.get(), 100); } @@ -588,17 +588,17 @@ fn array_intoiter_advance_back_by() { let mut it = IntoIterator::into_iter(a); let r = it.advance_back_by(1); - assert_eq!(r, Ok(())); + assert_eq!(r, 0); assert_eq!(it.len(), 99); assert_eq!(counter.get(), 1); let r = it.advance_back_by(0); - assert_eq!(r, Ok(())); + assert_eq!(r, 0); assert_eq!(it.len(), 99); assert_eq!(counter.get(), 1); let r = it.advance_back_by(11); - assert_eq!(r, Ok(())); + assert_eq!(r, 0); assert_eq!(it.len(), 88); assert_eq!(counter.get(), 12); @@ -610,17 +610,17 @@ fn array_intoiter_advance_back_by() { assert_eq!(counter.get(), 13); let r = it.advance_back_by(123456); - assert_eq!(r, Err(87)); + assert_eq!(r, 123456 - 87); assert_eq!(it.len(), 0); assert_eq!(counter.get(), 100); let r = it.advance_back_by(0); - assert_eq!(r, Ok(())); + assert_eq!(r, 0); assert_eq!(it.len(), 0); assert_eq!(counter.get(), 100); let r = it.advance_back_by(10); - assert_eq!(r, Err(0)); + assert_eq!(r, 10); assert_eq!(it.len(), 0); assert_eq!(counter.get(), 100); } @@ -679,8 +679,8 @@ fn array_into_iter_fold() { let a = [1, 2, 3, 4, 5, 6]; let mut it = a.into_iter(); - it.advance_by(1).unwrap(); - it.advance_back_by(2).unwrap(); + assert_eq!(it.advance_by(1), 0); + assert_eq!(it.advance_back_by(2), 0); let s = it.fold(10, |a, b| 10 * a + b); assert_eq!(s, 10234); } @@ -695,8 +695,8 @@ fn array_into_iter_rfold() { let a = [1, 2, 3, 4, 5, 6]; let mut it = a.into_iter(); - it.advance_by(1).unwrap(); - it.advance_back_by(2).unwrap(); + assert_eq!(it.advance_by(1), 0); + assert_eq!(it.advance_back_by(2), 0); let s = it.rfold(10, |a, b| 10 * a + b); assert_eq!(s, 10432); } diff --git a/library/core/tests/iter/adapters/chain.rs b/library/core/tests/iter/adapters/chain.rs index f419f9cec12..4da9263d7ac 100644 --- a/library/core/tests/iter/adapters/chain.rs +++ b/library/core/tests/iter/adapters/chain.rs @@ -31,28 +31,28 @@ fn test_iterator_chain_advance_by() { for i in 0..xs.len() { let mut iter = Unfuse::new(xs).chain(Unfuse::new(ys)); - iter.advance_by(i).unwrap(); + assert_eq!(0, iter.advance_by(i)); assert_eq!(iter.next(), Some(&xs[i])); - assert_eq!(iter.advance_by(100), Err(len - i - 1)); - iter.advance_by(0).unwrap(); + assert_eq!(iter.advance_by(100), 100 - (len - i - 1)); + assert_eq!(0, iter.advance_by(0)); } for i in 0..ys.len() { let mut iter = Unfuse::new(xs).chain(Unfuse::new(ys)); - iter.advance_by(xs.len() + i).unwrap(); + assert_eq!(iter.advance_by(xs.len() + i), 0); assert_eq!(iter.next(), Some(&ys[i])); - assert_eq!(iter.advance_by(100), Err(ys.len() - i - 1)); - iter.advance_by(0).unwrap(); + assert_eq!(iter.advance_by(100), 100 - (ys.len() - i - 1)); + assert_eq!(iter.advance_by(0), 0); } let mut iter = xs.iter().chain(ys); - iter.advance_by(len).unwrap(); + assert_eq!(iter.advance_by(len), 0); assert_eq!(iter.next(), None); - iter.advance_by(0).unwrap(); + assert_eq!(iter.advance_by(0), 0); let mut iter = xs.iter().chain(ys); - assert_eq!(iter.advance_by(len + 1), Err(len)); - iter.advance_by(0).unwrap(); + assert_eq!(iter.advance_by(len + 1), 1); + assert_eq!(iter.advance_by(0), 0); } test_chain(&[], &[]); @@ -68,28 +68,28 @@ fn test_iterator_chain_advance_back_by() { for i in 0..ys.len() { let mut iter = Unfuse::new(xs).chain(Unfuse::new(ys)); - iter.advance_back_by(i).unwrap(); + assert_eq!(iter.advance_back_by(i), 0); assert_eq!(iter.next_back(), Some(&ys[ys.len() - i - 1])); - assert_eq!(iter.advance_back_by(100), Err(len - i - 1)); - iter.advance_back_by(0).unwrap(); + assert_eq!(iter.advance_back_by(100), 100 - (len - i - 1)); + assert_eq!(iter.advance_back_by(0), 0); } for i in 0..xs.len() { let mut iter = Unfuse::new(xs).chain(Unfuse::new(ys)); - iter.advance_back_by(ys.len() + i).unwrap(); + assert_eq!(iter.advance_back_by(ys.len() + i), 0); assert_eq!(iter.next_back(), Some(&xs[xs.len() - i - 1])); - assert_eq!(iter.advance_back_by(100), Err(xs.len() - i - 1)); - iter.advance_back_by(0).unwrap(); + assert_eq!(iter.advance_back_by(100), 100 - (xs.len() - i - 1)); + assert_eq!(iter.advance_back_by(0), 0); } let mut iter = xs.iter().chain(ys); - iter.advance_back_by(len).unwrap(); + assert_eq!(iter.advance_back_by(len), 0); assert_eq!(iter.next_back(), None); - iter.advance_back_by(0).unwrap(); + assert_eq!(iter.advance_back_by(0), 0); let mut iter = xs.iter().chain(ys); - assert_eq!(iter.advance_back_by(len + 1), Err(len)); - iter.advance_back_by(0).unwrap(); + assert_eq!(iter.advance_back_by(len + 1), 1); + assert_eq!(iter.advance_back_by(0), 0); } test_chain(&[], &[]); diff --git a/library/core/tests/iter/adapters/flatten.rs b/library/core/tests/iter/adapters/flatten.rs index 690fd0c2197..e8e06a8ca40 100644 --- a/library/core/tests/iter/adapters/flatten.rs +++ b/library/core/tests/iter/adapters/flatten.rs @@ -1,3 +1,4 @@ +use core::assert_eq; use super::*; use core::iter::*; @@ -61,19 +62,19 @@ fn test_flatten_try_folds() { fn test_flatten_advance_by() { let mut it = once(0..10).chain(once(10..30)).chain(once(30..40)).flatten(); - it.advance_by(5).unwrap(); + assert_eq!(it.advance_by(5), 0); assert_eq!(it.next(), Some(5)); - it.advance_by(9).unwrap(); + assert_eq!(it.advance_by(9), 0); assert_eq!(it.next(), Some(15)); - it.advance_back_by(4).unwrap(); + assert_eq!(it.advance_back_by(4), 0); assert_eq!(it.next_back(), Some(35)); - it.advance_back_by(9).unwrap(); + assert_eq!(it.advance_back_by(9), 0); assert_eq!(it.next_back(), Some(25)); - assert_eq!(it.advance_by(usize::MAX), Err(9)); - assert_eq!(it.advance_back_by(usize::MAX), Err(0)); - it.advance_by(0).unwrap(); - it.advance_back_by(0).unwrap(); + assert_eq!(it.advance_by(usize::MAX), usize::MAX - 9); + assert_eq!(it.advance_back_by(usize::MAX), usize::MAX); + assert_eq!(it.advance_by(0), 0); + assert_eq!(it.advance_back_by(0), 0); assert_eq!(it.size_hint(), (0, Some(0))); } @@ -174,19 +175,19 @@ fn test_flatten_count() { let mut it = once(0..10).chain(once(10..30)).chain(once(30..40)).flatten(); assert_eq!(it.clone().count(), 40); - it.advance_by(5).unwrap(); + assert_eq!(it.advance_by(5), 0); assert_eq!(it.clone().count(), 35); - it.advance_back_by(5).unwrap(); + assert_eq!(it.advance_back_by(5), 0); assert_eq!(it.clone().count(), 30); - it.advance_by(10).unwrap(); + assert_eq!(it.advance_by(10), 0); assert_eq!(it.clone().count(), 20); - it.advance_back_by(8).unwrap(); + assert_eq!(it.advance_back_by(8), 0); assert_eq!(it.clone().count(), 12); - it.advance_by(4).unwrap(); + assert_eq!(it.advance_by(4), 0); assert_eq!(it.clone().count(), 8); - it.advance_back_by(5).unwrap(); + assert_eq!(it.advance_back_by(5), 0); assert_eq!(it.clone().count(), 3); - it.advance_by(3).unwrap(); + assert_eq!(it.advance_by(3), 0); assert_eq!(it.clone().count(), 0); } @@ -195,18 +196,18 @@ fn test_flatten_last() { let mut it = once(0..10).chain(once(10..30)).chain(once(30..40)).flatten(); assert_eq!(it.clone().last(), Some(39)); - it.advance_by(5).unwrap(); // 5..40 + assert_eq!(it.advance_by(5), 0); // 5..40 assert_eq!(it.clone().last(), Some(39)); - it.advance_back_by(5).unwrap(); // 5..35 + assert_eq!(it.advance_back_by(5), 0); // 5..35 assert_eq!(it.clone().last(), Some(34)); - it.advance_by(10).unwrap(); // 15..35 + assert_eq!(it.advance_by(10), 0); // 15..35 assert_eq!(it.clone().last(), Some(34)); - it.advance_back_by(8).unwrap(); // 15..27 + assert_eq!(it.advance_back_by(8), 0); // 15..27 assert_eq!(it.clone().last(), Some(26)); - it.advance_by(4).unwrap(); // 19..27 + assert_eq!(it.advance_by(4), 0); // 19..27 assert_eq!(it.clone().last(), Some(26)); - it.advance_back_by(5).unwrap(); // 19..22 + assert_eq!(it.advance_back_by(5), 0); // 19..22 assert_eq!(it.clone().last(), Some(21)); - it.advance_by(3).unwrap(); // 22..22 + assert_eq!(it.advance_by(3), 0); // 22..22 assert_eq!(it.clone().last(), None); } diff --git a/library/core/tests/iter/adapters/skip.rs b/library/core/tests/iter/adapters/skip.rs index 754641834e8..134dead4ad3 100644 --- a/library/core/tests/iter/adapters/skip.rs +++ b/library/core/tests/iter/adapters/skip.rs @@ -73,13 +73,16 @@ fn test_iterator_skip_nth() { #[test] fn test_skip_advance_by() { - assert_eq!((0..0).skip(10).advance_by(0), Ok(())); - assert_eq!((0..0).skip(10).advance_by(1), Err(0)); - assert_eq!((0u128..(usize::MAX as u128) + 1).skip(usize::MAX).advance_by(usize::MAX), Err(1)); - assert_eq!((0u128..u128::MAX).skip(usize::MAX).advance_by(1), Ok(())); + assert_eq!((0..0).skip(10).advance_by(0), 0); + assert_eq!((0..0).skip(10).advance_by(1), 1); + assert_eq!( + (0u128..(usize::MAX as u128) + 1).skip(usize::MAX - 10).advance_by(usize::MAX - 5), + usize::MAX - 16 + ); + assert_eq!((0u128..u128::MAX).skip(usize::MAX - 10).advance_by(20), 0); - assert_eq!((0..2).skip(1).advance_back_by(10), Err(1)); - assert_eq!((0..0).skip(1).advance_back_by(0), Ok(())); + assert_eq!((0..2).skip(1).advance_back_by(10), 9); + assert_eq!((0..0).skip(1).advance_back_by(0), 0); } #[test] diff --git a/library/core/tests/iter/adapters/take.rs b/library/core/tests/iter/adapters/take.rs index 3e26b43a2ed..8ba7f0c5f8a 100644 --- a/library/core/tests/iter/adapters/take.rs +++ b/library/core/tests/iter/adapters/take.rs @@ -76,23 +76,23 @@ fn test_iterator_take_nth_back() { #[test] fn test_take_advance_by() { let mut take = (0..10).take(3); - assert_eq!(take.advance_by(2), Ok(())); + assert_eq!(take.advance_by(2), 0); assert_eq!(take.next(), Some(2)); - assert_eq!(take.advance_by(1), Err(0)); + assert_eq!(take.advance_by(1), 1); - assert_eq!((0..0).take(10).advance_by(0), Ok(())); - assert_eq!((0..0).take(10).advance_by(1), Err(0)); - assert_eq!((0..10).take(4).advance_by(5), Err(4)); + assert_eq!((0..0).take(10).advance_by(0), 0); + assert_eq!((0..0).take(10).advance_by(1), 1); + assert_eq!((0..10).take(4).advance_by(5), 1); let mut take = (0..10).take(3); - assert_eq!(take.advance_back_by(2), Ok(())); + assert_eq!(take.advance_back_by(2), 0); assert_eq!(take.next(), Some(0)); - assert_eq!(take.advance_back_by(1), Err(0)); + assert_eq!(take.advance_back_by(1), 1); - assert_eq!((0..2).take(1).advance_back_by(10), Err(1)); - assert_eq!((0..0).take(1).advance_back_by(1), Err(0)); - assert_eq!((0..0).take(1).advance_back_by(0), Ok(())); - assert_eq!((0..usize::MAX).take(100).advance_back_by(usize::MAX), Err(100)); + assert_eq!((0..2).take(1).advance_back_by(10), 9); + assert_eq!((0..0).take(1).advance_back_by(1), 1); + assert_eq!((0..0).take(1).advance_back_by(0), 0); + assert_eq!((0..usize::MAX).take(100).advance_back_by(usize::MAX), usize::MAX - 100); } #[test] diff --git a/library/core/tests/iter/range.rs b/library/core/tests/iter/range.rs index 0f91ffe2dfc..d375dbf2ce4 100644 --- a/library/core/tests/iter/range.rs +++ b/library/core/tests/iter/range.rs @@ -287,25 +287,25 @@ fn test_range_step() { #[test] fn test_range_advance_by() { let mut r = 0..usize::MAX; - r.advance_by(0).unwrap(); - r.advance_back_by(0).unwrap(); + assert_eq!(0, r.advance_by(0)); + assert_eq!(0, r.advance_back_by(0)); assert_eq!(r.len(), usize::MAX); - r.advance_by(1).unwrap(); - r.advance_back_by(1).unwrap(); + assert_eq!(0, r.advance_by(1)); + assert_eq!(0, r.advance_back_by(1)); assert_eq!((r.start, r.end), (1, usize::MAX - 1)); - assert_eq!(r.advance_by(usize::MAX), Err(usize::MAX - 2)); + assert_eq!(2, r.advance_by(usize::MAX)); - r.advance_by(0).unwrap(); - r.advance_back_by(0).unwrap(); + assert_eq!(0, r.advance_by(0)); + assert_eq!(0, r.advance_back_by(0)); let mut r = 0u128..u128::MAX; - r.advance_by(usize::MAX).unwrap(); - r.advance_back_by(usize::MAX).unwrap(); + assert_eq!(0, r.advance_by(usize::MAX)); + assert_eq!(0, r.advance_back_by(usize::MAX)); assert_eq!((r.start, r.end), (0u128 + usize::MAX as u128, u128::MAX - usize::MAX as u128)); } diff --git a/library/core/tests/iter/traits/iterator.rs b/library/core/tests/iter/traits/iterator.rs index 62566a9502d..4b446727c9a 100644 --- a/library/core/tests/iter/traits/iterator.rs +++ b/library/core/tests/iter/traits/iterator.rs @@ -148,13 +148,13 @@ fn test_iterator_advance_by() { for i in 0..v.len() { let mut iter = v.iter(); - assert_eq!(iter.advance_by(i), Ok(())); + assert_eq!(iter.advance_by(i), 0); assert_eq!(iter.next().unwrap(), &v[i]); - assert_eq!(iter.advance_by(100), Err(v.len() - 1 - i)); + assert_eq!(iter.advance_by(100), 100 - (v.len() - 1 - i)); } - assert_eq!(v.iter().advance_by(v.len()), Ok(())); - assert_eq!(v.iter().advance_by(100), Err(v.len())); + assert_eq!(v.iter().advance_by(v.len()), 0); + assert_eq!(v.iter().advance_by(100), 100 - v.len()); } #[test] @@ -163,13 +163,13 @@ fn test_iterator_advance_back_by() { for i in 0..v.len() { let mut iter = v.iter(); - assert_eq!(iter.advance_back_by(i), Ok(())); + assert_eq!(iter.advance_back_by(i), 0); assert_eq!(iter.next_back().unwrap(), &v[v.len() - 1 - i]); - assert_eq!(iter.advance_back_by(100), Err(v.len() - 1 - i)); + assert_eq!(iter.advance_back_by(100), 100 - (v.len() - 1 - i)); } - assert_eq!(v.iter().advance_back_by(v.len()), Ok(())); - assert_eq!(v.iter().advance_back_by(100), Err(v.len())); + assert_eq!(v.iter().advance_back_by(v.len()), 0); + assert_eq!(v.iter().advance_back_by(100), 100 - v.len()); } #[test] @@ -178,13 +178,13 @@ fn test_iterator_rev_advance_back_by() { for i in 0..v.len() { let mut iter = v.iter().rev(); - assert_eq!(iter.advance_back_by(i), Ok(())); + assert_eq!(iter.advance_back_by(i), 0); assert_eq!(iter.next_back().unwrap(), &v[i]); - assert_eq!(iter.advance_back_by(100), Err(v.len() - 1 - i)); + assert_eq!(iter.advance_back_by(100), 100 - (v.len() - 1 - i)); } - assert_eq!(v.iter().rev().advance_back_by(v.len()), Ok(())); - assert_eq!(v.iter().rev().advance_back_by(100), Err(v.len())); + assert_eq!(v.iter().rev().advance_back_by(v.len()), 0); + assert_eq!(v.iter().rev().advance_back_by(100), 100 - v.len()); } #[test] @@ -422,13 +422,13 @@ fn test_iterator_rev_advance_by() { for i in 0..v.len() { let mut iter = v.iter().rev(); - assert_eq!(iter.advance_by(i), Ok(())); + assert_eq!(iter.advance_by(i), 0); assert_eq!(iter.next().unwrap(), &v[v.len() - 1 - i]); - assert_eq!(iter.advance_by(100), Err(v.len() - 1 - i)); + assert_eq!(iter.advance_by(100), 100 - (v.len() - 1 - i)); } - assert_eq!(v.iter().rev().advance_by(v.len()), Ok(())); - assert_eq!(v.iter().rev().advance_by(100), Err(v.len())); + assert_eq!(v.iter().rev().advance_by(v.len()), 0); + assert_eq!(v.iter().rev().advance_by(100), 100 - v.len()); } #[test] diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs index 39559cdbb5e..a675d9e13fb 100644 --- a/library/core/tests/slice.rs +++ b/library/core/tests/slice.rs @@ -142,20 +142,20 @@ fn test_iterator_advance_by() { for i in 0..=v.len() { let mut iter = v.iter(); - iter.advance_by(i).unwrap(); + assert_eq!(iter.advance_by(i), 0); assert_eq!(iter.as_slice(), &v[i..]); } let mut iter = v.iter(); - assert_eq!(iter.advance_by(v.len() + 1), Err(v.len())); + assert_eq!(iter.advance_by(v.len() + 1), 1); assert_eq!(iter.as_slice(), &[]); let mut iter = v.iter(); - iter.advance_by(3).unwrap(); + assert_eq!(iter.advance_by(3), 0); assert_eq!(iter.as_slice(), &v[3..]); - iter.advance_by(2).unwrap(); + assert_eq!(iter.advance_by(2), 0); assert_eq!(iter.as_slice(), &[]); - iter.advance_by(0).unwrap(); + assert_eq!(iter.advance_by(0), 0); } #[test] @@ -164,20 +164,20 @@ fn test_iterator_advance_back_by() { for i in 0..=v.len() { let mut iter = v.iter(); - iter.advance_back_by(i).unwrap(); + assert_eq!(iter.advance_back_by(i), 0); assert_eq!(iter.as_slice(), &v[..v.len() - i]); } let mut iter = v.iter(); - assert_eq!(iter.advance_back_by(v.len() + 1), Err(v.len())); + assert_eq!(iter.advance_back_by(v.len() + 1), 1); assert_eq!(iter.as_slice(), &[]); let mut iter = v.iter(); - iter.advance_back_by(3).unwrap(); + assert_eq!(iter.advance_back_by(3), 0); assert_eq!(iter.as_slice(), &v[..v.len() - 3]); - iter.advance_back_by(2).unwrap(); + assert_eq!(iter.advance_back_by(2), 0); assert_eq!(iter.as_slice(), &[]); - iter.advance_back_by(0).unwrap(); + assert_eq!(iter.advance_back_by(0), 0); } #[test] From 0c13565ca66d25d15ee9146919dd74e57cdfda89 Mon Sep 17 00:00:00 2001 From: lcnr Date: Wed, 20 Jul 2022 14:32:58 +0200 Subject: [PATCH 171/346] Add a builtin `FnPtr` trait --- .../src/interpret/terminator.rs | 1 + compiler/rustc_hir/src/lang_items.rs | 3 + compiler/rustc_middle/src/mir/mono.rs | 3 +- compiler/rustc_middle/src/mir/visit.rs | 3 +- compiler/rustc_middle/src/ty/instance.rs | 18 ++- compiler/rustc_middle/src/ty/mod.rs | 16 +- compiler/rustc_mir_transform/src/inline.rs | 3 +- .../rustc_mir_transform/src/inline/cycle.rs | 3 + compiler/rustc_mir_transform/src/shim.rs | 37 +++++ compiler/rustc_monomorphize/src/collector.rs | 3 +- .../src/partitioning/default.rs | 6 +- compiler/rustc_span/src/symbol.rs | 2 + .../src/solve/assembly.rs | 8 + .../src/solve/project_goals.rs | 7 + .../src/solve/trait_goals.rs | 16 +- .../src/traits/coherence.rs | 13 ++ .../src/traits/select/candidate_assembly.rs | 152 +++++++++++++++++- compiler/rustc_ty_utils/src/instance.rs | 19 ++- library/core/src/marker.rs | 15 ++ tests/ui/fn/fn-ptr-trait.rs | 9 ++ 20 files changed, 310 insertions(+), 27 deletions(-) create mode 100644 tests/ui/fn/fn-ptr-trait.rs diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index fc83985eaca..54d67bd1f29 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -382,6 +382,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { | ty::InstanceDef::FnPtrShim(..) | ty::InstanceDef::DropGlue(..) | ty::InstanceDef::CloneShim(..) + | ty::InstanceDef::FnPtrAddrShim(..) | ty::InstanceDef::Item(_) => { // We need MIR for this fn let Some((body, instance)) = diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 0863d65d8f9..07faecdb6a7 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -166,6 +166,9 @@ language_item_table! { Freeze, sym::freeze, freeze_trait, Target::Trait, GenericRequirement::Exact(0); + FnPtrTrait, sym::fn_ptr_trait, fn_ptr_trait, Target::Trait, GenericRequirement::Exact(0); + FnPtrAddr, sym::fn_ptr_addr, fn_ptr_addr, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None; + Drop, sym::drop, drop_trait, Target::Trait, GenericRequirement::None; Destruct, sym::destruct, destruct_trait, Target::Trait, GenericRequirement::None; diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index 7a05ee2ff37..90397f01bc8 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -381,7 +381,8 @@ impl<'tcx> CodegenUnit<'tcx> { | InstanceDef::Virtual(..) | InstanceDef::ClosureOnceShim { .. } | InstanceDef::DropGlue(..) - | InstanceDef::CloneShim(..) => None, + | InstanceDef::CloneShim(..) + | InstanceDef::FnPtrAddrShim(..) => None, } } MonoItem::Static(def_id) => def_id.as_local().map(Idx::index), diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index cffdd7ff37f..9b31ad783fc 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -340,7 +340,8 @@ macro_rules! make_mir_visitor { ty::InstanceDef::FnPtrShim(_def_id, ty) | ty::InstanceDef::DropGlue(_def_id, Some(ty)) | - ty::InstanceDef::CloneShim(_def_id, ty) => { + ty::InstanceDef::CloneShim(_def_id, ty) | + ty::InstanceDef::FnPtrAddrShim(_def_id, ty) => { // FIXME(eddyb) use a better `TyContext` here. self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)); } diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index aa10a651c07..036b4477679 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -96,6 +96,13 @@ pub enum InstanceDef<'tcx> { /// /// The `DefId` is for `Clone::clone`, the `Ty` is the type `T` with the builtin `Clone` impl. CloneShim(DefId, Ty<'tcx>), + + /// Compiler-generated `::addr` implementation. + /// + /// Automatically generated for all potentially higher-ranked `fn(I) -> R` types. + /// + /// The `DefId` is for `FnPtr::addr`, the `Ty` is the type `T`. + FnPtrAddrShim(DefId, Ty<'tcx>), } impl<'tcx> Instance<'tcx> { @@ -151,7 +158,8 @@ impl<'tcx> InstanceDef<'tcx> { | InstanceDef::Intrinsic(def_id) | InstanceDef::ClosureOnceShim { call_once: def_id, track_caller: _ } | InstanceDef::DropGlue(def_id, _) - | InstanceDef::CloneShim(def_id, _) => def_id, + | InstanceDef::CloneShim(def_id, _) + | InstanceDef::FnPtrAddrShim(def_id, _) => def_id, } } @@ -167,7 +175,8 @@ impl<'tcx> InstanceDef<'tcx> { | InstanceDef::Intrinsic(..) | InstanceDef::ClosureOnceShim { .. } | InstanceDef::DropGlue(..) - | InstanceDef::CloneShim(..) => None, + | InstanceDef::CloneShim(..) + | InstanceDef::FnPtrAddrShim(..) => None, } } @@ -182,7 +191,8 @@ impl<'tcx> InstanceDef<'tcx> { | InstanceDef::Intrinsic(def_id) | InstanceDef::ClosureOnceShim { call_once: def_id, track_caller: _ } | InstanceDef::DropGlue(def_id, _) - | InstanceDef::CloneShim(def_id, _) => ty::WithOptConstParam::unknown(def_id), + | InstanceDef::CloneShim(def_id, _) + | InstanceDef::FnPtrAddrShim(def_id, _) => ty::WithOptConstParam::unknown(def_id), } } @@ -268,6 +278,7 @@ impl<'tcx> InstanceDef<'tcx> { pub fn has_polymorphic_mir_body(&self) -> bool { match *self { InstanceDef::CloneShim(..) + | InstanceDef::FnPtrAddrShim(..) | InstanceDef::FnPtrShim(..) | InstanceDef::DropGlue(_, Some(_)) => false, InstanceDef::ClosureOnceShim { .. } @@ -306,6 +317,7 @@ fn fmt_instance( InstanceDef::DropGlue(_, None) => write!(f, " - shim(None)"), InstanceDef::DropGlue(_, Some(ty)) => write!(f, " - shim(Some({}))", ty), InstanceDef::CloneShim(_, ty) => write!(f, " - shim({})", ty), + InstanceDef::FnPtrAddrShim(_, ty) => write!(f, " - shim({})", ty), } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index c6a56df5a5e..48b400f7c97 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2284,12 +2284,12 @@ impl<'tcx> TyCtxt<'tcx> { def_id1: DefId, def_id2: DefId, ) -> Option { + let impl_trait_ref1 = self.impl_trait_ref(def_id1); + let impl_trait_ref2 = self.impl_trait_ref(def_id2); // If either trait impl references an error, they're allowed to overlap, // as one of them essentially doesn't exist. - if self.impl_trait_ref(def_id1).map_or(false, |tr| tr.subst_identity().references_error()) - || self - .impl_trait_ref(def_id2) - .map_or(false, |tr| tr.subst_identity().references_error()) + if impl_trait_ref1.map_or(false, |tr| tr.subst_identity().references_error()) + || impl_trait_ref2.map_or(false, |tr| tr.subst_identity().references_error()) { return Some(ImplOverlapKind::Permitted { marker: false }); } @@ -2317,11 +2317,10 @@ impl<'tcx> TyCtxt<'tcx> { }; let is_marker_overlap = { - let is_marker_impl = |def_id: DefId| -> bool { - let trait_ref = self.impl_trait_ref(def_id); + let is_marker_impl = |trait_ref: Option>>| -> bool { trait_ref.map_or(false, |tr| self.trait_def(tr.skip_binder().def_id).is_marker) }; - is_marker_impl(def_id1) && is_marker_impl(def_id2) + is_marker_impl(impl_trait_ref1) && is_marker_impl(impl_trait_ref2) }; if is_marker_overlap { @@ -2405,7 +2404,8 @@ impl<'tcx> TyCtxt<'tcx> { | ty::InstanceDef::Virtual(..) | ty::InstanceDef::ClosureOnceShim { .. } | ty::InstanceDef::DropGlue(..) - | ty::InstanceDef::CloneShim(..) => self.mir_shims(instance), + | ty::InstanceDef::CloneShim(..) + | ty::InstanceDef::FnPtrAddrShim(..) => self.mir_shims(instance), } } diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 4e7f68437e7..b69186c9451 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -270,7 +270,8 @@ impl<'tcx> Inliner<'tcx> { | InstanceDef::FnPtrShim(..) | InstanceDef::ClosureOnceShim { .. } | InstanceDef::DropGlue(..) - | InstanceDef::CloneShim(..) => return Ok(()), + | InstanceDef::CloneShim(..) + | InstanceDef::FnPtrAddrShim(..) => return Ok(()), } if self.tcx.is_constructor(callee_def_id) { diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs index 792457c80b0..faf404c7771 100644 --- a/compiler/rustc_mir_transform/src/inline/cycle.rs +++ b/compiler/rustc_mir_transform/src/inline/cycle.rs @@ -84,6 +84,9 @@ pub(crate) fn mir_callgraph_reachable<'tcx>( | InstanceDef::FnPtrShim(..) | InstanceDef::ClosureOnceShim { .. } | InstanceDef::CloneShim(..) => {} + + // This shim does not call any other functions, thus there can be no recursion. + InstanceDef::FnPtrAddrShim(..) => continue, InstanceDef::DropGlue(..) => { // FIXME: A not fully substituted drop shim can cause ICEs if one attempts to // have its MIR built. Likely oli-obk just screwed up the `ParamEnv`s, so this diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 970a0a8d4bf..06a6deeee43 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -77,6 +77,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<' build_drop_shim(tcx, def_id, ty) } ty::InstanceDef::CloneShim(def_id, ty) => build_clone_shim(tcx, def_id, ty), + ty::InstanceDef::FnPtrAddrShim(def_id, ty) => build_fn_ptr_addr_shim(tcx, def_id, ty), ty::InstanceDef::Virtual(..) => { bug!("InstanceDef::Virtual ({:?}) is for direct calls only", instance) } @@ -861,3 +862,39 @@ pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> { body } + +/// ```ignore (pseudo-impl) +/// impl FnPtr for fn(u32) { +/// fn addr(self) -> usize { +/// self as usize +/// } +/// } +/// ``` +fn build_fn_ptr_addr_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -> Body<'tcx> { + assert!(matches!(self_ty.kind(), ty::FnPtr(..)), "expected fn ptr, found {self_ty}"); + let span = tcx.def_span(def_id); + let Some(sig) = tcx.fn_sig(def_id).subst(tcx, &[self_ty.into()]).no_bound_vars() else { + span_bug!(span, "FnPtr::addr with bound vars for `{self_ty}`"); + }; + let locals = local_decls_for_sig(&sig, span); + + let source_info = SourceInfo::outermost(span); + // FIXME: use `expose_addr` once we figure out whether function pointers have meaningful provenance. + let rvalue = Rvalue::Cast( + CastKind::FnPtrToPtr, + Operand::Move(Place::from(Local::new(1))), + tcx.mk_imm_ptr(tcx.types.unit), + ); + let stmt = Statement { + source_info, + kind: StatementKind::Assign(Box::new((Place::return_place(), rvalue))), + }; + let statements = vec![stmt]; + let start_block = BasicBlockData { + statements, + terminator: Some(Terminator { source_info, kind: TerminatorKind::Return }), + is_cleanup: false, + }; + let source = MirSource::from_instance(ty::InstanceDef::FnPtrAddrShim(def_id, self_ty)); + new_body(source, IndexVec::from_elem_n(start_block, 1), locals, sig.inputs().len(), span) +} diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index aff27e5664b..8e7012c2774 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -974,7 +974,8 @@ fn visit_instance_use<'tcx>( | ty::InstanceDef::ClosureOnceShim { .. } | ty::InstanceDef::Item(..) | ty::InstanceDef::FnPtrShim(..) - | ty::InstanceDef::CloneShim(..) => { + | ty::InstanceDef::CloneShim(..) + | ty::InstanceDef::FnPtrAddrShim(..) => { output.push(create_fn_mono_item(tcx, instance, source)); } } diff --git a/compiler/rustc_monomorphize/src/partitioning/default.rs b/compiler/rustc_monomorphize/src/partitioning/default.rs index 3c7425d83c4..64968a76ab5 100644 --- a/compiler/rustc_monomorphize/src/partitioning/default.rs +++ b/compiler/rustc_monomorphize/src/partitioning/default.rs @@ -278,7 +278,8 @@ fn characteristic_def_id_of_mono_item<'tcx>( | ty::InstanceDef::Intrinsic(..) | ty::InstanceDef::DropGlue(..) | ty::InstanceDef::Virtual(..) - | ty::InstanceDef::CloneShim(..) => return None, + | ty::InstanceDef::CloneShim(..) + | ty::InstanceDef::FnPtrAddrShim(..) => return None, }; // If this is a method, we want to put it into the same module as @@ -432,7 +433,8 @@ fn mono_item_visibility<'tcx>( | InstanceDef::Intrinsic(..) | InstanceDef::ClosureOnceShim { .. } | InstanceDef::DropGlue(..) - | InstanceDef::CloneShim(..) => return Visibility::Hidden, + | InstanceDef::CloneShim(..) + | InstanceDef::FnPtrAddrShim(..) => return Visibility::Hidden, }; // The `start_fn` lang item is actually a monomorphized instance of a diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 4a1abdf6318..0ed99353145 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -722,6 +722,8 @@ symbols! { fn_mut, fn_once, fn_once_output, + fn_ptr_addr, + fn_ptr_trait, forbid, forget, format, diff --git a/compiler/rustc_trait_selection/src/solve/assembly.rs b/compiler/rustc_trait_selection/src/solve/assembly.rs index 995fec78c40..8dad3f312c9 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly.rs @@ -153,6 +153,12 @@ pub(super) trait GoalKind<'tcx>: TypeFoldable> + Copy + Eq { goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx>; + // A type is a `FnPtr` if it is of `FnPtr` type. + fn consider_builtin_fn_ptr_trait_candidate( + ecx: &mut EvalCtxt<'_, 'tcx>, + goal: Goal<'tcx, Self>, + ) -> QueryResult<'tcx>; + // A callable type (a closure, fn def, or fn ptr) is known to implement the `Fn` // family of traits where `A` is given by the signature of the type. fn consider_builtin_fn_trait_candidates( @@ -331,6 +337,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { G::consider_builtin_copy_clone_candidate(self, goal) } else if lang_items.pointer_like() == Some(trait_def_id) { G::consider_builtin_pointer_like_candidate(self, goal) + } else if lang_items.fn_ptr_trait() == Some(trait_def_id) { + G::consider_builtin_fn_ptr_trait_candidate(self, goal) } else if let Some(kind) = self.tcx().fn_trait_kind_from_def_id(trait_def_id) { G::consider_builtin_fn_trait_candidates(self, goal, kind) } else if lang_items.tuple_trait() == Some(trait_def_id) { diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index 14c5b83c6ca..2b104703aab 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -261,6 +261,13 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { bug!("`PointerLike` does not have an associated type: {:?}", goal); } + fn consider_builtin_fn_ptr_trait_candidate( + _ecx: &mut EvalCtxt<'_, 'tcx>, + goal: Goal<'tcx, Self>, + ) -> QueryResult<'tcx> { + bug!("`FnPtr` does not have an associated type: {:?}", goal); + } + fn consider_builtin_fn_trait_candidates( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index ade45d199f0..718c82c8f1f 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -222,9 +222,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { let self_ty = tcx.erase_regions(goal.predicate.self_ty()); if let Ok(layout) = tcx.layout_of(goal.param_env.and(self_ty)) - && let usize_layout = tcx.layout_of(ty::ParamEnv::empty().and(tcx.types.usize)).unwrap().layout - && layout.layout.size() == usize_layout.size() - && layout.layout.align().abi == usize_layout.align().abi + && layout.layout.size() == tcx.data_layout.pointer_size + && layout.layout.align().abi == tcx.data_layout.pointer_align.abi { // FIXME: We could make this faster by making a no-constraints response ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) @@ -233,6 +232,17 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { } } + fn consider_builtin_fn_ptr_trait_candidate( + ecx: &mut EvalCtxt<'_, 'tcx>, + goal: Goal<'tcx, Self>, + ) -> QueryResult<'tcx> { + if let ty::FnPtr(..) = goal.predicate.self_ty().kind() { + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + } else { + Err(NoSolution) + } + } + fn consider_builtin_fn_trait_candidates( ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 98e00e8223b..89e91eb298b 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -411,11 +411,24 @@ fn resolve_negative_obligation<'tcx>( infcx.resolve_regions(&outlives_env).is_empty() } +/// Returns whether all impls which would apply to the `trait_ref` +/// e.g. `Ty: Trait` are already known in the local crate. +/// +/// This both checks whether any downstream or sibling crates could +/// implement it and whether an upstream crate can add this impl +/// without breaking backwards compatibility. #[instrument(level = "debug", skip(tcx), ret)] pub fn trait_ref_is_knowable<'tcx>( tcx: TyCtxt<'tcx>, trait_ref: ty::TraitRef<'tcx>, ) -> Result<(), Conflict> { + if Some(trait_ref.def_id) == tcx.lang_items().fn_ptr_trait() { + // The only types implementing `FnPtr` are function pointers, + // so if there's no impl of `FnPtr` in the current crate, + // then such an impl will never be added in the future. + return Ok(()); + } + if orphan_check_trait_ref(trait_ref, InCrate::Remote).is_ok() { // A downstream or cousin crate is allowed to implement some // substitution of this trait-ref. diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index e06eff34df2..234d773d64d 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -5,6 +5,8 @@ //! candidates. See the [rustc dev guide] for more details. //! //! [rustc dev guide]:https://rustc-dev-guide.rust-lang.org/traits/resolution.html#candidate-assembly + +use hir::def_id::DefId; use hir::LangItem; use rustc_hir as hir; use rustc_infer::traits::ObligationCause; @@ -96,6 +98,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.assemble_candidate_for_tuple(obligation, &mut candidates); } else if lang_items.pointer_like() == Some(def_id) { self.assemble_candidate_for_ptr_sized(obligation, &mut candidates); + } else if lang_items.fn_ptr_trait() == Some(def_id) { + self.assemble_candidates_for_fn_ptr_trait(obligation, &mut candidates); } else { if lang_items.clone_trait() == Some(def_id) { // Same builtin conditions as `Copy`, i.e., every type which has builtin support @@ -321,13 +325,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } /// Searches for impls that might apply to `obligation`. + #[instrument(level = "debug", skip(self, candidates))] fn assemble_candidates_from_impls( &mut self, obligation: &TraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, ) { - debug!(?obligation, "assemble_candidates_from_impls"); - // Essentially any user-written impl will match with an error type, // so creating `ImplCandidates` isn't useful. However, we might // end up finding a candidate elsewhere (e.g. a `BuiltinCandidate` for `Sized`) @@ -352,6 +355,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { if self.fast_reject_trait_refs(obligation, &impl_trait_ref.0) { return; } + if self.reject_fn_ptr_impls( + impl_def_id, + obligation, + impl_trait_ref.skip_binder().self_ty(), + ) { + return; + } self.infcx.probe(|_| { if let Ok(_substs) = self.match_impl(impl_def_id, impl_trait_ref, obligation) { @@ -362,6 +372,99 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ); } + /// The various `impl Trait for T` in libcore are more like builtin impls for all function items + /// and function pointers and less like blanket impls. Rejecting them when they can't possibly apply (because + /// the obligation's self-type does not implement `FnPtr`) avoids reporting that the self type does not implement + /// `FnPtr`, when we wanted to report that it doesn't implement `Trait`. + #[instrument(level = "trace", skip(self), ret)] + fn reject_fn_ptr_impls( + &self, + impl_def_id: DefId, + obligation: &TraitObligation<'tcx>, + impl_self_ty: Ty<'tcx>, + ) -> bool { + // Let `impl Trait for Vec` go through the normal rejection path. + if !matches!(impl_self_ty.kind(), ty::Param(..)) { + return false; + } + let Some(fn_ptr_trait) = self.tcx().lang_items().fn_ptr_trait() else { + return false; + }; + + for &(predicate, _) in self.tcx().predicates_of(impl_def_id).predicates { + let ty::PredicateKind::Clause(ty::Clause::Trait(pred)) + = predicate.kind().skip_binder() else { continue }; + if fn_ptr_trait != pred.trait_ref.def_id { + continue; + } + trace!(?pred); + // Not the bound we're looking for + if pred.self_ty() != impl_self_ty { + continue; + } + + match obligation.self_ty().skip_binder().kind() { + // Fast path to avoid evaluating an obligation that trivally holds. + // There may be more bounds, but these are checked by the regular path. + ty::FnPtr(..) => return false, + // These may potentially implement `FnPtr` + ty::Placeholder(..) + | ty::Dynamic(_, _, _) + | ty::Alias(_, _) + | ty::Infer(_) + | ty::Param(..) => {} + + ty::Bound(_, _) => span_bug!( + obligation.cause.span(), + "cannot have escaping bound var in self type of {obligation:#?}" + ), + // These can't possibly implement `FnPtr` as they are concrete types + // and not `FnPtr` + ty::Bool + | ty::Char + | ty::Int(_) + | ty::Uint(_) + | ty::Float(_) + | ty::Adt(_, _) + | ty::Foreign(_) + | ty::Str + | ty::Array(_, _) + | ty::Slice(_) + | ty::RawPtr(_) + | ty::Ref(_, _, _) + | ty::Closure(_, _) + | ty::Generator(_, _, _) + | ty::GeneratorWitness(_) + | ty::GeneratorWitnessMIR(_, _) + | ty::Never + | ty::Tuple(_) + | ty::Error(_) => return true, + // FIXME: Function definitions could actually implement `FnPtr` by + // casting the ZST function def to a function pointer. + ty::FnDef(_, _) => return true, + } + + // Generic params can implement `FnPtr` if the predicate + // holds within its own environment. + let obligation = Obligation::new( + self.tcx(), + obligation.cause.clone(), + obligation.param_env, + self.tcx().mk_predicate(obligation.predicate.map_bound(|mut pred| { + pred.trait_ref = + self.tcx().mk_trait_ref(fn_ptr_trait, [pred.trait_ref.self_ty()]); + ty::PredicateKind::Clause(ty::Clause::Trait(pred)) + })), + ); + if let Ok(r) = self.infcx.evaluate_obligation(&obligation) { + if !r.may_apply() { + return true; + } + } + } + false + } + fn assemble_candidates_from_auto_impls( &mut self, obligation: &TraitObligation<'tcx>, @@ -853,13 +956,50 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { return; } - let usize_layout = - self.tcx().layout_of(ty::ParamEnv::empty().and(self.tcx().types.usize)).unwrap().layout; if let Ok(layout) = self.tcx().layout_of(obligation.param_env.and(self_ty)) - && layout.layout.size() == usize_layout.size() - && layout.layout.align().abi == usize_layout.align().abi + && layout.layout.size() == self.tcx().data_layout.pointer_size + && layout.layout.align().abi == self.tcx().data_layout.pointer_align.abi { candidates.vec.push(BuiltinCandidate { has_nested: false }); } } + + fn assemble_candidates_for_fn_ptr_trait( + &mut self, + obligation: &TraitObligation<'tcx>, + candidates: &mut SelectionCandidateSet<'tcx>, + ) { + let self_ty = self.infcx.shallow_resolve(obligation.self_ty()); + match self_ty.skip_binder().kind() { + ty::FnPtr(_) => candidates.vec.push(BuiltinCandidate { has_nested: false }), + ty::Bool + | ty::Char + | ty::Int(_) + | ty::Uint(_) + | ty::Float(_) + | ty::Adt(..) + | ty::Foreign(..) + | ty::Str + | ty::Array(..) + | ty::Slice(_) + | ty::RawPtr(_) + | ty::Ref(..) + | ty::FnDef(..) + | ty::Placeholder(..) + | ty::Dynamic(..) + | ty::Closure(..) + | ty::Generator(..) + | ty::GeneratorWitness(..) + | ty::GeneratorWitnessMIR(..) + | ty::Never + | ty::Tuple(..) + | ty::Alias(..) + | ty::Param(..) + | ty::Bound(..) + | ty::Error(_) => {} + ty::Infer(_) => { + candidates.ambiguous = true; + } + } + } } diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 2eaeca73da7..ad70154c98e 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -243,7 +243,8 @@ fn resolve_associated_item<'tcx>( } } traits::ImplSource::Builtin(..) => { - if Some(trait_ref.def_id) == tcx.lang_items().clone_trait() { + let lang_items = tcx.lang_items(); + if Some(trait_ref.def_id) == lang_items.clone_trait() { // FIXME(eddyb) use lang items for methods instead of names. let name = tcx.item_name(trait_item_id); if name == sym::clone { @@ -270,6 +271,22 @@ fn resolve_associated_item<'tcx>( let substs = tcx.erase_regions(rcvr_substs); Some(ty::Instance::new(trait_item_id, substs)) } + } else if Some(trait_ref.def_id) == lang_items.fn_ptr_trait() { + if lang_items.fn_ptr_addr() == Some(trait_item_id) { + let self_ty = trait_ref.self_ty(); + if !matches!(self_ty.kind(), ty::FnPtr(..)) { + return Ok(None); + } + Some(Instance { + def: ty::InstanceDef::FnPtrAddrShim(trait_item_id, self_ty), + substs: rcvr_substs, + }) + } else { + tcx.sess.span_fatal( + tcx.def_span(trait_item_id), + "`FnPtrAddr` trait with unexpected assoc item", + ) + } } else { None } diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 9a0fd1f5f51..c0cb12df5b0 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -922,3 +922,18 @@ mod copy_impls { #[stable(feature = "rust1", since = "1.0.0")] impl Copy for &T {} } + +/// A common trait implemented by all function pointers. +#[unstable( + feature = "fn_ptr_trait", + issue = "none", + reason = "internal trait for implementing various traits for all function pointers" +)] +#[lang = "fn_ptr_trait"] +#[cfg(not(bootstrap))] +#[rustc_deny_explicit_impl] +pub trait FnPtr { + /// Returns the address of the function pointer. + #[lang = "fn_ptr_addr"] + fn addr(self) -> *const (); +} diff --git a/tests/ui/fn/fn-ptr-trait.rs b/tests/ui/fn/fn-ptr-trait.rs new file mode 100644 index 00000000000..45918ae5b61 --- /dev/null +++ b/tests/ui/fn/fn-ptr-trait.rs @@ -0,0 +1,9 @@ +#![feature(fn_ptr_trait)] +// check-pass + +use std::marker::FnPtr; + +trait Foo {} +impl Foo for Vec where T: FnPtr {} + +fn main() {} From 9e27c6c133b6710510f1a2ff94a943cb61efbc52 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 7 Mar 2023 08:04:34 +0000 Subject: [PATCH 172/346] Some tracing/instrument cleanups --- compiler/rustc_middle/src/ty/mod.rs | 23 ++----------------- .../traits/specialize/specialization_graph.rs | 9 +++----- 2 files changed, 5 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 48b400f7c97..c9dd3e499a8 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2279,6 +2279,7 @@ impl<'tcx> TyCtxt<'tcx> { /// Returns `true` if the impls are the same polarity and the trait either /// has no items or is annotated `#[marker]` and prevents item overrides. + #[instrument(level = "debug", skip(self), ret)] pub fn impls_are_allowed_to_overlap( self, def_id1: DefId, @@ -2297,19 +2298,11 @@ impl<'tcx> TyCtxt<'tcx> { match (self.impl_polarity(def_id1), self.impl_polarity(def_id2)) { (ImplPolarity::Reservation, _) | (_, ImplPolarity::Reservation) => { // `#[rustc_reservation_impl]` impls don't overlap with anything - debug!( - "impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted) (reservations)", - def_id1, def_id2 - ); return Some(ImplOverlapKind::Permitted { marker: false }); } (ImplPolarity::Positive, ImplPolarity::Negative) | (ImplPolarity::Negative, ImplPolarity::Positive) => { // `impl AutoTrait for Type` + `impl !AutoTrait for Type` - debug!( - "impls_are_allowed_to_overlap({:?}, {:?}) - None (differing polarities)", - def_id1, def_id2 - ); return None; } (ImplPolarity::Positive, ImplPolarity::Positive) @@ -2324,30 +2317,18 @@ impl<'tcx> TyCtxt<'tcx> { }; if is_marker_overlap { - debug!( - "impls_are_allowed_to_overlap({:?}, {:?}) = Some(Permitted) (marker overlap)", - def_id1, def_id2 - ); 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) { if self_ty1 == self_ty2 { - debug!( - "impls_are_allowed_to_overlap({:?}, {:?}) - issue #33140 HACK", - def_id1, def_id2 - ); return Some(ImplOverlapKind::Issue33140); } else { - debug!( - "impls_are_allowed_to_overlap({:?}, {:?}) - found {:?} != {:?}", - def_id1, def_id2, self_ty1, self_ty2 - ); + debug!("found {self_ty1:?} != {self_ty2:?}"); } } } - debug!("impls_are_allowed_to_overlap({:?}, {:?}) = None", def_id1, def_id2); None } } diff --git a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs index 11eb968a415..aa5c624f471 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs @@ -21,6 +21,7 @@ pub struct FutureCompatOverlapError<'tcx> { } /// The result of attempting to insert an impl into a group of children. +#[derive(Debug)] enum Inserted<'tcx> { /// The impl was inserted as a new child in this group of children. BecameNewSibling(Option>), @@ -82,6 +83,7 @@ impl<'tcx> ChildrenExt<'tcx> for Children { /// Attempt to insert an impl into this set of children, while comparing for /// specialization relationships. + #[instrument(level = "debug", skip(self, tcx), ret)] fn insert( &mut self, tcx: TyCtxt<'tcx>, @@ -92,18 +94,13 @@ impl<'tcx> ChildrenExt<'tcx> for Children { let mut last_lint = None; let mut replace_children = Vec::new(); - debug!("insert(impl_def_id={:?}, simplified_self={:?})", impl_def_id, simplified_self,); - let possible_siblings = match simplified_self { Some(st) => PotentialSiblings::Filtered(filtered_children(self, st)), None => PotentialSiblings::Unfiltered(iter_children(self)), }; for possible_sibling in possible_siblings { - debug!( - "insert: impl_def_id={:?}, simplified_self={:?}, possible_sibling={:?}", - impl_def_id, simplified_self, possible_sibling, - ); + debug!(?possible_sibling); let create_overlap_error = |overlap: traits::coherence::OverlapResult<'tcx>| { let trait_ref = overlap.impl_header.trait_ref.unwrap(); From 5ae6caa0f04c686f0cc8a330f54390131148f899 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 6 Mar 2023 16:48:22 +0000 Subject: [PATCH 173/346] Use the FnPtr trait to avoid implementing common traits via macros --- library/core/src/marker.rs | 2 +- library/core/src/ptr/mod.rs | 267 +++++++++++++++++------------ tests/ui/issues/issue-59488.stderr | 20 --- 3 files changed, 162 insertions(+), 127 deletions(-) diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index c0cb12df5b0..74e9c55396d 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -932,7 +932,7 @@ mod copy_impls { #[lang = "fn_ptr_trait"] #[cfg(not(bootstrap))] #[rustc_deny_explicit_impl] -pub trait FnPtr { +pub trait FnPtr: Copy + Clone { /// Returns the address of the function pointer. #[lang = "fn_ptr_addr"] fn addr(self) -> *const (); diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs index 5884a8ca308..9cdfd2c21cc 100644 --- a/library/core/src/ptr/mod.rs +++ b/library/core/src/ptr/mod.rs @@ -1891,150 +1891,205 @@ pub fn hash(hashee: *const T, into: &mut S) { hashee.hash(into); } -// If this is a unary fn pointer, it adds a doc comment. -// Otherwise, it hides the docs entirely. -macro_rules! maybe_fnptr_doc { - (@ #[$meta:meta] $item:item) => { - #[doc(hidden)] - #[$meta] - $item - }; - ($a:ident @ #[$meta:meta] $item:item) => { - #[doc(fake_variadic)] - #[doc = "This trait is implemented for function pointers with up to twelve arguments."] - #[$meta] - $item - }; - ($a:ident $($rest_a:ident)+ @ #[$meta:meta] $item:item) => { - #[doc(hidden)] - #[$meta] - $item - }; -} +#[cfg(bootstrap)] +mod old_fn_ptr_impl { + use super::*; + // If this is a unary fn pointer, it adds a doc comment. + // Otherwise, it hides the docs entirely. + macro_rules! maybe_fnptr_doc { + (@ #[$meta:meta] $item:item) => { + #[doc(hidden)] + #[$meta] + $item + }; + ($a:ident @ #[$meta:meta] $item:item) => { + #[doc(fake_variadic)] + #[doc = "This trait is implemented for function pointers with up to twelve arguments."] + #[$meta] + $item + }; + ($a:ident $($rest_a:ident)+ @ #[$meta:meta] $item:item) => { + #[doc(hidden)] + #[$meta] + $item + }; + } -// FIXME(strict_provenance_magic): function pointers have buggy codegen that -// necessitates casting to a usize to get the backend to do the right thing. -// for now I will break AVR to silence *a billion* lints. We should probably -// have a proper "opaque function pointer type" to handle this kind of thing. + // FIXME(strict_provenance_magic): function pointers have buggy codegen that + // necessitates casting to a usize to get the backend to do the right thing. + // for now I will break AVR to silence *a billion* lints. We should probably + // have a proper "opaque function pointer type" to handle this kind of thing. -// Impls for function pointers -macro_rules! fnptr_impls_safety_abi { - ($FnTy: ty, $($Arg: ident),*) => { + // Impls for function pointers + macro_rules! fnptr_impls_safety_abi { + ($FnTy: ty, $($Arg: ident),*) => { fnptr_impls_safety_abi! { #[stable(feature = "fnptr_impls", since = "1.4.0")] $FnTy, $($Arg),* } }; (@c_unwind $FnTy: ty, $($Arg: ident),*) => { fnptr_impls_safety_abi! { #[unstable(feature = "c_unwind", issue = "74990")] $FnTy, $($Arg),* } }; (#[$meta:meta] $FnTy: ty, $($Arg: ident),*) => { - maybe_fnptr_doc! { - $($Arg)* @ - #[$meta] - impl PartialEq for $FnTy { - #[inline] - fn eq(&self, other: &Self) -> bool { - *self as usize == *other as usize + maybe_fnptr_doc! { + $($Arg)* @ + #[$meta] + impl PartialEq for $FnTy { + #[inline] + fn eq(&self, other: &Self) -> bool { + *self as usize == *other as usize + } } } - } - maybe_fnptr_doc! { - $($Arg)* @ - #[$meta] - impl Eq for $FnTy {} - } + maybe_fnptr_doc! { + $($Arg)* @ + #[$meta] + impl Eq for $FnTy {} + } - maybe_fnptr_doc! { - $($Arg)* @ - #[$meta] - impl PartialOrd for $FnTy { - #[inline] - fn partial_cmp(&self, other: &Self) -> Option { - (*self as usize).partial_cmp(&(*other as usize)) + maybe_fnptr_doc! { + $($Arg)* @ + #[$meta] + impl PartialOrd for $FnTy { + #[inline] + fn partial_cmp(&self, other: &Self) -> Option { + (*self as usize).partial_cmp(&(*other as usize)) + } } } - } - maybe_fnptr_doc! { - $($Arg)* @ - #[$meta] - impl Ord for $FnTy { - #[inline] - fn cmp(&self, other: &Self) -> Ordering { - (*self as usize).cmp(&(*other as usize)) + maybe_fnptr_doc! { + $($Arg)* @ + #[$meta] + impl Ord for $FnTy { + #[inline] + fn cmp(&self, other: &Self) -> Ordering { + (*self as usize).cmp(&(*other as usize)) + } } } - } - maybe_fnptr_doc! { - $($Arg)* @ - #[$meta] - impl hash::Hash for $FnTy { - fn hash(&self, state: &mut HH) { - state.write_usize(*self as usize) + maybe_fnptr_doc! { + $($Arg)* @ + #[$meta] + impl hash::Hash for $FnTy { + fn hash(&self, state: &mut HH) { + state.write_usize(*self as usize) + } } } - } - maybe_fnptr_doc! { - $($Arg)* @ - #[$meta] - impl fmt::Pointer for $FnTy { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::pointer_fmt_inner(*self as usize, f) + maybe_fnptr_doc! { + $($Arg)* @ + #[$meta] + impl fmt::Pointer for $FnTy { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::pointer_fmt_inner(*self as usize, f) + } } } - } - maybe_fnptr_doc! { - $($Arg)* @ - #[$meta] - impl fmt::Debug for $FnTy { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::pointer_fmt_inner(*self as usize, f) + maybe_fnptr_doc! { + $($Arg)* @ + #[$meta] + impl fmt::Debug for $FnTy { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::pointer_fmt_inner(*self as usize, f) + } } } } } -} -macro_rules! fnptr_impls_args { - ($($Arg: ident),+) => { - fnptr_impls_safety_abi! { extern "Rust" fn($($Arg),+) -> Ret, $($Arg),+ } - fnptr_impls_safety_abi! { extern "C" fn($($Arg),+) -> Ret, $($Arg),+ } - fnptr_impls_safety_abi! { extern "C" fn($($Arg),+ , ...) -> Ret, $($Arg),+ } + macro_rules! fnptr_impls_args { + ($($Arg: ident),+) => { + fnptr_impls_safety_abi! { extern "Rust" fn($($Arg),+) -> Ret, $($Arg),+ } + fnptr_impls_safety_abi! { extern "C" fn($($Arg),+) -> Ret, $($Arg),+ } + fnptr_impls_safety_abi! { extern "C" fn($($Arg),+ , ...) -> Ret, $($Arg),+ } fnptr_impls_safety_abi! { @c_unwind extern "C-unwind" fn($($Arg),+) -> Ret, $($Arg),+ } fnptr_impls_safety_abi! { @c_unwind extern "C-unwind" fn($($Arg),+ , ...) -> Ret, $($Arg),+ } - fnptr_impls_safety_abi! { unsafe extern "Rust" fn($($Arg),+) -> Ret, $($Arg),+ } - fnptr_impls_safety_abi! { unsafe extern "C" fn($($Arg),+) -> Ret, $($Arg),+ } - fnptr_impls_safety_abi! { unsafe extern "C" fn($($Arg),+ , ...) -> Ret, $($Arg),+ } + fnptr_impls_safety_abi! { unsafe extern "Rust" fn($($Arg),+) -> Ret, $($Arg),+ } + fnptr_impls_safety_abi! { unsafe extern "C" fn($($Arg),+) -> Ret, $($Arg),+ } + fnptr_impls_safety_abi! { unsafe extern "C" fn($($Arg),+ , ...) -> Ret, $($Arg),+ } fnptr_impls_safety_abi! { @c_unwind unsafe extern "C-unwind" fn($($Arg),+) -> Ret, $($Arg),+ } fnptr_impls_safety_abi! { @c_unwind unsafe extern "C-unwind" fn($($Arg),+ , ...) -> Ret, $($Arg),+ } - }; - () => { - // No variadic functions with 0 parameters - fnptr_impls_safety_abi! { extern "Rust" fn() -> Ret, } - fnptr_impls_safety_abi! { extern "C" fn() -> Ret, } + }; + () => { + // No variadic functions with 0 parameters + fnptr_impls_safety_abi! { extern "Rust" fn() -> Ret, } + fnptr_impls_safety_abi! { extern "C" fn() -> Ret, } fnptr_impls_safety_abi! { @c_unwind extern "C-unwind" fn() -> Ret, } - fnptr_impls_safety_abi! { unsafe extern "Rust" fn() -> Ret, } - fnptr_impls_safety_abi! { unsafe extern "C" fn() -> Ret, } + fnptr_impls_safety_abi! { unsafe extern "Rust" fn() -> Ret, } + fnptr_impls_safety_abi! { unsafe extern "C" fn() -> Ret, } fnptr_impls_safety_abi! { @c_unwind unsafe extern "C-unwind" fn() -> Ret, } - }; + }; + } + + fnptr_impls_args! {} + fnptr_impls_args! { T } + fnptr_impls_args! { A, B } + fnptr_impls_args! { A, B, C } + fnptr_impls_args! { A, B, C, D } + fnptr_impls_args! { A, B, C, D, E } + fnptr_impls_args! { A, B, C, D, E, F } + fnptr_impls_args! { A, B, C, D, E, F, G } + fnptr_impls_args! { A, B, C, D, E, F, G, H } + fnptr_impls_args! { A, B, C, D, E, F, G, H, I } + fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J } + fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K } + fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K, L } } -fnptr_impls_args! {} -fnptr_impls_args! { T } -fnptr_impls_args! { A, B } -fnptr_impls_args! { A, B, C } -fnptr_impls_args! { A, B, C, D } -fnptr_impls_args! { A, B, C, D, E } -fnptr_impls_args! { A, B, C, D, E, F } -fnptr_impls_args! { A, B, C, D, E, F, G } -fnptr_impls_args! { A, B, C, D, E, F, G, H } -fnptr_impls_args! { A, B, C, D, E, F, G, H, I } -fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J } -fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K } -fnptr_impls_args! { A, B, C, D, E, F, G, H, I, J, K, L } +#[cfg(not(bootstrap))] +mod new_fn_ptr_impl { + use super::*; + use crate::marker::FnPtr; + #[stable(feature = "fnptr_impls", since = "1.4.0")] + impl PartialEq for F { + #[inline] + fn eq(&self, other: &Self) -> bool { + self.addr() == other.addr() + } + } + #[stable(feature = "fnptr_impls", since = "1.4.0")] + impl Eq for F {} + + #[stable(feature = "fnptr_impls", since = "1.4.0")] + impl PartialOrd for F { + #[inline] + fn partial_cmp(&self, other: &Self) -> Option { + self.addr().partial_cmp(&other.addr()) + } + } + #[stable(feature = "fnptr_impls", since = "1.4.0")] + impl Ord for F { + #[inline] + fn cmp(&self, other: &Self) -> Ordering { + self.addr().cmp(&other.addr()) + } + } + + #[stable(feature = "fnptr_impls", since = "1.4.0")] + impl hash::Hash for F { + fn hash(&self, state: &mut HH) { + state.write_usize(self.addr() as _) + } + } + + #[stable(feature = "fnptr_impls", since = "1.4.0")] + impl fmt::Pointer for F { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::pointer_fmt_inner(self.addr() as _, f) + } + } + + #[stable(feature = "fnptr_impls", since = "1.4.0")] + impl fmt::Debug for F { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::pointer_fmt_inner(self.addr() as _, f) + } + } +} /// Create a `const` raw pointer to a place, without creating an intermediate reference. /// /// Creating a reference with `&`/`&mut` is only allowed if the pointer is properly aligned diff --git a/tests/ui/issues/issue-59488.stderr b/tests/ui/issues/issue-59488.stderr index d45beefa420..ac8862716c0 100644 --- a/tests/ui/issues/issue-59488.stderr +++ b/tests/ui/issues/issue-59488.stderr @@ -90,16 +90,6 @@ LL | assert_eq!(Foo::Bar, i); | ^^^^^^^^^^^^^^^^^^^^^^^ `fn(usize) -> Foo {Foo::Bar}` cannot be formatted using `{:?}` because it doesn't implement `Debug` | = help: the trait `Debug` is not implemented for fn item `fn(usize) -> Foo {Foo::Bar}` - = help: the following other types implement trait `Debug`: - extern "C" fn() -> Ret - extern "C" fn(A, B) -> Ret - extern "C" fn(A, B, ...) -> Ret - extern "C" fn(A, B, C) -> Ret - extern "C" fn(A, B, C, ...) -> Ret - extern "C" fn(A, B, C, D) -> Ret - extern "C" fn(A, B, C, D, ...) -> Ret - extern "C" fn(A, B, C, D, E) -> Ret - and 118 others = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `fn(usize) -> Foo {Foo::Bar}` doesn't implement `Debug` @@ -109,16 +99,6 @@ LL | assert_eq!(Foo::Bar, i); | ^^^^^^^^^^^^^^^^^^^^^^^ `fn(usize) -> Foo {Foo::Bar}` cannot be formatted using `{:?}` because it doesn't implement `Debug` | = help: the trait `Debug` is not implemented for fn item `fn(usize) -> Foo {Foo::Bar}` - = help: the following other types implement trait `Debug`: - extern "C" fn() -> Ret - extern "C" fn(A, B) -> Ret - extern "C" fn(A, B, ...) -> Ret - extern "C" fn(A, B, C) -> Ret - extern "C" fn(A, B, C, ...) -> Ret - extern "C" fn(A, B, C, D) -> Ret - extern "C" fn(A, B, C, D, ...) -> Ret - extern "C" fn(A, B, C, D, E) -> Ret - and 118 others = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 10 previous errors From 1b3fda4978b691b2601ed862efae2798a82ef957 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Mon, 27 Mar 2023 14:42:56 +0200 Subject: [PATCH 174/346] Use span of placeholders in format_args!() expansion. --- compiler/rustc_ast_lowering/src/format.rs | 66 +++++++++++++++-------- 1 file changed, 43 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/format.rs b/compiler/rustc_ast_lowering/src/format.rs index 72352b138cb..c41bdc44093 100644 --- a/compiler/rustc_ast_lowering/src/format.rs +++ b/compiler/rustc_ast_lowering/src/format.rs @@ -2,7 +2,7 @@ use super::LoweringContext; use rustc_ast as ast; use rustc_ast::visit::{self, Visitor}; use rustc_ast::*; -use rustc_data_structures::fx::FxIndexSet; +use rustc_data_structures::fx::FxIndexMap; use rustc_hir as hir; use rustc_span::{ sym, @@ -238,7 +238,7 @@ fn make_count<'hir>( ctx: &mut LoweringContext<'_, 'hir>, sp: Span, count: &Option, - argmap: &mut FxIndexSet<(usize, ArgumentType)>, + argmap: &mut FxIndexMap<(usize, ArgumentType), Option>, ) -> hir::Expr<'hir> { match count { Some(FormatCount::Literal(n)) => { @@ -252,7 +252,7 @@ fn make_count<'hir>( } Some(FormatCount::Argument(arg)) => { if let Ok(arg_index) = arg.index { - let (i, _) = argmap.insert_full((arg_index, ArgumentType::Usize)); + let (i, _) = argmap.insert_full((arg_index, ArgumentType::Usize), arg.span); let count_param = ctx.arena.alloc(ctx.expr_lang_item_type_relative( sp, hir::LangItem::FormatCount, @@ -291,12 +291,14 @@ fn make_format_spec<'hir>( ctx: &mut LoweringContext<'_, 'hir>, sp: Span, placeholder: &FormatPlaceholder, - argmap: &mut FxIndexSet<(usize, ArgumentType)>, + argmap: &mut FxIndexMap<(usize, ArgumentType), Option>, ) -> hir::Expr<'hir> { let position = match placeholder.argument.index { Ok(arg_index) => { - let (i, _) = - argmap.insert_full((arg_index, ArgumentType::Format(placeholder.format_trait))); + let (i, _) = argmap.insert_full( + (arg_index, ArgumentType::Format(placeholder.format_trait)), + placeholder.span, + ); ctx.expr_usize(sp, i) } Err(_) => ctx.expr( @@ -386,7 +388,7 @@ fn expand_format_args<'hir>( // Create a list of all _unique_ (argument, format trait) combinations. // E.g. "{0} {0:x} {0} {1}" -> [(0, Display), (0, LowerHex), (1, Display)] - let mut argmap = FxIndexSet::default(); + let mut argmap = FxIndexMap::default(); for piece in &fmt.template { let FormatArgsPiece::Placeholder(placeholder) = piece else { continue }; if placeholder.format_options != Default::default() { @@ -394,7 +396,10 @@ fn expand_format_args<'hir>( use_format_options = true; } if let Ok(index) = placeholder.argument.index { - if !argmap.insert((index, ArgumentType::Format(placeholder.format_trait))) { + if argmap + .insert((index, ArgumentType::Format(placeholder.format_trait)), placeholder.span) + .is_some() + { // Duplicate (argument, format trait) combination, // which we'll only put once in the args array. use_format_options = true; @@ -438,7 +443,7 @@ fn expand_format_args<'hir>( // This is an optimization, speeding up compilation about 1-2% in some cases. // See https://github.com/rust-lang/rust/pull/106770#issuecomment-1380790609 let use_simple_array = argmap.len() == arguments.len() - && argmap.iter().enumerate().all(|(i, &(j, _))| i == j) + && argmap.iter().enumerate().all(|(i, (&(j, _), _))| i == j) && arguments.iter().skip(1).all(|arg| !may_contain_yield_point(&arg.expr)); let args = if use_simple_array { @@ -452,14 +457,19 @@ fn expand_format_args<'hir>( let elements: Vec<_> = arguments .iter() .zip(argmap) - .map(|(arg, (_, ty))| { - let sp = arg.expr.span.with_ctxt(macsp.ctxt()); + .map(|(arg, ((_, ty), placeholder_span))| { + let placeholder_span = + placeholder_span.unwrap_or(arg.expr.span).with_ctxt(macsp.ctxt()); + let arg_span = match arg.kind { + FormatArgumentKind::Captured(_) => placeholder_span, + _ => arg.expr.span.with_ctxt(macsp.ctxt()), + }; let arg = ctx.lower_expr(&arg.expr); let ref_arg = ctx.arena.alloc(ctx.expr( - sp, + arg_span, hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Not, arg), )); - make_argument(ctx, sp, ref_arg, ty) + make_argument(ctx, placeholder_span, ref_arg, ty) }) .collect(); ctx.expr_array_ref(macsp, ctx.arena.alloc_from_iter(elements)) @@ -475,16 +485,26 @@ fn expand_format_args<'hir>( // } let args_ident = Ident::new(sym::args, macsp); let (args_pat, args_hir_id) = ctx.pat_ident(macsp, args_ident); - let args = ctx.arena.alloc_from_iter(argmap.iter().map(|&(arg_index, ty)| { - let arg = &arguments[arg_index]; - let sp = arg.expr.span.with_ctxt(macsp.ctxt()); - let args_ident_expr = ctx.expr_ident(macsp, args_ident, args_hir_id); - let arg = ctx.arena.alloc(ctx.expr( - sp, - hir::ExprKind::Field(args_ident_expr, Ident::new(sym::integer(arg_index), macsp)), - )); - make_argument(ctx, sp, arg, ty) - })); + let args = ctx.arena.alloc_from_iter(argmap.iter().map( + |(&(arg_index, ty), &placeholder_span)| { + let arg = &arguments[arg_index]; + let placeholder_span = + placeholder_span.unwrap_or(arg.expr.span).with_ctxt(macsp.ctxt()); + let arg_span = match arg.kind { + FormatArgumentKind::Captured(_) => placeholder_span, + _ => arg.expr.span.with_ctxt(macsp.ctxt()), + }; + let args_ident_expr = ctx.expr_ident(macsp, args_ident, args_hir_id); + let arg = ctx.arena.alloc(ctx.expr( + arg_span, + hir::ExprKind::Field( + args_ident_expr, + Ident::new(sym::integer(arg_index), macsp), + ), + )); + make_argument(ctx, placeholder_span, arg, ty) + }, + )); let elements: Vec<_> = arguments .iter() .map(|arg| { From 7f395f1effa518708b6b6e30429ba799cf4ba6f6 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Mon, 27 Mar 2023 14:43:17 +0200 Subject: [PATCH 175/346] Bless UI tests. --- tests/ui/consts/const-eval/format.stderr | 8 ++++---- tests/ui/fmt/ifmt-bad-arg.stderr | 14 ++++++-------- tests/ui/fmt/ifmt-unimpl.stderr | 4 +++- tests/ui/suggestions/issue-97760.stderr | 4 ++-- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/tests/ui/consts/const-eval/format.stderr b/tests/ui/consts/const-eval/format.stderr index c39920d444d..70a1abb0a95 100644 --- a/tests/ui/consts/const-eval/format.stderr +++ b/tests/ui/consts/const-eval/format.stderr @@ -1,8 +1,8 @@ error[E0015]: cannot call non-const formatting macro in constant functions - --> $DIR/format.rs:2:20 + --> $DIR/format.rs:2:13 | LL | panic!("{:?}", 0); - | ^ + | ^^^^ | = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: this error originates in the macro `$crate::const_format_args` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -17,10 +17,10 @@ LL | panic!("{:?}", 0); = note: this error originates in the macro `$crate::const_format_args` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0015]: cannot call non-const formatting macro in constant functions - --> $DIR/format.rs:8:22 + --> $DIR/format.rs:8:15 | LL | println!("{:?}", 0); - | ^ + | ^^^^ | = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/tests/ui/fmt/ifmt-bad-arg.stderr b/tests/ui/fmt/ifmt-bad-arg.stderr index d716bbe51af..bf18fb315c9 100644 --- a/tests/ui/fmt/ifmt-bad-arg.stderr +++ b/tests/ui/fmt/ifmt-bad-arg.stderr @@ -300,10 +300,9 @@ error[E0308]: mismatched types --> $DIR/ifmt-bad-arg.rs:78:32 | LL | println!("{} {:.*} {}", 1, 3.2, 4); - | ^^^ - | | - | expected `&usize`, found `&{float}` - | arguments to this function are incorrect + | -- ^^^ expected `&usize`, found `&{float}` + | | + | arguments to this function are incorrect | = note: expected reference `&usize` found reference `&{float}` @@ -315,10 +314,9 @@ error[E0308]: mismatched types --> $DIR/ifmt-bad-arg.rs:81:35 | LL | println!("{} {:07$.*} {}", 1, 3.2, 4); - | ^^^ - | | - | expected `&usize`, found `&{float}` - | arguments to this function are incorrect + | -- ^^^ expected `&usize`, found `&{float}` + | | + | arguments to this function are incorrect | = note: expected reference `&usize` found reference `&{float}` diff --git a/tests/ui/fmt/ifmt-unimpl.stderr b/tests/ui/fmt/ifmt-unimpl.stderr index 3480a2ec815..dc2dee3f341 100644 --- a/tests/ui/fmt/ifmt-unimpl.stderr +++ b/tests/ui/fmt/ifmt-unimpl.stderr @@ -2,7 +2,9 @@ error[E0277]: the trait bound `str: UpperHex` is not satisfied --> $DIR/ifmt-unimpl.rs:2:21 | LL | format!("{:X}", "3"); - | ^^^ the trait `UpperHex` is not implemented for `str` + | ---- ^^^ the trait `UpperHex` is not implemented for `str` + | | + | required by a bound introduced by this call | = help: the following other types implement trait `UpperHex`: &T diff --git a/tests/ui/suggestions/issue-97760.stderr b/tests/ui/suggestions/issue-97760.stderr index bbcc3693fff..5415c247c8f 100644 --- a/tests/ui/suggestions/issue-97760.stderr +++ b/tests/ui/suggestions/issue-97760.stderr @@ -1,8 +1,8 @@ error[E0277]: `::Item` doesn't implement `std::fmt::Display` - --> $DIR/issue-97760.rs:4:20 + --> $DIR/issue-97760.rs:4:19 | LL | println!("{x}"); - | ^ `::Item` cannot be formatted with the default formatter + | ^^^ `::Item` cannot be formatted with the default formatter | = help: the trait `std::fmt::Display` is not implemented for `::Item` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead From 769886cc35ce08b76839f4cf72b8af1161c432e1 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Mon, 27 Mar 2023 14:56:15 +0200 Subject: [PATCH 176/346] Bless mir-opt tests. (Only the lifetime spans changed.) --- ...mes.foo.ScalarReplacementOfAggregates.diff | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff index 225f80ed41b..f6f2344e82f 100644 --- a/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff +++ b/tests/mir-opt/sroa/lifetimes.foo.ScalarReplacementOfAggregates.diff @@ -19,12 +19,12 @@ let mut _17: &[core::fmt::ArgumentV1<'_>; 2]; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL let _18: &[core::fmt::ArgumentV1<'_>; 2]; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL let _19: [core::fmt::ArgumentV1<'_>; 2]; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL - let mut _20: core::fmt::ArgumentV1<'_>; // in scope 0 at $DIR/lifetimes.rs:+10:21: +10:22 - let mut _21: &std::boxed::Box; // in scope 0 at $DIR/lifetimes.rs:+10:21: +10:22 - let _22: &std::boxed::Box; // in scope 0 at $DIR/lifetimes.rs:+10:21: +10:22 - let mut _23: core::fmt::ArgumentV1<'_>; // in scope 0 at $DIR/lifetimes.rs:+10:25: +10:26 - let mut _24: &u32; // in scope 0 at $DIR/lifetimes.rs:+10:25: +10:26 - let _25: &u32; // in scope 0 at $DIR/lifetimes.rs:+10:25: +10:26 + let mut _20: core::fmt::ArgumentV1<'_>; // in scope 0 at $DIR/lifetimes.rs:+10:20: +10:23 + let mut _21: &std::boxed::Box; // in scope 0 at $DIR/lifetimes.rs:+10:20: +10:23 + let _22: &std::boxed::Box; // in scope 0 at $DIR/lifetimes.rs:+10:20: +10:23 + let mut _23: core::fmt::ArgumentV1<'_>; // in scope 0 at $DIR/lifetimes.rs:+10:24: +10:27 + let mut _24: &u32; // in scope 0 at $DIR/lifetimes.rs:+10:24: +10:27 + let _25: &u32; // in scope 0 at $DIR/lifetimes.rs:+10:24: +10:27 let mut _27: bool; // in scope 0 at $DIR/lifetimes.rs:+12:1: +12:2 let mut _28: isize; // in scope 0 at $DIR/lifetimes.rs:+12:1: +12:2 let mut _29: isize; // in scope 0 at $DIR/lifetimes.rs:+12:1: +12:2 @@ -108,34 +108,34 @@ StorageLive(_17); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL StorageLive(_18); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL StorageLive(_19); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL - StorageLive(_20); // scope 4 at $DIR/lifetimes.rs:+10:21: +10:22 - StorageLive(_21); // scope 4 at $DIR/lifetimes.rs:+10:21: +10:22 - StorageLive(_22); // scope 4 at $DIR/lifetimes.rs:+10:21: +10:22 - _22 = &_8; // scope 4 at $DIR/lifetimes.rs:+10:21: +10:22 - _21 = &(*_22); // scope 4 at $DIR/lifetimes.rs:+10:21: +10:22 - _20 = core::fmt::ArgumentV1::<'_>::new_display::>(move _21) -> bb3; // scope 4 at $DIR/lifetimes.rs:+10:21: +10:22 + StorageLive(_20); // scope 4 at $DIR/lifetimes.rs:+10:20: +10:23 + StorageLive(_21); // scope 4 at $DIR/lifetimes.rs:+10:20: +10:23 + StorageLive(_22); // scope 4 at $DIR/lifetimes.rs:+10:20: +10:23 + _22 = &_8; // scope 4 at $DIR/lifetimes.rs:+10:20: +10:23 + _21 = &(*_22); // scope 4 at $DIR/lifetimes.rs:+10:20: +10:23 + _20 = core::fmt::ArgumentV1::<'_>::new_display::>(move _21) -> bb3; // scope 4 at $DIR/lifetimes.rs:+10:20: +10:23 // mir::Constant - // + span: $DIR/lifetimes.rs:27:21: 27:22 + // + span: $DIR/lifetimes.rs:27:20: 27:23 // + user_ty: UserType(4) // + literal: Const { ty: for<'b> fn(&'b Box) -> core::fmt::ArgumentV1<'b> {core::fmt::ArgumentV1::<'_>::new_display::>}, val: Value() } } bb3: { - StorageDead(_21); // scope 4 at $DIR/lifetimes.rs:+10:21: +10:22 - StorageLive(_23); // scope 4 at $DIR/lifetimes.rs:+10:25: +10:26 - StorageLive(_24); // scope 4 at $DIR/lifetimes.rs:+10:25: +10:26 - StorageLive(_25); // scope 4 at $DIR/lifetimes.rs:+10:25: +10:26 - _25 = &_6; // scope 4 at $DIR/lifetimes.rs:+10:25: +10:26 - _24 = &(*_25); // scope 4 at $DIR/lifetimes.rs:+10:25: +10:26 - _23 = core::fmt::ArgumentV1::<'_>::new_display::(move _24) -> bb4; // scope 4 at $DIR/lifetimes.rs:+10:25: +10:26 + StorageDead(_21); // scope 4 at $DIR/lifetimes.rs:+10:22: +10:23 + StorageLive(_23); // scope 4 at $DIR/lifetimes.rs:+10:24: +10:27 + StorageLive(_24); // scope 4 at $DIR/lifetimes.rs:+10:24: +10:27 + StorageLive(_25); // scope 4 at $DIR/lifetimes.rs:+10:24: +10:27 + _25 = &_6; // scope 4 at $DIR/lifetimes.rs:+10:24: +10:27 + _24 = &(*_25); // scope 4 at $DIR/lifetimes.rs:+10:24: +10:27 + _23 = core::fmt::ArgumentV1::<'_>::new_display::(move _24) -> bb4; // scope 4 at $DIR/lifetimes.rs:+10:24: +10:27 // mir::Constant - // + span: $DIR/lifetimes.rs:27:25: 27:26 + // + span: $DIR/lifetimes.rs:27:24: 27:27 // + user_ty: UserType(5) // + literal: Const { ty: for<'b> fn(&'b u32) -> core::fmt::ArgumentV1<'b> {core::fmt::ArgumentV1::<'_>::new_display::}, val: Value() } } bb4: { - StorageDead(_24); // scope 4 at $DIR/lifetimes.rs:+10:25: +10:26 + StorageDead(_24); // scope 4 at $DIR/lifetimes.rs:+10:26: +10:27 _19 = [move _20, move _23]; // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL StorageDead(_23); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL StorageDead(_20); // scope 4 at $SRC_DIR/std/src/macros.rs:LL:COL From 6c72a002a68043f9bc67399c43a66e8ab68ca20b Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Mon, 27 Mar 2023 14:43:25 +0200 Subject: [PATCH 177/346] Add test for span of implicit format args captures. --- tests/ui/fmt/format-args-argument-span.rs | 22 ++++++++ tests/ui/fmt/format-args-argument-span.stderr | 51 +++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 tests/ui/fmt/format-args-argument-span.rs create mode 100644 tests/ui/fmt/format-args-argument-span.stderr diff --git a/tests/ui/fmt/format-args-argument-span.rs b/tests/ui/fmt/format-args-argument-span.rs new file mode 100644 index 00000000000..c7acb08f84b --- /dev/null +++ b/tests/ui/fmt/format-args-argument-span.rs @@ -0,0 +1,22 @@ +// check-compile + +struct DisplayOnly; + +impl std::fmt::Display for DisplayOnly { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + unimplemented!() + } +} + +fn main() { + let x = Some(1); + println!("{x:?} {x} {x:?}"); + //~^ ERROR: `Option<{integer}>` doesn't implement `std::fmt::Display` + println!("{x:?} {x} {x:?}", x = Some(1)); + //~^ ERROR: `Option<{integer}>` doesn't implement `std::fmt::Display` + let x = DisplayOnly; + println!("{x} {x:?} {x}"); + //~^ ERROR: `DisplayOnly` doesn't implement `Debug` + println!("{x} {x:?} {x}", x = DisplayOnly); + //~^ ERROR: `DisplayOnly` doesn't implement `Debug` +} diff --git a/tests/ui/fmt/format-args-argument-span.stderr b/tests/ui/fmt/format-args-argument-span.stderr new file mode 100644 index 00000000000..b060b2cd339 --- /dev/null +++ b/tests/ui/fmt/format-args-argument-span.stderr @@ -0,0 +1,51 @@ +error[E0277]: `Option<{integer}>` doesn't implement `std::fmt::Display` + --> $DIR/format-args-argument-span.rs:13:21 + | +LL | println!("{x:?} {x} {x:?}"); + | ^^^ `Option<{integer}>` cannot be formatted with the default formatter + | + = help: the trait `std::fmt::Display` is not implemented for `Option<{integer}>` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead + = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: `Option<{integer}>` doesn't implement `std::fmt::Display` + --> $DIR/format-args-argument-span.rs:15:37 + | +LL | println!("{x:?} {x} {x:?}", x = Some(1)); + | ^^^^^^^ `Option<{integer}>` cannot be formatted with the default formatter + | + = help: the trait `std::fmt::Display` is not implemented for `Option<{integer}>` + = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead + = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: `DisplayOnly` doesn't implement `Debug` + --> $DIR/format-args-argument-span.rs:18:19 + | +LL | println!("{x} {x:?} {x}"); + | ^^^^^ `DisplayOnly` cannot be formatted using `{:?}` + | + = help: the trait `Debug` is not implemented for `DisplayOnly` + = note: add `#[derive(Debug)]` to `DisplayOnly` or manually `impl Debug for DisplayOnly` + = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider annotating `DisplayOnly` with `#[derive(Debug)]` + | +LL | #[derive(Debug)] + | + +error[E0277]: `DisplayOnly` doesn't implement `Debug` + --> $DIR/format-args-argument-span.rs:20:35 + | +LL | println!("{x} {x:?} {x}", x = DisplayOnly); + | ^^^^^^^^^^^ `DisplayOnly` cannot be formatted using `{:?}` + | + = help: the trait `Debug` is not implemented for `DisplayOnly` + = note: add `#[derive(Debug)]` to `DisplayOnly` or manually `impl Debug for DisplayOnly` + = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider annotating `DisplayOnly` with `#[derive(Debug)]` + | +LL | #[derive(Debug)] + | + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0277`. From e29b27b4a4c6b6fc80e38d2747c8076a59475c03 Mon Sep 17 00:00:00 2001 From: The 8472 Date: Mon, 13 Mar 2023 20:07:53 +0100 Subject: [PATCH 178/346] replace advance_by returning usize with Result<(), NonZeroUsize> --- .../src/collections/vec_deque/into_iter.rs | 15 ++++--- .../alloc/src/collections/vec_deque/iter.rs | 26 ++++++----- .../src/collections/vec_deque/iter_mut.rs | 27 ++++++----- library/alloc/src/vec/into_iter.rs | 9 ++-- library/alloc/tests/vec.rs | 19 ++++---- library/core/src/array/iter.rs | 9 ++-- .../core/src/iter/adapters/by_ref_sized.rs | 5 ++- library/core/src/iter/adapters/chain.rs | 37 +++++++-------- library/core/src/iter/adapters/copied.rs | 5 ++- library/core/src/iter/adapters/cycle.rs | 23 +++++----- library/core/src/iter/adapters/enumerate.rs | 15 ++++--- library/core/src/iter/adapters/flatten.rs | 29 ++++++------ library/core/src/iter/adapters/rev.rs | 5 ++- library/core/src/iter/adapters/skip.rs | 23 ++++++---- library/core/src/iter/adapters/take.rs | 19 +++++--- library/core/src/iter/range.rs | 25 ++++++----- library/core/src/iter/sources/repeat.rs | 9 ++-- library/core/src/iter/sources/repeat_n.rs | 10 +++-- library/core/src/iter/traits/double_ended.rs | 19 ++++---- library/core/src/iter/traits/iterator.rs | 21 ++++----- library/core/src/ops/index_range.rs | 9 ++-- library/core/src/slice/iter/macros.rs | 8 ++-- library/core/tests/array.rs | 33 +++++++------- library/core/tests/iter/adapters/chain.rs | 41 ++++++++--------- library/core/tests/iter/adapters/enumerate.rs | 15 +++++++ library/core/tests/iter/adapters/flatten.rs | 45 ++++++++++--------- library/core/tests/iter/adapters/skip.rs | 13 +++--- library/core/tests/iter/adapters/take.rs | 23 +++++----- library/core/tests/iter/range.rs | 19 ++++---- library/core/tests/iter/traits/iterator.rs | 34 +++++++------- library/core/tests/slice.rs | 21 ++++----- 31 files changed, 340 insertions(+), 271 deletions(-) diff --git a/library/alloc/src/collections/vec_deque/into_iter.rs b/library/alloc/src/collections/vec_deque/into_iter.rs index 8ba963b790d..c277c62ad14 100644 --- a/library/alloc/src/collections/vec_deque/into_iter.rs +++ b/library/alloc/src/collections/vec_deque/into_iter.rs @@ -1,4 +1,5 @@ use core::iter::{FusedIterator, TrustedLen}; +use core::num::NonZeroUsize; use core::{array, fmt, mem::MaybeUninit, ops::Try, ptr}; use crate::alloc::{Allocator, Global}; @@ -54,15 +55,16 @@ impl Iterator for IntoIter { } #[inline] - fn advance_by(&mut self, n: usize) -> usize { - if self.inner.len < n { + fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { + let rem = if self.inner.len < n { let len = self.inner.len; self.inner.clear(); len - n } else { self.inner.drain(..n); 0 - } + }; + NonZeroUsize::new(rem).map_or(Ok(()), Err) } #[inline] @@ -182,15 +184,16 @@ impl DoubleEndedIterator for IntoIter { } #[inline] - fn advance_back_by(&mut self, n: usize) -> usize { + fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { let len = self.inner.len; - if len >= n { + let rem = if len >= n { self.inner.truncate(len - n); 0 } else { self.inner.clear(); n - len - } + }; + NonZeroUsize::new(rem).map_or(Ok(()), Err) } fn try_rfold(&mut self, mut init: B, mut f: F) -> R diff --git a/library/alloc/src/collections/vec_deque/iter.rs b/library/alloc/src/collections/vec_deque/iter.rs index 5b91c1635f0..646a2a991e7 100644 --- a/library/alloc/src/collections/vec_deque/iter.rs +++ b/library/alloc/src/collections/vec_deque/iter.rs @@ -1,4 +1,5 @@ use core::iter::{FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce}; +use core::num::NonZeroUsize; use core::ops::Try; use core::{fmt, mem, slice}; @@ -55,13 +56,15 @@ impl<'a, T> Iterator for Iter<'a, T> { } } - fn advance_by(&mut self, n: usize) -> usize { + fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { let remaining = self.i1.advance_by(n); - if remaining == 0 { - return 0; + match remaining { + Ok(()) => return Ok(()), + Err(n) => { + mem::swap(&mut self.i1, &mut self.i2); + self.i1.advance_by(n.get()) + } } - mem::swap(&mut self.i1, &mut self.i2); - self.i1.advance_by(remaining) } #[inline] @@ -125,13 +128,14 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> { } } - fn advance_back_by(&mut self, n: usize) -> usize { - let remaining = self.i2.advance_back_by(n); - if remaining == 0 { - return 0; + fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { + match self.i2.advance_back_by(n) { + Ok(()) => return Ok(()), + Err(n) => { + mem::swap(&mut self.i1, &mut self.i2); + self.i2.advance_back_by(n.get()) + } } - mem::swap(&mut self.i1, &mut self.i2); - self.i2.advance_back_by(remaining) } fn rfold(self, accum: Acc, mut f: F) -> Acc diff --git a/library/alloc/src/collections/vec_deque/iter_mut.rs b/library/alloc/src/collections/vec_deque/iter_mut.rs index 848cb3649c8..7defbb1090f 100644 --- a/library/alloc/src/collections/vec_deque/iter_mut.rs +++ b/library/alloc/src/collections/vec_deque/iter_mut.rs @@ -1,4 +1,5 @@ use core::iter::{FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce}; +use core::num::NonZeroUsize; use core::ops::Try; use core::{fmt, mem, slice}; @@ -47,13 +48,14 @@ impl<'a, T> Iterator for IterMut<'a, T> { } } - fn advance_by(&mut self, n: usize) -> usize { - let remaining = self.i1.advance_by(n); - if remaining == 0 { - return 0; + fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { + match self.i1.advance_by(n) { + Ok(()) => return Ok(()), + Err(remaining) => { + mem::swap(&mut self.i1, &mut self.i2); + self.i1.advance_by(remaining.get()) + } } - mem::swap(&mut self.i1, &mut self.i2); - self.i1.advance_by(remaining) } #[inline] @@ -117,13 +119,14 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, T> { } } - fn advance_back_by(&mut self, n: usize) -> usize { - let remaining = self.i2.advance_back_by(n); - if remaining == 0 { - return 0; + fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { + match self.i2.advance_back_by(n) { + Ok(()) => return Ok(()), + Err(remaining) => { + mem::swap(&mut self.i1, &mut self.i2); + self.i2.advance_back_by(remaining.get()) + } } - mem::swap(&mut self.i1, &mut self.i2); - self.i2.advance_back_by(remaining) } fn rfold(self, accum: Acc, mut f: F) -> Acc diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index 504ca4333be..6a05f70e437 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -11,6 +11,7 @@ use core::iter::{ }; use core::marker::PhantomData; use core::mem::{self, ManuallyDrop, MaybeUninit, SizedTypeProperties}; +use core::num::NonZeroUsize; #[cfg(not(no_global_oom_handling))] use core::ops::Deref; use core::ptr::{self, NonNull}; @@ -213,7 +214,7 @@ impl Iterator for IntoIter { } #[inline] - fn advance_by(&mut self, n: usize) -> usize { + fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { let step_size = self.len().min(n); let to_drop = ptr::slice_from_raw_parts_mut(self.ptr as *mut T, step_size); if T::IS_ZST { @@ -227,7 +228,7 @@ impl Iterator for IntoIter { unsafe { ptr::drop_in_place(to_drop); } - n - step_size + NonZeroUsize::new(n - step_size).map_or(Ok(()), Err) } #[inline] @@ -310,7 +311,7 @@ impl DoubleEndedIterator for IntoIter { } #[inline] - fn advance_back_by(&mut self, n: usize) -> usize { + fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { let step_size = self.len().min(n); if T::IS_ZST { // SAFETY: same as for advance_by() @@ -324,7 +325,7 @@ impl DoubleEndedIterator for IntoIter { unsafe { ptr::drop_in_place(to_drop); } - n - step_size + NonZeroUsize::new(n - step_size).map_or(Ok(()), Err) } } diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index e00af189fbf..3ee16f04e92 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -1,6 +1,7 @@ use core::alloc::{Allocator, Layout}; use core::assert_eq; use core::iter::IntoIterator; +use core::num::NonZeroUsize; use core::ptr::NonNull; use std::alloc::System; use std::assert_matches::assert_matches; @@ -1064,20 +1065,20 @@ fn test_into_iter_leak() { #[test] fn test_into_iter_advance_by() { let mut i = vec![1, 2, 3, 4, 5].into_iter(); - assert_eq!(i.advance_by(0), 0); - assert_eq!(i.advance_back_by(0), 0); + assert_eq!(i.advance_by(0), Ok(())); + assert_eq!(i.advance_back_by(0), Ok(())); assert_eq!(i.as_slice(), [1, 2, 3, 4, 5]); - assert_eq!(i.advance_by(1), 0); - assert_eq!(i.advance_back_by(1), 0); + assert_eq!(i.advance_by(1), Ok(())); + assert_eq!(i.advance_back_by(1), Ok(())); assert_eq!(i.as_slice(), [2, 3, 4]); - assert_eq!(i.advance_back_by(usize::MAX), usize::MAX - 3); + assert_eq!(i.advance_back_by(usize::MAX), Err(NonZeroUsize::new(usize::MAX - 3).unwrap())); - assert_eq!(i.advance_by(usize::MAX), usize::MAX); + assert_eq!(i.advance_by(usize::MAX), Err(NonZeroUsize::new(usize::MAX).unwrap())); - assert_eq!(i.advance_by(0), 0); - assert_eq!(i.advance_back_by(0), 0); + assert_eq!(i.advance_by(0), Ok(())); + assert_eq!(i.advance_back_by(0), Ok(())); assert_eq!(i.len(), 0); } @@ -1125,7 +1126,7 @@ fn test_into_iter_zst() { for _ in vec![C; 5].into_iter().rev() {} let mut it = vec![C, C].into_iter(); - assert_eq!(it.advance_by(1), 0); + assert_eq!(it.advance_by(1), Ok(())); drop(it); let mut it = vec![C, C].into_iter(); diff --git a/library/core/src/array/iter.rs b/library/core/src/array/iter.rs index 2d853dd6684..73e2c2cfbbe 100644 --- a/library/core/src/array/iter.rs +++ b/library/core/src/array/iter.rs @@ -1,5 +1,6 @@ //! Defines the `IntoIter` owned iterator for arrays. +use crate::num::NonZeroUsize; use crate::{ fmt, iter::{self, ExactSizeIterator, FusedIterator, TrustedLen}, @@ -284,7 +285,7 @@ impl Iterator for IntoIter { self.next_back() } - fn advance_by(&mut self, n: usize) -> usize { + fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { // This also moves the start, which marks them as conceptually "dropped", // so if anything goes bad then our drop impl won't double-free them. let range_to_drop = self.alive.take_prefix(n); @@ -296,7 +297,7 @@ impl Iterator for IntoIter { ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(slice)); } - remaining + NonZeroUsize::new(remaining).map_or(Ok(()), Err) } } @@ -333,7 +334,7 @@ impl DoubleEndedIterator for IntoIter { }) } - fn advance_back_by(&mut self, n: usize) -> usize { + fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { // This also moves the end, which marks them as conceptually "dropped", // so if anything goes bad then our drop impl won't double-free them. let range_to_drop = self.alive.take_suffix(n); @@ -345,7 +346,7 @@ impl DoubleEndedIterator for IntoIter { ptr::drop_in_place(MaybeUninit::slice_assume_init_mut(slice)); } - remaining + NonZeroUsize::new(remaining).map_or(Ok(()), Err) } } diff --git a/library/core/src/iter/adapters/by_ref_sized.rs b/library/core/src/iter/adapters/by_ref_sized.rs index ff28e5760d0..4e0e19ddc78 100644 --- a/library/core/src/iter/adapters/by_ref_sized.rs +++ b/library/core/src/iter/adapters/by_ref_sized.rs @@ -1,3 +1,4 @@ +use crate::num::NonZeroUsize; use crate::ops::{NeverShortCircuit, Try}; /// Like `Iterator::by_ref`, but requiring `Sized` so it can forward generics. @@ -26,7 +27,7 @@ impl Iterator for ByRefSized<'_, I> { } #[inline] - fn advance_by(&mut self, n: usize) -> usize { + fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { I::advance_by(self.0, n) } @@ -62,7 +63,7 @@ impl DoubleEndedIterator for ByRefSized<'_, I> { } #[inline] - fn advance_back_by(&mut self, n: usize) -> usize { + fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { I::advance_back_by(self.0, n) } diff --git a/library/core/src/iter/adapters/chain.rs b/library/core/src/iter/adapters/chain.rs index 965a33de1cd..2046b70c9c6 100644 --- a/library/core/src/iter/adapters/chain.rs +++ b/library/core/src/iter/adapters/chain.rs @@ -1,4 +1,5 @@ use crate::iter::{DoubleEndedIterator, FusedIterator, Iterator, TrustedLen}; +use crate::num::NonZeroUsize; use crate::ops::Try; /// An iterator that links two iterators together, in a chain. @@ -95,32 +96,32 @@ where } #[inline] - fn advance_by(&mut self, mut n: usize) -> usize { + fn advance_by(&mut self, mut n: usize) -> Result<(), NonZeroUsize> { if let Some(ref mut a) = self.a { - n = a.advance_by(n); - if n == 0 { - return n; - } + n = match a.advance_by(n) { + Ok(()) => return Ok(()), + Err(k) => k.get(), + }; self.a = None; } if let Some(ref mut b) = self.b { - n = b.advance_by(n); + return b.advance_by(n); // we don't fuse the second iterator } - n + NonZeroUsize::new(n).map_or(Ok(()), Err) } #[inline] fn nth(&mut self, mut n: usize) -> Option { if let Some(ref mut a) = self.a { n = match a.advance_by(n) { - 0 => match a.next() { + Ok(()) => match a.next() { None => 0, x => return x, }, - k => k, + Err(k) => k.get(), }; self.a = None; @@ -181,32 +182,32 @@ where } #[inline] - fn advance_back_by(&mut self, mut n: usize) -> usize { + fn advance_back_by(&mut self, mut n: usize) -> Result<(), NonZeroUsize> { if let Some(ref mut b) = self.b { - n = b.advance_back_by(n); - if n == 0 { - return n; - } + n = match b.advance_back_by(n) { + Ok(()) => return Ok(()), + Err(k) => k.get(), + }; self.b = None; } if let Some(ref mut a) = self.a { - n = a.advance_back_by(n); + return a.advance_back_by(n); // we don't fuse the second iterator } - n + NonZeroUsize::new(n).map_or(Ok(()), Err) } #[inline] fn nth_back(&mut self, mut n: usize) -> Option { if let Some(ref mut b) = self.b { n = match b.advance_back_by(n) { - 0 => match b.next_back() { + Ok(()) => match b.next_back() { None => 0, x => return x, }, - k => k, + Err(k) => k.get(), }; self.b = None; diff --git a/library/core/src/iter/adapters/copied.rs b/library/core/src/iter/adapters/copied.rs index 7533de588db..2289025d0a7 100644 --- a/library/core/src/iter/adapters/copied.rs +++ b/library/core/src/iter/adapters/copied.rs @@ -4,6 +4,7 @@ use crate::iter::adapters::{ use crate::iter::{FusedIterator, TrustedLen}; use crate::mem::MaybeUninit; use crate::mem::SizedTypeProperties; +use crate::num::NonZeroUsize; use crate::ops::Try; use crate::{array, ptr}; @@ -89,7 +90,7 @@ where } #[inline] - fn advance_by(&mut self, n: usize) -> usize { + fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { self.it.advance_by(n) } @@ -130,7 +131,7 @@ where } #[inline] - fn advance_back_by(&mut self, n: usize) -> usize { + fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { self.it.advance_back_by(n) } } diff --git a/library/core/src/iter/adapters/cycle.rs b/library/core/src/iter/adapters/cycle.rs index 2d1fcf667bf..51bd09b6eff 100644 --- a/library/core/src/iter/adapters/cycle.rs +++ b/library/core/src/iter/adapters/cycle.rs @@ -1,3 +1,4 @@ +use crate::num::NonZeroUsize; use crate::{iter::FusedIterator, ops::Try}; /// An iterator that repeats endlessly. @@ -81,22 +82,22 @@ where #[inline] #[rustc_inherit_overflow_checks] - fn advance_by(&mut self, n: usize) -> usize { - let mut n = self.iter.advance_by(n); - if n == 0 { - return n; - } + fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { + let mut n = match self.iter.advance_by(n) { + Ok(()) => return Ok(()), + Err(rem) => rem.get(), + }; while n > 0 { self.iter = self.orig.clone(); - let rem = self.iter.advance_by(n); - if rem == n { - return n; - } - n = rem; + n = match self.iter.advance_by(n) { + Ok(()) => return Ok(()), + e @ Err(rem) if rem.get() == n => return e, + Err(rem) => rem.get(), + }; } - 0 + NonZeroUsize::new(n).map_or(Ok(()), Err) } // No `fold` override, because `fold` doesn't make much sense for `Cycle`, diff --git a/library/core/src/iter/adapters/enumerate.rs b/library/core/src/iter/adapters/enumerate.rs index 30017d13a6c..479ea6d83c7 100644 --- a/library/core/src/iter/adapters/enumerate.rs +++ b/library/core/src/iter/adapters/enumerate.rs @@ -2,6 +2,7 @@ use crate::iter::adapters::{ zip::try_get_unchecked, SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce, }; use crate::iter::{FusedIterator, InPlaceIterable, TrustedLen}; +use crate::num::NonZeroUsize; use crate::ops::Try; /// An iterator that yields the current count and the element during iteration. @@ -114,10 +115,14 @@ where #[inline] #[rustc_inherit_overflow_checks] - fn advance_by(&mut self, n: usize) -> usize { - let n = self.iter.advance_by(n); - self.count += n; - n + fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { + let remaining = self.iter.advance_by(n); + let advanced = match remaining { + Ok(()) => n, + Err(rem) => n - rem.get(), + }; + self.count += advanced; + remaining } #[rustc_inherit_overflow_checks] @@ -201,7 +206,7 @@ where } #[inline] - fn advance_back_by(&mut self, n: usize) -> usize { + fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { // we do not need to update the count since that only tallies the number of items // consumed from the front. consuming items from the back can never reduce that. self.iter.advance_back_by(n) diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs index 980c4bebc97..e0308e3360f 100644 --- a/library/core/src/iter/adapters/flatten.rs +++ b/library/core/src/iter/adapters/flatten.rs @@ -1,5 +1,6 @@ use crate::fmt; use crate::iter::{DoubleEndedIterator, Fuse, FusedIterator, Iterator, Map, TrustedLen}; +use crate::num::NonZeroUsize; use crate::ops::{ControlFlow, Try}; /// An iterator that maps each element to an iterator, and yields the elements @@ -75,7 +76,7 @@ where } #[inline] - fn advance_by(&mut self, n: usize) -> usize { + fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { self.inner.advance_by(n) } @@ -120,7 +121,7 @@ where } #[inline] - fn advance_back_by(&mut self, n: usize) -> usize { + fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { self.inner.advance_back_by(n) } } @@ -236,7 +237,7 @@ where } #[inline] - fn advance_by(&mut self, n: usize) -> usize { + fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { self.inner.advance_by(n) } @@ -281,7 +282,7 @@ where } #[inline] - fn advance_back_by(&mut self, n: usize) -> usize { + fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { self.inner.advance_back_by(n) } } @@ -552,19 +553,19 @@ where #[inline] #[rustc_inherit_overflow_checks] - fn advance_by(&mut self, n: usize) -> usize { + fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { #[inline] #[rustc_inherit_overflow_checks] fn advance(n: usize, iter: &mut U) -> ControlFlow<(), usize> { match iter.advance_by(n) { - 0 => ControlFlow::Break(()), - remaining => ControlFlow::Continue(remaining), + Ok(()) => ControlFlow::Break(()), + Err(remaining) => ControlFlow::Continue(remaining.get()), } } match self.iter_try_fold(n, advance) { - ControlFlow::Continue(remaining) => remaining, - _ => 0, + ControlFlow::Continue(remaining) => NonZeroUsize::new(remaining).map_or(Ok(()), Err), + _ => Ok(()), } } @@ -642,19 +643,19 @@ where #[inline] #[rustc_inherit_overflow_checks] - fn advance_back_by(&mut self, n: usize) -> usize { + fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { #[inline] #[rustc_inherit_overflow_checks] fn advance(n: usize, iter: &mut U) -> ControlFlow<(), usize> { match iter.advance_back_by(n) { - 0 => ControlFlow::Break(()), - remaining => ControlFlow::Continue(remaining), + Ok(()) => ControlFlow::Break(()), + Err(remaining) => ControlFlow::Continue(remaining.get()), } } match self.iter_try_rfold(n, advance) { - ControlFlow::Continue(remaining) => remaining, - _ => 0, + ControlFlow::Continue(remaining) => NonZeroUsize::new(remaining).map_or(Ok(()), Err), + _ => Ok(()), } } } diff --git a/library/core/src/iter/adapters/rev.rs b/library/core/src/iter/adapters/rev.rs index b64baf838a2..1d882087f69 100644 --- a/library/core/src/iter/adapters/rev.rs +++ b/library/core/src/iter/adapters/rev.rs @@ -1,4 +1,5 @@ use crate::iter::{FusedIterator, TrustedLen}; +use crate::num::NonZeroUsize; use crate::ops::Try; /// A double-ended iterator with the direction inverted. @@ -38,7 +39,7 @@ where } #[inline] - fn advance_by(&mut self, n: usize) -> usize { + fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { self.iter.advance_back_by(n) } @@ -83,7 +84,7 @@ where } #[inline] - fn advance_back_by(&mut self, n: usize) -> usize { + fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { self.iter.advance_by(n) } diff --git a/library/core/src/iter/adapters/skip.rs b/library/core/src/iter/adapters/skip.rs index bb32e19b542..306338bc7cc 100644 --- a/library/core/src/iter/adapters/skip.rs +++ b/library/core/src/iter/adapters/skip.rs @@ -1,5 +1,6 @@ use crate::intrinsics::unlikely; use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable}; +use crate::num::NonZeroUsize; use crate::ops::{ControlFlow, Try}; /// An iterator that skips over `n` elements of `iter`. @@ -128,21 +129,27 @@ where #[inline] #[rustc_inherit_overflow_checks] - fn advance_by(&mut self, mut n: usize) -> usize { + fn advance_by(&mut self, mut n: usize) -> Result<(), NonZeroUsize> { let skip_inner = self.n; let skip_and_advance = skip_inner.saturating_add(n); - let remainder = self.iter.advance_by(skip_and_advance); + let remainder = match self.iter.advance_by(skip_and_advance) { + Ok(()) => 0, + Err(n) => n.get(), + }; let advanced_inner = skip_and_advance - remainder; n -= advanced_inner.saturating_sub(skip_inner); self.n = self.n.saturating_sub(advanced_inner); // skip_and_advance may have saturated if unlikely(remainder == 0 && n > 0) { - n = self.iter.advance_by(n); + n = match self.iter.advance_by(n) { + Ok(()) => 0, + Err(n) => n.get(), + } } - n + NonZeroUsize::new(n).map_or(Ok(()), Err) } } @@ -196,13 +203,11 @@ where impl_fold_via_try_fold! { rfold -> try_rfold } #[inline] - fn advance_back_by(&mut self, n: usize) -> usize { + fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { let min = crate::cmp::min(self.len(), n); let rem = self.iter.advance_back_by(min); - if rem != 0 { - panic!("ExactSizeIterator contract violation"); - }; - n - min + assert!(rem.is_ok(), "ExactSizeIterator contract violation"); + NonZeroUsize::new(n - min).map_or(Ok(()), Err) } } diff --git a/library/core/src/iter/adapters/take.rs b/library/core/src/iter/adapters/take.rs index 12e2395fe68..ce18bffe714 100644 --- a/library/core/src/iter/adapters/take.rs +++ b/library/core/src/iter/adapters/take.rs @@ -1,5 +1,6 @@ use crate::cmp; use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable, TrustedLen}; +use crate::num::NonZeroUsize; use crate::ops::{ControlFlow, Try}; /// An iterator that only iterates over the first `n` iterations of `iter`. @@ -121,12 +122,15 @@ where #[inline] #[rustc_inherit_overflow_checks] - fn advance_by(&mut self, n: usize) -> usize { + fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { let min = self.n.min(n); - let rem = self.iter.advance_by(min); + let rem = match self.iter.advance_by(min) { + Ok(()) => 0, + Err(rem) => rem.get(), + }; let advanced = min - rem; self.n -= advanced; - n - advanced + NonZeroUsize::new(n - advanced).map_or(Ok(()), Err) } } @@ -217,7 +221,7 @@ where #[inline] #[rustc_inherit_overflow_checks] - fn advance_back_by(&mut self, n: usize) -> usize { + fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { // The amount by which the inner iterator needs to be shortened for it to be // at most as long as the take() amount. let trim_inner = self.iter.len().saturating_sub(self.n); @@ -226,11 +230,14 @@ where // about having to advance more than usize::MAX here. let advance_by = trim_inner.saturating_add(n); - let remainder = self.iter.advance_back_by(advance_by); + let remainder = match self.iter.advance_back_by(advance_by) { + Ok(()) => 0, + Err(rem) => rem.get(), + }; let advanced_by_inner = advance_by - remainder; let advanced_by = advanced_by_inner - trim_inner; self.n -= advanced_by; - n - advanced_by + NonZeroUsize::new(n - advanced_by).map_or(Ok(()), Err) } } diff --git a/library/core/src/iter/range.rs b/library/core/src/iter/range.rs index 63c719f8b3a..1cd71193bd7 100644 --- a/library/core/src/iter/range.rs +++ b/library/core/src/iter/range.rs @@ -1,6 +1,7 @@ use crate::convert::TryFrom; use crate::marker::Destruct; use crate::mem; +use crate::num::NonZeroUsize; use crate::ops::{self, Try}; use super::{ @@ -530,12 +531,12 @@ trait RangeIteratorImpl { // Iterator fn spec_next(&mut self) -> Option; fn spec_nth(&mut self, n: usize) -> Option; - fn spec_advance_by(&mut self, n: usize) -> usize; + fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize>; // DoubleEndedIterator fn spec_next_back(&mut self) -> Option; fn spec_nth_back(&mut self, n: usize) -> Option; - fn spec_advance_back_by(&mut self, n: usize) -> usize; + fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize>; } impl const RangeIteratorImpl for ops::Range { @@ -567,7 +568,7 @@ impl const RangeIteratorImpl for ops::Range } #[inline] - default fn spec_advance_by(&mut self, n: usize) -> usize { + default fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { let available = if self.start <= self.end { Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX) } else { @@ -579,7 +580,7 @@ impl const RangeIteratorImpl for ops::Range self.start = Step::forward_checked(self.start.clone(), taken).expect("`Step` invariants not upheld"); - n - taken + NonZeroUsize::new(n - taken).map_or(Ok(()), Err) } #[inline] @@ -608,7 +609,7 @@ impl const RangeIteratorImpl for ops::Range } #[inline] - default fn spec_advance_back_by(&mut self, n: usize) -> usize { + default fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { let available = if self.start <= self.end { Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX) } else { @@ -620,7 +621,7 @@ impl const RangeIteratorImpl for ops::Range self.end = Step::backward_checked(self.end.clone(), taken).expect("`Step` invariants not upheld"); - n - taken + NonZeroUsize::new(n - taken).map_or(Ok(()), Err) } } @@ -651,7 +652,7 @@ impl const RangeIteratorImpl for ops::R } #[inline] - fn spec_advance_by(&mut self, n: usize) -> usize { + fn spec_advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { let available = if self.start <= self.end { Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX) } else { @@ -666,7 +667,7 @@ impl const RangeIteratorImpl for ops::R // Otherwise 0 is returned which always safe to use. self.start = unsafe { Step::forward_unchecked(self.start.clone(), taken) }; - n - taken + NonZeroUsize::new(n - taken).map_or(Ok(()), Err) } #[inline] @@ -695,7 +696,7 @@ impl const RangeIteratorImpl for ops::R } #[inline] - fn spec_advance_back_by(&mut self, n: usize) -> usize { + fn spec_advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { let available = if self.start <= self.end { Step::steps_between(&self.start, &self.end).unwrap_or(usize::MAX) } else { @@ -707,7 +708,7 @@ impl const RangeIteratorImpl for ops::R // SAFETY: same as the spec_advance_by() implementation self.end = unsafe { Step::backward_unchecked(self.end.clone(), taken) }; - n - taken + NonZeroUsize::new(n - taken).map_or(Ok(()), Err) } } @@ -757,7 +758,7 @@ impl const Iterator for ops::Range { } #[inline] - fn advance_by(&mut self, n: usize) -> usize { + fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { self.spec_advance_by(n) } @@ -836,7 +837,7 @@ impl const DoubleEndedIterator for ops::Range< } #[inline] - fn advance_back_by(&mut self, n: usize) -> usize { + fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { self.spec_advance_back_by(n) } } diff --git a/library/core/src/iter/sources/repeat.rs b/library/core/src/iter/sources/repeat.rs index 56a6d973705..67051f6e97b 100644 --- a/library/core/src/iter/sources/repeat.rs +++ b/library/core/src/iter/sources/repeat.rs @@ -1,4 +1,5 @@ use crate::iter::{FusedIterator, TrustedLen}; +use crate::num::NonZeroUsize; /// Creates a new iterator that endlessly repeats a single element. /// @@ -80,10 +81,10 @@ impl Iterator for Repeat { } #[inline] - fn advance_by(&mut self, n: usize) -> usize { + fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { // Advancing an infinite iterator of a single element is a no-op. let _ = n; - 0 + Ok(()) } #[inline] @@ -109,10 +110,10 @@ impl DoubleEndedIterator for Repeat { } #[inline] - fn advance_back_by(&mut self, n: usize) -> usize { + fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { // Advancing an infinite iterator of a single element is a no-op. let _ = n; - 0 + Ok(()) } #[inline] diff --git a/library/core/src/iter/sources/repeat_n.rs b/library/core/src/iter/sources/repeat_n.rs index 918f2a36ed0..0b0445850bf 100644 --- a/library/core/src/iter/sources/repeat_n.rs +++ b/library/core/src/iter/sources/repeat_n.rs @@ -1,5 +1,6 @@ use crate::iter::{FusedIterator, TrustedLen}; use crate::mem::ManuallyDrop; +use crate::num::NonZeroUsize; /// Creates a new iterator that repeats a single element a given number of times. /// @@ -137,7 +138,7 @@ impl Iterator for RepeatN { } #[inline] - fn advance_by(&mut self, skip: usize) -> usize { + fn advance_by(&mut self, skip: usize) -> Result<(), NonZeroUsize> { let len = self.count; if skip >= len { @@ -145,10 +146,11 @@ impl Iterator for RepeatN { } if skip > len { - skip - len + // SAFETY: we just checked that the difference is positive + Err(unsafe { NonZeroUsize::new_unchecked(skip - len) }) } else { self.count = len - skip; - 0 + Ok(()) } } @@ -178,7 +180,7 @@ impl DoubleEndedIterator for RepeatN { } #[inline] - fn advance_back_by(&mut self, n: usize) -> usize { + fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { self.advance_by(n) } diff --git a/library/core/src/iter/traits/double_ended.rs b/library/core/src/iter/traits/double_ended.rs index 06538d61aa0..182b365b030 100644 --- a/library/core/src/iter/traits/double_ended.rs +++ b/library/core/src/iter/traits/double_ended.rs @@ -1,4 +1,5 @@ use crate::marker::Destruct; +use crate::num::NonZeroUsize; use crate::ops::{ControlFlow, Try}; /// An iterator able to yield elements from both ends. @@ -120,29 +121,31 @@ pub trait DoubleEndedIterator: Iterator { /// ``` /// #![feature(iter_advance_by)] /// + /// use std::num::NonZeroUsize; /// let a = [3, 4, 5, 6]; /// let mut iter = a.iter(); /// - /// assert_eq!(iter.advance_back_by(2), 0); + /// assert_eq!(iter.advance_back_by(2), Ok(())); /// assert_eq!(iter.next_back(), Some(&4)); - /// assert_eq!(iter.advance_back_by(0), 0); - /// assert_eq!(iter.advance_back_by(100), 99); // only `&3` was skipped + /// assert_eq!(iter.advance_back_by(0), Ok(())); + /// assert_eq!(iter.advance_back_by(100), Err(NonZeroUsize::new(99).unwrap())); // only `&3` was skipped /// ``` /// /// [`Ok(())`]: Ok /// [`Err(k)`]: Err #[inline] #[unstable(feature = "iter_advance_by", reason = "recently added", issue = "77404")] - fn advance_back_by(&mut self, n: usize) -> usize + fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> where Self::Item: ~const Destruct, { for i in 0..n { if self.next_back().is_none() { - return n - i; + // SAFETY: `i` is always less than `n`. + return Err(unsafe { NonZeroUsize::new_unchecked(n - i) }); } } - 0 + Ok(()) } /// Returns the `n`th element from the end of the iterator. @@ -190,7 +193,7 @@ pub trait DoubleEndedIterator: Iterator { #[stable(feature = "iter_nth_back", since = "1.37.0")] #[rustc_do_not_const_check] fn nth_back(&mut self, n: usize) -> Option { - if self.advance_back_by(n) > 0 { + if self.advance_back_by(n).is_err() { return None; } self.next_back() @@ -378,7 +381,7 @@ impl<'a, I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for &'a mut I { fn next_back(&mut self) -> Option { (**self).next_back() } - fn advance_back_by(&mut self, n: usize) -> usize { + fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { (**self).advance_back_by(n) } fn nth_back(&mut self, n: usize) -> Option { diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index f2de040c635..5a1ee80f796 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -1,6 +1,7 @@ use crate::array; use crate::cmp::{self, Ordering}; use crate::marker::Destruct; +use crate::num::NonZeroUsize; use crate::ops::{ChangeOutputType, ControlFlow, FromResidual, Residual, Try}; use super::super::try_process; @@ -327,26 +328,28 @@ pub trait Iterator { /// ``` /// #![feature(iter_advance_by)] /// + /// use std::num::NonZeroUsize; /// let a = [1, 2, 3, 4]; /// let mut iter = a.iter(); /// - /// assert_eq!(iter.advance_by(2), 0); + /// assert_eq!(iter.advance_by(2), Ok(())); /// assert_eq!(iter.next(), Some(&3)); - /// assert_eq!(iter.advance_by(0), 0); - /// assert_eq!(iter.advance_by(100), 99); // only `&4` was skipped + /// assert_eq!(iter.advance_by(0), Ok(())); + /// assert_eq!(iter.advance_by(100), Err(NonZeroUsize::new(99).unwrap())); // only `&4` was skipped /// ``` #[inline] #[unstable(feature = "iter_advance_by", reason = "recently added", issue = "77404")] - fn advance_by(&mut self, n: usize) -> usize + fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> where Self::Item: ~const Destruct, { for i in 0..n { if self.next().is_none() { - return n - i; + // SAFETY: `i` is always less than `n`. + return Err(unsafe { NonZeroUsize::new_unchecked(n - i) }); } } - 0 + Ok(()) } /// Returns the `n`th element of the iterator. @@ -394,9 +397,7 @@ pub trait Iterator { where Self::Item: ~const Destruct, { - if self.advance_by(n) > 0 { - return None; - } + self.advance_by(n).ok()?; self.next() } @@ -4017,7 +4018,7 @@ impl Iterator for &mut I { fn size_hint(&self) -> (usize, Option) { (**self).size_hint() } - fn advance_by(&mut self, n: usize) -> usize { + fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { (**self).advance_by(n) } fn nth(&mut self, n: usize) -> Option { diff --git a/library/core/src/ops/index_range.rs b/library/core/src/ops/index_range.rs index 744ec3b0245..265022a394e 100644 --- a/library/core/src/ops/index_range.rs +++ b/library/core/src/ops/index_range.rs @@ -1,5 +1,6 @@ use crate::intrinsics::{assert_unsafe_precondition, unchecked_add, unchecked_sub}; use crate::iter::{FusedIterator, TrustedLen}; +use crate::num::NonZeroUsize; /// Like a `Range`, but with a safety invariant that `start <= end`. /// @@ -132,9 +133,9 @@ impl Iterator for IndexRange { } #[inline] - fn advance_by(&mut self, n: usize) -> usize { + fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { let taken = self.take_prefix(n); - n - taken.len() + NonZeroUsize::new(n - taken.len()).map_or(Ok(()), Err) } } @@ -150,9 +151,9 @@ impl DoubleEndedIterator for IndexRange { } #[inline] - fn advance_back_by(&mut self, n: usize) -> usize { + fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { let taken = self.take_suffix(n); - n - taken.len() + NonZeroUsize::new(n - taken.len()).map_or(Ok(()), Err) } } diff --git a/library/core/src/slice/iter/macros.rs b/library/core/src/slice/iter/macros.rs index d3e9b9c2b22..b73e35f1e91 100644 --- a/library/core/src/slice/iter/macros.rs +++ b/library/core/src/slice/iter/macros.rs @@ -176,11 +176,11 @@ macro_rules! iterator { } #[inline] - fn advance_by(&mut self, n: usize) -> usize { + fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { let advance = cmp::min(len!(self), n); // SAFETY: By construction, `advance` does not exceed `self.len()`. unsafe { self.post_inc_start(advance) }; - n - advance + NonZeroUsize::new(n - advance).map_or(Ok(()), Err) } #[inline] @@ -371,11 +371,11 @@ macro_rules! iterator { } #[inline] - fn advance_back_by(&mut self, n: usize) -> usize { + fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { let advance = cmp::min(len!(self), n); // SAFETY: By construction, `advance` does not exceed `self.len()`. unsafe { self.pre_dec_end(advance) }; - n - advance + NonZeroUsize::new(n - advance).map_or(Ok(()), Err) } } diff --git a/library/core/tests/array.rs b/library/core/tests/array.rs index 9b90c77e151..0869644c040 100644 --- a/library/core/tests/array.rs +++ b/library/core/tests/array.rs @@ -1,5 +1,6 @@ use core::{array, assert_eq}; use core::convert::TryFrom; +use core::num::NonZeroUsize; use core::sync::atomic::{AtomicUsize, Ordering}; #[test] @@ -535,17 +536,17 @@ fn array_intoiter_advance_by() { let mut it = IntoIterator::into_iter(a); let r = it.advance_by(1); - assert_eq!(r, 0); + assert_eq!(r, Ok(())); assert_eq!(it.len(), 99); assert_eq!(counter.get(), 1); let r = it.advance_by(0); - assert_eq!(r, 0); + assert_eq!(r, Ok(())); assert_eq!(it.len(), 99); assert_eq!(counter.get(), 1); let r = it.advance_by(11); - assert_eq!(r, 0); + assert_eq!(r, Ok(())); assert_eq!(it.len(), 88); assert_eq!(counter.get(), 12); @@ -557,17 +558,17 @@ fn array_intoiter_advance_by() { assert_eq!(counter.get(), 13); let r = it.advance_by(123456); - assert_eq!(r, 123456 - 87); + assert_eq!(r, Err(NonZeroUsize::new(123456 - 87).unwrap())); assert_eq!(it.len(), 0); assert_eq!(counter.get(), 100); let r = it.advance_by(0); - assert_eq!(r, 0); + assert_eq!(r, Ok(())); assert_eq!(it.len(), 0); assert_eq!(counter.get(), 100); let r = it.advance_by(10); - assert_eq!(r, 10); + assert_eq!(r, Err(NonZeroUsize::new(10).unwrap())); assert_eq!(it.len(), 0); assert_eq!(counter.get(), 100); } @@ -588,17 +589,17 @@ fn array_intoiter_advance_back_by() { let mut it = IntoIterator::into_iter(a); let r = it.advance_back_by(1); - assert_eq!(r, 0); + assert_eq!(r, Ok(())); assert_eq!(it.len(), 99); assert_eq!(counter.get(), 1); let r = it.advance_back_by(0); - assert_eq!(r, 0); + assert_eq!(r, Ok(())); assert_eq!(it.len(), 99); assert_eq!(counter.get(), 1); let r = it.advance_back_by(11); - assert_eq!(r, 0); + assert_eq!(r, Ok(())); assert_eq!(it.len(), 88); assert_eq!(counter.get(), 12); @@ -610,17 +611,17 @@ fn array_intoiter_advance_back_by() { assert_eq!(counter.get(), 13); let r = it.advance_back_by(123456); - assert_eq!(r, 123456 - 87); + assert_eq!(r, Err(NonZeroUsize::new(123456 - 87).unwrap())); assert_eq!(it.len(), 0); assert_eq!(counter.get(), 100); let r = it.advance_back_by(0); - assert_eq!(r, 0); + assert_eq!(r, Ok(())); assert_eq!(it.len(), 0); assert_eq!(counter.get(), 100); let r = it.advance_back_by(10); - assert_eq!(r, 10); + assert_eq!(r, Err(NonZeroUsize::new(10).unwrap())); assert_eq!(it.len(), 0); assert_eq!(counter.get(), 100); } @@ -679,8 +680,8 @@ fn array_into_iter_fold() { let a = [1, 2, 3, 4, 5, 6]; let mut it = a.into_iter(); - assert_eq!(it.advance_by(1), 0); - assert_eq!(it.advance_back_by(2), 0); + assert_eq!(it.advance_by(1), Ok(())); + assert_eq!(it.advance_back_by(2), Ok(())); let s = it.fold(10, |a, b| 10 * a + b); assert_eq!(s, 10234); } @@ -695,8 +696,8 @@ fn array_into_iter_rfold() { let a = [1, 2, 3, 4, 5, 6]; let mut it = a.into_iter(); - assert_eq!(it.advance_by(1), 0); - assert_eq!(it.advance_back_by(2), 0); + assert_eq!(it.advance_by(1), Ok(())); + assert_eq!(it.advance_back_by(2), Ok(())); let s = it.rfold(10, |a, b| 10 * a + b); assert_eq!(s, 10432); } diff --git a/library/core/tests/iter/adapters/chain.rs b/library/core/tests/iter/adapters/chain.rs index 4da9263d7ac..175a1b638e1 100644 --- a/library/core/tests/iter/adapters/chain.rs +++ b/library/core/tests/iter/adapters/chain.rs @@ -1,5 +1,6 @@ use super::*; use core::iter::*; +use core::num::NonZeroUsize; #[test] fn test_iterator_chain() { @@ -31,28 +32,28 @@ fn test_iterator_chain_advance_by() { for i in 0..xs.len() { let mut iter = Unfuse::new(xs).chain(Unfuse::new(ys)); - assert_eq!(0, iter.advance_by(i)); + assert_eq!(iter.advance_by(i), Ok(())); assert_eq!(iter.next(), Some(&xs[i])); - assert_eq!(iter.advance_by(100), 100 - (len - i - 1)); - assert_eq!(0, iter.advance_by(0)); + assert_eq!(iter.advance_by(100), Err(NonZeroUsize::new(100 - (len - i - 1)).unwrap())); + assert_eq!(iter.advance_by(0), Ok(())); } for i in 0..ys.len() { let mut iter = Unfuse::new(xs).chain(Unfuse::new(ys)); - assert_eq!(iter.advance_by(xs.len() + i), 0); + assert_eq!(iter.advance_by(xs.len() + i), Ok(())); assert_eq!(iter.next(), Some(&ys[i])); - assert_eq!(iter.advance_by(100), 100 - (ys.len() - i - 1)); - assert_eq!(iter.advance_by(0), 0); + assert_eq!(iter.advance_by(100), Err(NonZeroUsize::new(100 - (ys.len() - i - 1)).unwrap())); + assert_eq!(iter.advance_by(0), Ok(())); } let mut iter = xs.iter().chain(ys); - assert_eq!(iter.advance_by(len), 0); + assert_eq!(iter.advance_by(len), Ok(())); assert_eq!(iter.next(), None); - assert_eq!(iter.advance_by(0), 0); + assert_eq!(iter.advance_by(0), Ok(())); let mut iter = xs.iter().chain(ys); - assert_eq!(iter.advance_by(len + 1), 1); - assert_eq!(iter.advance_by(0), 0); + assert_eq!(iter.advance_by(len + 1), Err(NonZeroUsize::new(1).unwrap())); + assert_eq!(iter.advance_by(0), Ok(())); } test_chain(&[], &[]); @@ -68,28 +69,28 @@ fn test_iterator_chain_advance_back_by() { for i in 0..ys.len() { let mut iter = Unfuse::new(xs).chain(Unfuse::new(ys)); - assert_eq!(iter.advance_back_by(i), 0); + assert_eq!(iter.advance_back_by(i), Ok(())); assert_eq!(iter.next_back(), Some(&ys[ys.len() - i - 1])); - assert_eq!(iter.advance_back_by(100), 100 - (len - i - 1)); - assert_eq!(iter.advance_back_by(0), 0); + assert_eq!(iter.advance_back_by(100), Err(NonZeroUsize::new(100 - (len - i - 1)).unwrap())); + assert_eq!(iter.advance_back_by(0), Ok(())); } for i in 0..xs.len() { let mut iter = Unfuse::new(xs).chain(Unfuse::new(ys)); - assert_eq!(iter.advance_back_by(ys.len() + i), 0); + assert_eq!(iter.advance_back_by(ys.len() + i), Ok(())); assert_eq!(iter.next_back(), Some(&xs[xs.len() - i - 1])); - assert_eq!(iter.advance_back_by(100), 100 - (xs.len() - i - 1)); - assert_eq!(iter.advance_back_by(0), 0); + assert_eq!(iter.advance_back_by(100), Err(NonZeroUsize::new(100 - (xs.len() - i - 1)).unwrap())); + assert_eq!(iter.advance_back_by(0), Ok(())); } let mut iter = xs.iter().chain(ys); - assert_eq!(iter.advance_back_by(len), 0); + assert_eq!(iter.advance_back_by(len), Ok(())); assert_eq!(iter.next_back(), None); - assert_eq!(iter.advance_back_by(0), 0); + assert_eq!(iter.advance_back_by(0), Ok(())); let mut iter = xs.iter().chain(ys); - assert_eq!(iter.advance_back_by(len + 1), 1); - assert_eq!(iter.advance_back_by(0), 0); + assert_eq!(iter.advance_back_by(len + 1), Err(NonZeroUsize::new(1).unwrap())); + assert_eq!(iter.advance_back_by(0), Ok(())); } test_chain(&[], &[]); diff --git a/library/core/tests/iter/adapters/enumerate.rs b/library/core/tests/iter/adapters/enumerate.rs index 0e603387847..ff57973a62a 100644 --- a/library/core/tests/iter/adapters/enumerate.rs +++ b/library/core/tests/iter/adapters/enumerate.rs @@ -1,4 +1,5 @@ use core::iter::*; +use core::num::NonZeroUsize; #[test] fn test_iterator_enumerate() { @@ -55,6 +56,20 @@ fn test_iterator_enumerate_count() { assert_eq!(xs.iter().enumerate().count(), 6); } +#[test] +fn test_iterator_enumerate_advance_by() { + let xs = [0, 1, 2, 3, 4, 5]; + let mut it = xs.iter().enumerate(); + assert_eq!(it.advance_by(0), Ok(())); + assert_eq!(it.next(), Some((0, &0))); + assert_eq!(it.advance_by(1), Ok(())); + assert_eq!(it.next(), Some((2, &2))); + assert_eq!(it.advance_by(2), Ok(())); + assert_eq!(it.next(), Some((5, &5))); + assert_eq!(it.advance_by(1), Err(NonZeroUsize::new(1).unwrap())); + assert_eq!(it.next(), None); +} + #[test] fn test_iterator_enumerate_fold() { let xs = [0, 1, 2, 3, 4, 5]; diff --git a/library/core/tests/iter/adapters/flatten.rs b/library/core/tests/iter/adapters/flatten.rs index e8e06a8ca40..91809c9e5fd 100644 --- a/library/core/tests/iter/adapters/flatten.rs +++ b/library/core/tests/iter/adapters/flatten.rs @@ -1,6 +1,7 @@ use core::assert_eq; use super::*; use core::iter::*; +use core::num::NonZeroUsize; #[test] fn test_iterator_flatten() { @@ -62,19 +63,19 @@ fn test_flatten_try_folds() { fn test_flatten_advance_by() { let mut it = once(0..10).chain(once(10..30)).chain(once(30..40)).flatten(); - assert_eq!(it.advance_by(5), 0); + assert_eq!(it.advance_by(5), Ok(())); assert_eq!(it.next(), Some(5)); - assert_eq!(it.advance_by(9), 0); + assert_eq!(it.advance_by(9), Ok(())); assert_eq!(it.next(), Some(15)); - assert_eq!(it.advance_back_by(4), 0); + assert_eq!(it.advance_back_by(4), Ok(())); assert_eq!(it.next_back(), Some(35)); - assert_eq!(it.advance_back_by(9), 0); + assert_eq!(it.advance_back_by(9), Ok(())); assert_eq!(it.next_back(), Some(25)); - assert_eq!(it.advance_by(usize::MAX), usize::MAX - 9); - assert_eq!(it.advance_back_by(usize::MAX), usize::MAX); - assert_eq!(it.advance_by(0), 0); - assert_eq!(it.advance_back_by(0), 0); + assert_eq!(it.advance_by(usize::MAX), Err(NonZeroUsize::new(usize::MAX - 9).unwrap())); + assert_eq!(it.advance_back_by(usize::MAX), Err(NonZeroUsize::new(usize::MAX).unwrap())); + assert_eq!(it.advance_by(0), Ok(())); + assert_eq!(it.advance_back_by(0), Ok(())); assert_eq!(it.size_hint(), (0, Some(0))); } @@ -175,19 +176,19 @@ fn test_flatten_count() { let mut it = once(0..10).chain(once(10..30)).chain(once(30..40)).flatten(); assert_eq!(it.clone().count(), 40); - assert_eq!(it.advance_by(5), 0); + assert_eq!(it.advance_by(5), Ok(())); assert_eq!(it.clone().count(), 35); - assert_eq!(it.advance_back_by(5), 0); + assert_eq!(it.advance_back_by(5), Ok(())); assert_eq!(it.clone().count(), 30); - assert_eq!(it.advance_by(10), 0); + assert_eq!(it.advance_by(10), Ok(())); assert_eq!(it.clone().count(), 20); - assert_eq!(it.advance_back_by(8), 0); + assert_eq!(it.advance_back_by(8), Ok(())); assert_eq!(it.clone().count(), 12); - assert_eq!(it.advance_by(4), 0); + assert_eq!(it.advance_by(4), Ok(())); assert_eq!(it.clone().count(), 8); - assert_eq!(it.advance_back_by(5), 0); + assert_eq!(it.advance_back_by(5), Ok(())); assert_eq!(it.clone().count(), 3); - assert_eq!(it.advance_by(3), 0); + assert_eq!(it.advance_by(3), Ok(())); assert_eq!(it.clone().count(), 0); } @@ -196,18 +197,18 @@ fn test_flatten_last() { let mut it = once(0..10).chain(once(10..30)).chain(once(30..40)).flatten(); assert_eq!(it.clone().last(), Some(39)); - assert_eq!(it.advance_by(5), 0); // 5..40 + assert_eq!(it.advance_by(5), Ok(())); // 5..40 assert_eq!(it.clone().last(), Some(39)); - assert_eq!(it.advance_back_by(5), 0); // 5..35 + assert_eq!(it.advance_back_by(5), Ok(())); // 5..35 assert_eq!(it.clone().last(), Some(34)); - assert_eq!(it.advance_by(10), 0); // 15..35 + assert_eq!(it.advance_by(10), Ok(())); // 15..35 assert_eq!(it.clone().last(), Some(34)); - assert_eq!(it.advance_back_by(8), 0); // 15..27 + assert_eq!(it.advance_back_by(8), Ok(())); // 15..27 assert_eq!(it.clone().last(), Some(26)); - assert_eq!(it.advance_by(4), 0); // 19..27 + assert_eq!(it.advance_by(4), Ok(())); // 19..27 assert_eq!(it.clone().last(), Some(26)); - assert_eq!(it.advance_back_by(5), 0); // 19..22 + assert_eq!(it.advance_back_by(5), Ok(())); // 19..22 assert_eq!(it.clone().last(), Some(21)); - assert_eq!(it.advance_by(3), 0); // 22..22 + assert_eq!(it.advance_by(3), Ok(())); // 22..22 assert_eq!(it.clone().last(), None); } diff --git a/library/core/tests/iter/adapters/skip.rs b/library/core/tests/iter/adapters/skip.rs index 134dead4ad3..e3e88a84fad 100644 --- a/library/core/tests/iter/adapters/skip.rs +++ b/library/core/tests/iter/adapters/skip.rs @@ -1,4 +1,5 @@ use core::iter::*; +use core::num::NonZeroUsize; use super::Unfuse; @@ -73,16 +74,16 @@ fn test_iterator_skip_nth() { #[test] fn test_skip_advance_by() { - assert_eq!((0..0).skip(10).advance_by(0), 0); - assert_eq!((0..0).skip(10).advance_by(1), 1); + assert_eq!((0..0).skip(10).advance_by(0), Ok(())); + assert_eq!((0..0).skip(10).advance_by(1), Err(NonZeroUsize::new(1).unwrap())); assert_eq!( (0u128..(usize::MAX as u128) + 1).skip(usize::MAX - 10).advance_by(usize::MAX - 5), - usize::MAX - 16 + Err(NonZeroUsize::new(usize::MAX - 16).unwrap()) ); - assert_eq!((0u128..u128::MAX).skip(usize::MAX - 10).advance_by(20), 0); + assert_eq!((0u128..u128::MAX).skip(usize::MAX - 10).advance_by(20), Ok(())); - assert_eq!((0..2).skip(1).advance_back_by(10), 9); - assert_eq!((0..0).skip(1).advance_back_by(0), 0); + assert_eq!((0..2).skip(1).advance_back_by(10), Err(NonZeroUsize::new(9).unwrap())); + assert_eq!((0..0).skip(1).advance_back_by(0), Ok(())); } #[test] diff --git a/library/core/tests/iter/adapters/take.rs b/library/core/tests/iter/adapters/take.rs index 8ba7f0c5f8a..3cad47c06de 100644 --- a/library/core/tests/iter/adapters/take.rs +++ b/library/core/tests/iter/adapters/take.rs @@ -1,4 +1,5 @@ use core::iter::*; +use core::num::NonZeroUsize; #[test] fn test_iterator_take() { @@ -76,23 +77,23 @@ fn test_iterator_take_nth_back() { #[test] fn test_take_advance_by() { let mut take = (0..10).take(3); - assert_eq!(take.advance_by(2), 0); + assert_eq!(take.advance_by(2), Ok(())); assert_eq!(take.next(), Some(2)); - assert_eq!(take.advance_by(1), 1); + assert_eq!(take.advance_by(1), Err(NonZeroUsize::new(1).unwrap())); - assert_eq!((0..0).take(10).advance_by(0), 0); - assert_eq!((0..0).take(10).advance_by(1), 1); - assert_eq!((0..10).take(4).advance_by(5), 1); + assert_eq!((0..0).take(10).advance_by(0), Ok(())); + assert_eq!((0..0).take(10).advance_by(1), Err(NonZeroUsize::new(1).unwrap())); + assert_eq!((0..10).take(4).advance_by(5), Err(NonZeroUsize::new(1).unwrap())); let mut take = (0..10).take(3); - assert_eq!(take.advance_back_by(2), 0); + assert_eq!(take.advance_back_by(2), Ok(())); assert_eq!(take.next(), Some(0)); - assert_eq!(take.advance_back_by(1), 1); + assert_eq!(take.advance_back_by(1), Err(NonZeroUsize::new(1).unwrap())); - assert_eq!((0..2).take(1).advance_back_by(10), 9); - assert_eq!((0..0).take(1).advance_back_by(1), 1); - assert_eq!((0..0).take(1).advance_back_by(0), 0); - assert_eq!((0..usize::MAX).take(100).advance_back_by(usize::MAX), usize::MAX - 100); + assert_eq!((0..2).take(1).advance_back_by(10), Err(NonZeroUsize::new(9).unwrap())); + assert_eq!((0..0).take(1).advance_back_by(1), Err(NonZeroUsize::new(1).unwrap())); + assert_eq!((0..0).take(1).advance_back_by(0), Ok(())); + assert_eq!((0..usize::MAX).take(100).advance_back_by(usize::MAX), Err(NonZeroUsize::new(usize::MAX - 100).unwrap())); } #[test] diff --git a/library/core/tests/iter/range.rs b/library/core/tests/iter/range.rs index d375dbf2ce4..0a77ecddb84 100644 --- a/library/core/tests/iter/range.rs +++ b/library/core/tests/iter/range.rs @@ -1,3 +1,4 @@ +use core::num::NonZeroUsize; use super::*; #[test] @@ -287,25 +288,25 @@ fn test_range_step() { #[test] fn test_range_advance_by() { let mut r = 0..usize::MAX; - assert_eq!(0, r.advance_by(0)); - assert_eq!(0, r.advance_back_by(0)); + assert_eq!(Ok(()), r.advance_by(0)); + assert_eq!(Ok(()), r.advance_back_by(0)); assert_eq!(r.len(), usize::MAX); - assert_eq!(0, r.advance_by(1)); - assert_eq!(0, r.advance_back_by(1)); + assert_eq!(Ok(()), r.advance_by(1)); + assert_eq!(Ok(()), r.advance_back_by(1)); assert_eq!((r.start, r.end), (1, usize::MAX - 1)); - assert_eq!(2, r.advance_by(usize::MAX)); + assert_eq!(Err(NonZeroUsize::new(2).unwrap()), r.advance_by(usize::MAX)); - assert_eq!(0, r.advance_by(0)); - assert_eq!(0, r.advance_back_by(0)); + assert_eq!(Ok(()), r.advance_by(0)); + assert_eq!(Ok(()), r.advance_back_by(0)); let mut r = 0u128..u128::MAX; - assert_eq!(0, r.advance_by(usize::MAX)); - assert_eq!(0, r.advance_back_by(usize::MAX)); + assert_eq!(Ok(()), r.advance_by(usize::MAX)); + assert_eq!(Ok(()), r.advance_back_by(usize::MAX)); assert_eq!((r.start, r.end), (0u128 + usize::MAX as u128, u128::MAX - usize::MAX as u128)); } diff --git a/library/core/tests/iter/traits/iterator.rs b/library/core/tests/iter/traits/iterator.rs index 4b446727c9a..9eebfb1f1f3 100644 --- a/library/core/tests/iter/traits/iterator.rs +++ b/library/core/tests/iter/traits/iterator.rs @@ -1,3 +1,5 @@ +use core::num::NonZeroUsize; + /// A wrapper struct that implements `Eq` and `Ord` based on the wrapped /// integer modulo 3. Used to test that `Iterator::max` and `Iterator::min` /// return the correct element if some of them are equal. @@ -148,13 +150,13 @@ fn test_iterator_advance_by() { for i in 0..v.len() { let mut iter = v.iter(); - assert_eq!(iter.advance_by(i), 0); + assert_eq!(iter.advance_by(i), Ok(())); assert_eq!(iter.next().unwrap(), &v[i]); - assert_eq!(iter.advance_by(100), 100 - (v.len() - 1 - i)); + assert_eq!(iter.advance_by(100), Err(NonZeroUsize::new(100 - (v.len() - 1 - i)).unwrap())); } - assert_eq!(v.iter().advance_by(v.len()), 0); - assert_eq!(v.iter().advance_by(100), 100 - v.len()); + assert_eq!(v.iter().advance_by(v.len()), Ok(())); + assert_eq!(v.iter().advance_by(100), Err(NonZeroUsize::new(100 - v.len()).unwrap())); } #[test] @@ -163,13 +165,13 @@ fn test_iterator_advance_back_by() { for i in 0..v.len() { let mut iter = v.iter(); - assert_eq!(iter.advance_back_by(i), 0); + assert_eq!(iter.advance_back_by(i), Ok(())); assert_eq!(iter.next_back().unwrap(), &v[v.len() - 1 - i]); - assert_eq!(iter.advance_back_by(100), 100 - (v.len() - 1 - i)); + assert_eq!(iter.advance_back_by(100), Err(NonZeroUsize::new(100 - (v.len() - 1 - i)).unwrap())); } - assert_eq!(v.iter().advance_back_by(v.len()), 0); - assert_eq!(v.iter().advance_back_by(100), 100 - v.len()); + assert_eq!(v.iter().advance_back_by(v.len()), Ok(())); + assert_eq!(v.iter().advance_back_by(100), Err(NonZeroUsize::new(100 - v.len()).unwrap())); } #[test] @@ -178,13 +180,13 @@ fn test_iterator_rev_advance_back_by() { for i in 0..v.len() { let mut iter = v.iter().rev(); - assert_eq!(iter.advance_back_by(i), 0); + assert_eq!(iter.advance_back_by(i), Ok(())); assert_eq!(iter.next_back().unwrap(), &v[i]); - assert_eq!(iter.advance_back_by(100), 100 - (v.len() - 1 - i)); + assert_eq!(iter.advance_back_by(100), Err(NonZeroUsize::new(100 - (v.len() - 1 - i)).unwrap())); } - assert_eq!(v.iter().rev().advance_back_by(v.len()), 0); - assert_eq!(v.iter().rev().advance_back_by(100), 100 - v.len()); + assert_eq!(v.iter().rev().advance_back_by(v.len()), Ok(())); + assert_eq!(v.iter().rev().advance_back_by(100), Err(NonZeroUsize::new(100 - v.len()).unwrap())); } #[test] @@ -422,13 +424,13 @@ fn test_iterator_rev_advance_by() { for i in 0..v.len() { let mut iter = v.iter().rev(); - assert_eq!(iter.advance_by(i), 0); + assert_eq!(iter.advance_by(i), Ok(())); assert_eq!(iter.next().unwrap(), &v[v.len() - 1 - i]); - assert_eq!(iter.advance_by(100), 100 - (v.len() - 1 - i)); + assert_eq!(iter.advance_by(100), Err(NonZeroUsize::new(100 - (v.len() - 1 - i)).unwrap())); } - assert_eq!(v.iter().rev().advance_by(v.len()), 0); - assert_eq!(v.iter().rev().advance_by(100), 100 - v.len()); + assert_eq!(v.iter().rev().advance_by(v.len()), Ok(())); + assert_eq!(v.iter().rev().advance_by(100), Err(NonZeroUsize::new(100 - v.len()).unwrap())); } #[test] diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs index a675d9e13fb..88f54591bb4 100644 --- a/library/core/tests/slice.rs +++ b/library/core/tests/slice.rs @@ -1,6 +1,7 @@ use core::cell::Cell; use core::cmp::Ordering; use core::mem::MaybeUninit; +use core::num::NonZeroUsize; use core::result::Result::{Err, Ok}; use core::slice; @@ -142,20 +143,20 @@ fn test_iterator_advance_by() { for i in 0..=v.len() { let mut iter = v.iter(); - assert_eq!(iter.advance_by(i), 0); + assert_eq!(iter.advance_by(i), Ok(())); assert_eq!(iter.as_slice(), &v[i..]); } let mut iter = v.iter(); - assert_eq!(iter.advance_by(v.len() + 1), 1); + assert_eq!(iter.advance_by(v.len() + 1), Err(NonZeroUsize::new(1).unwrap())); assert_eq!(iter.as_slice(), &[]); let mut iter = v.iter(); - assert_eq!(iter.advance_by(3), 0); + assert_eq!(iter.advance_by(3), Ok(())); assert_eq!(iter.as_slice(), &v[3..]); - assert_eq!(iter.advance_by(2), 0); + assert_eq!(iter.advance_by(2), Ok(())); assert_eq!(iter.as_slice(), &[]); - assert_eq!(iter.advance_by(0), 0); + assert_eq!(iter.advance_by(0), Ok(())); } #[test] @@ -164,20 +165,20 @@ fn test_iterator_advance_back_by() { for i in 0..=v.len() { let mut iter = v.iter(); - assert_eq!(iter.advance_back_by(i), 0); + assert_eq!(iter.advance_back_by(i), Ok(())); assert_eq!(iter.as_slice(), &v[..v.len() - i]); } let mut iter = v.iter(); - assert_eq!(iter.advance_back_by(v.len() + 1), 1); + assert_eq!(iter.advance_back_by(v.len() + 1), Err(NonZeroUsize::new(1).unwrap())); assert_eq!(iter.as_slice(), &[]); let mut iter = v.iter(); - assert_eq!(iter.advance_back_by(3), 0); + assert_eq!(iter.advance_back_by(3), Ok(())); assert_eq!(iter.as_slice(), &v[..v.len() - 3]); - assert_eq!(iter.advance_back_by(2), 0); + assert_eq!(iter.advance_back_by(2), Ok(())); assert_eq!(iter.as_slice(), &[]); - assert_eq!(iter.advance_back_by(0), 0); + assert_eq!(iter.advance_back_by(0), Ok(())); } #[test] From 9cd9da2cd1c365791c7bf41be5759ebc34180aa0 Mon Sep 17 00:00:00 2001 From: The 8472 Date: Mon, 13 Mar 2023 20:16:43 +0100 Subject: [PATCH 179/346] update documentation --- library/core/src/iter/traits/double_ended.rs | 9 +++++---- library/core/src/iter/traits/iterator.rs | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/library/core/src/iter/traits/double_ended.rs b/library/core/src/iter/traits/double_ended.rs index 182b365b030..d82ecb698dd 100644 --- a/library/core/src/iter/traits/double_ended.rs +++ b/library/core/src/iter/traits/double_ended.rs @@ -101,10 +101,11 @@ pub trait DoubleEndedIterator: Iterator { /// eagerly skip `n` elements starting from the back by calling [`next_back`] up /// to `n` times until [`None`] is encountered. /// - /// `advance_back_by(n)` will return `0` if the iterator successfully advances by - /// `n` elements, or an usize `k` if [`None`] is encountered, where `k` is remaining number - /// of steps that could not be advanced because the iterator ran out. - /// Note that `k` is always less than `n`. + /// `advance_back_by(n)` will return `Ok(())` if the iterator successfully advances by + /// `n` elements, or a `Err(NonZeroUsize)` with value `k` if [`None`] is encountered, where `k` + /// is remaining number of steps that could not be advanced because the iterator ran out. + /// If `self` is empty and `n` is non-zero, then this returns `Err(n)`. + /// Otherwise, `k` is always less than `n`. /// /// Calling `advance_back_by(0)` can do meaningful work, for example [`Flatten`] can advance its /// outer iterator until it finds an inner iterator that is not empty, which then often diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 5a1ee80f796..080330fa41e 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -309,10 +309,11 @@ pub trait Iterator { /// This method will eagerly skip `n` elements by calling [`next`] up to `n` /// times until [`None`] is encountered. /// - /// `advance_by(n)` will return `0` if the iterator successfully advances by - /// `n` elements, or an usize `k` if [`None`] is encountered, where `k` is remaining number - /// of steps that could not be advanced because the iterator ran out. - /// Note that `k` is always less than `n`. + /// `advance_by(n)` will return `Ok(())` if the iterator successfully advances by + /// `n` elements, or a `Err(NonZeroUsize)` with value `k` if [`None`] is encountered, + /// where `k` is remaining number of steps that could not be advanced because the iterator ran out. + /// If `self` is empty and `n` is non-zero, then this returns `Err(n)`. + /// Otherwise, `k` is always less than `n`. /// /// Calling `advance_by(0)` can do meaningful work, for example [`Flatten`] /// can advance its outer iterator until it finds an inner iterator that is not empty, which From 41807938d2fbc7928d75b1d68ac08899682168a2 Mon Sep 17 00:00:00 2001 From: The 8472 Date: Mon, 27 Mar 2023 14:56:14 +0200 Subject: [PATCH 180/346] fix advance_by impl for vec_deque and add tests --- .../src/collections/vec_deque/into_iter.rs | 14 +++++------ library/alloc/tests/vec_deque.rs | 23 +++++++++++++++++++ 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/library/alloc/src/collections/vec_deque/into_iter.rs b/library/alloc/src/collections/vec_deque/into_iter.rs index c277c62ad14..e2b40f7912e 100644 --- a/library/alloc/src/collections/vec_deque/into_iter.rs +++ b/library/alloc/src/collections/vec_deque/into_iter.rs @@ -56,10 +56,10 @@ impl Iterator for IntoIter { #[inline] fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { - let rem = if self.inner.len < n { - let len = self.inner.len; + let len = self.inner.len; + let rem = if len < n { self.inner.clear(); - len - n + n - len } else { self.inner.drain(..n); 0 @@ -186,12 +186,12 @@ impl DoubleEndedIterator for IntoIter { #[inline] fn advance_back_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { let len = self.inner.len; - let rem = if len >= n { - self.inner.truncate(len - n); - 0 - } else { + let rem = if len < n { self.inner.clear(); n - len + } else { + self.inner.truncate(len - n); + 0 }; NonZeroUsize::new(rem).map_or(Ok(()), Err) } diff --git a/library/alloc/tests/vec_deque.rs b/library/alloc/tests/vec_deque.rs index 5a0b852e8d5..ddc27e34ed9 100644 --- a/library/alloc/tests/vec_deque.rs +++ b/library/alloc/tests/vec_deque.rs @@ -1,3 +1,4 @@ +use core::num::NonZeroUsize; use std::assert_matches::assert_matches; use std::collections::TryReserveErrorKind::*; use std::collections::{vec_deque::Drain, VecDeque}; @@ -426,6 +427,28 @@ fn test_into_iter() { assert_eq!(it.next(), Some(7)); assert_eq!(it.size_hint(), (5, Some(5))); } + + // advance_by + { + let mut d = VecDeque::new(); + for i in 0..=4 { + d.push_back(i); + } + for i in 6..=8 { + d.push_front(i); + } + + let mut it = d.into_iter(); + assert_eq!(it.advance_by(1), Ok(())); + assert_eq!(it.next(), Some(7)); + assert_eq!(it.advance_back_by(1), Ok(())); + assert_eq!(it.next_back(), Some(3)); + + let mut it = VecDeque::from(vec![1, 2, 3, 4, 5]).into_iter(); + assert_eq!(it.advance_by(10), Err(NonZeroUsize::new(5).unwrap())); + let mut it = VecDeque::from(vec![1, 2, 3, 4, 5]).into_iter(); + assert_eq!(it.advance_back_by(10), Err(NonZeroUsize::new(5).unwrap())); + } } #[test] From 3e16c56ffcca750a85d25cf32f79e13caf0a6533 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Mon, 27 Mar 2023 16:06:54 +0100 Subject: [PATCH 181/346] Fix ASCII case comment --- library/core/src/num/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index a50c91579fa..9b812bbfc23 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -414,7 +414,7 @@ impl isize { } } -/// If 6th bit set ascii is upper case. +/// If 6th bit is set ascii is lower case. const ASCII_CASE_MASK: u8 = 0b0010_0000; impl u8 { From 73c34cbaf71b40bd7944b3eb3d64009b93d05873 Mon Sep 17 00:00:00 2001 From: Jamen Marz Date: Mon, 27 Mar 2023 10:14:08 -0400 Subject: [PATCH 182/346] Add notes to non-structural const in pattern error message --- compiler/rustc_mir_build/messages.ftl | 4 ++ compiler/rustc_mir_build/src/errors.rs | 6 +++ .../clippy/tests/ui/crashes/ice-6254.stderr | 2 + .../const_in_pattern/cross-crate-fail.stderr | 6 +++ .../const_in_pattern/custom-eq-branch-warn.rs | 2 + .../custom-eq-branch-warn.stderr | 2 + .../const_in_pattern/incomplete-slice.stderr | 2 + .../const_in_pattern/issue-78057.stderr | 3 ++ .../const_in_pattern/no-eq-branch-fail.stderr | 3 ++ .../reject_non_partial_eq.stderr | 3 ++ .../const_in_pattern/reject_non_structural.rs | 22 ++++++++ .../reject_non_structural.stderr | 52 +++++++++++++++---- .../const_in_pattern/warn_corner_cases.stderr | 6 +++ tests/ui/consts/match_ice.stderr | 3 ++ .../const-partial_eq-fallback-ice.stderr | 3 ++ .../pattern/usefulness/consts-opaque.stderr | 29 +++++++++++ ...-hide-behind-direct-struct-embedded.stderr | 3 ++ ...ant-hide-behind-direct-struct-param.stderr | 3 ++ ...ide-behind-doubly-indirect-embedded.stderr | 2 + ...t-hide-behind-doubly-indirect-param.stderr | 2 + ...ide-behind-indirect-struct-embedded.stderr | 2 + ...t-hide-behind-indirect-struct-param.stderr | 2 + ...88-match-slice-forbidden-without-eq.stderr | 3 ++ ...-match-ref-ref-forbidden-without-eq.stderr | 4 ++ .../match-forbidden-without-eq.stderr | 3 ++ ...nonempty-array-forbidden-without-eq.stderr | 3 ++ ...atch-requires-both-partialeq-and-eq.stderr | 3 ++ 27 files changed, 168 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl index 93e7fb330e0..fcc7cbe0715 100644 --- a/compiler/rustc_mir_build/messages.ftl +++ b/compiler/rustc_mir_build/messages.ftl @@ -331,6 +331,10 @@ mir_build_indirect_structural_match = mir_build_nontrivial_structural_match = to use a constant of type `{$non_sm_ty}` in a pattern, the constant's initializer must be trivial or `{$non_sm_ty}` must be annotated with `#[derive(PartialEq, Eq)]` +mir_build_type_not_structural_tip = the traits must be derived, manual `impl`s are not sufficient + +mir_build_type_not_structural_more_info = see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details + mir_build_overlapping_range_endpoints = multiple patterns overlap on their endpoints .range = ... with this range .note = you likely meant to write mutually exclusive ranges diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index dc4d2276e4a..cbfca77bd25 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -663,6 +663,8 @@ pub struct UnionPattern { #[derive(Diagnostic)] #[diag(mir_build_type_not_structural)] +#[note(mir_build_type_not_structural_tip)] +#[note(mir_build_type_not_structural_more_info)] pub struct TypeNotStructural<'tcx> { #[primary_span] pub span: Span, @@ -695,12 +697,16 @@ pub struct PointerPattern; #[derive(LintDiagnostic)] #[diag(mir_build_indirect_structural_match)] +#[note(mir_build_type_not_structural_tip)] +#[note(mir_build_type_not_structural_more_info)] pub struct IndirectStructuralMatch<'tcx> { pub non_sm_ty: Ty<'tcx>, } #[derive(LintDiagnostic)] #[diag(mir_build_nontrivial_structural_match)] +#[note(mir_build_type_not_structural_tip)] +#[note(mir_build_type_not_structural_more_info)] pub struct NontrivialStructuralMatch<'tcx> { pub non_sm_ty: Ty<'tcx>, } diff --git a/src/tools/clippy/tests/ui/crashes/ice-6254.stderr b/src/tools/clippy/tests/ui/crashes/ice-6254.stderr index 22d82a30c6a..263c27d3d64 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-6254.stderr +++ b/src/tools/clippy/tests/ui/crashes/ice-6254.stderr @@ -6,6 +6,8 @@ LL | FOO_REF_REF => {}, | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #62411 + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details = note: `-D indirect-structural-match` implied by `-D warnings` error: aborting due to previous error diff --git a/tests/ui/consts/const_in_pattern/cross-crate-fail.stderr b/tests/ui/consts/const_in_pattern/cross-crate-fail.stderr index a8066a88c35..2f6786999ed 100644 --- a/tests/ui/consts/const_in_pattern/cross-crate-fail.stderr +++ b/tests/ui/consts/const_in_pattern/cross-crate-fail.stderr @@ -3,12 +3,18 @@ error: to use a constant of type `CustomEq` in a pattern, `CustomEq` must be ann | LL | consts::SOME => panic!(), | ^^^^^^^^^^^^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `CustomEq` in a pattern, `CustomEq` must be annotated with `#[derive(PartialEq, Eq)]` --> $DIR/cross-crate-fail.rs:20:9 | LL | ::SOME => panic!(), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: aborting due to 2 previous errors diff --git a/tests/ui/consts/const_in_pattern/custom-eq-branch-warn.rs b/tests/ui/consts/const_in_pattern/custom-eq-branch-warn.rs index 856d204178d..41de5e7b4fe 100644 --- a/tests/ui/consts/const_in_pattern/custom-eq-branch-warn.rs +++ b/tests/ui/consts/const_in_pattern/custom-eq-branch-warn.rs @@ -28,6 +28,8 @@ fn main() { match Foo::Qux(CustomEq) { BAR_BAZ => panic!(), //~^ WARN must be annotated with `#[derive(PartialEq, Eq)]` + //~| NOTE the traits must be derived + //~| NOTE StructuralEq.html for details //~| WARN this was previously accepted //~| NOTE see issue #73448 //~| NOTE `#[warn(nontrivial_structural_match)]` on by default diff --git a/tests/ui/consts/const_in_pattern/custom-eq-branch-warn.stderr b/tests/ui/consts/const_in_pattern/custom-eq-branch-warn.stderr index 22348272275..3f19c67d223 100644 --- a/tests/ui/consts/const_in_pattern/custom-eq-branch-warn.stderr +++ b/tests/ui/consts/const_in_pattern/custom-eq-branch-warn.stderr @@ -6,6 +6,8 @@ LL | BAR_BAZ => panic!(), | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #73448 + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details = note: `#[warn(nontrivial_structural_match)]` on by default warning: 1 warning emitted diff --git a/tests/ui/consts/const_in_pattern/incomplete-slice.stderr b/tests/ui/consts/const_in_pattern/incomplete-slice.stderr index ddc576ced8f..b005f3220e9 100644 --- a/tests/ui/consts/const_in_pattern/incomplete-slice.stderr +++ b/tests/ui/consts/const_in_pattern/incomplete-slice.stderr @@ -6,6 +6,8 @@ LL | E_SL => {} | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #62411 + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details = note: `#[warn(indirect_structural_match)]` on by default error[E0004]: non-exhaustive patterns: `&_` not covered diff --git a/tests/ui/consts/const_in_pattern/issue-78057.stderr b/tests/ui/consts/const_in_pattern/issue-78057.stderr index 35619594f75..df155bdb625 100644 --- a/tests/ui/consts/const_in_pattern/issue-78057.stderr +++ b/tests/ui/consts/const_in_pattern/issue-78057.stderr @@ -3,6 +3,9 @@ error: to use a constant of type `Opaque` in a pattern, `Opaque` must be annotat | LL | FOO => {}, | ^^^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: unreachable pattern --> $DIR/issue-78057.rs:14:9 diff --git a/tests/ui/consts/const_in_pattern/no-eq-branch-fail.stderr b/tests/ui/consts/const_in_pattern/no-eq-branch-fail.stderr index e505dad69be..cced6af499f 100644 --- a/tests/ui/consts/const_in_pattern/no-eq-branch-fail.stderr +++ b/tests/ui/consts/const_in_pattern/no-eq-branch-fail.stderr @@ -3,6 +3,9 @@ error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated wit | LL | BAR_BAZ => panic!(), | ^^^^^^^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: aborting due to previous error diff --git a/tests/ui/consts/const_in_pattern/reject_non_partial_eq.stderr b/tests/ui/consts/const_in_pattern/reject_non_partial_eq.stderr index 95cfa4a9ebe..958bf373cf4 100644 --- a/tests/ui/consts/const_in_pattern/reject_non_partial_eq.stderr +++ b/tests/ui/consts/const_in_pattern/reject_non_partial_eq.stderr @@ -3,6 +3,9 @@ error: to use a constant of type `NoPartialEq` in a pattern, `NoPartialEq` must | LL | NO_PARTIAL_EQ_NONE => println!("NO_PARTIAL_EQ_NONE"), | ^^^^^^^^^^^^^^^^^^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: aborting due to previous error diff --git a/tests/ui/consts/const_in_pattern/reject_non_structural.rs b/tests/ui/consts/const_in_pattern/reject_non_structural.rs index 75fde0d92de..dc6b9a33197 100644 --- a/tests/ui/consts/const_in_pattern/reject_non_structural.rs +++ b/tests/ui/consts/const_in_pattern/reject_non_structural.rs @@ -39,45 +39,67 @@ fn main() { const ENUM: Derive = Derive::Some(NoDerive); match Derive::Some(NoDerive) { ENUM => dbg!(ENUM), _ => panic!("whoops"), }; //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` + //~| NOTE the traits must be derived + //~| NOTE StructuralEq.html for details const FIELD: OND = TrivialEq(Some(NoDerive)).0; match Some(NoDerive) { FIELD => dbg!(FIELD), _ => panic!("whoops"), }; //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` + //~| NOTE the traits must be derived + //~| NOTE StructuralEq.html for details const NO_DERIVE_SOME: OND = Some(NoDerive); const INDIRECT: OND = NO_DERIVE_SOME; match Some(NoDerive) {INDIRECT => dbg!(INDIRECT), _ => panic!("whoops"), }; //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` + //~| NOTE the traits must be derived + //~| NOTE StructuralEq.html for details const TUPLE: (OND, OND) = (None, Some(NoDerive)); match (None, Some(NoDerive)) { TUPLE => dbg!(TUPLE), _ => panic!("whoops"), }; //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` + //~| NOTE the traits must be derived + //~| NOTE StructuralEq.html for details const TYPE_ASCRIPTION: OND = type_ascribe!(Some(NoDerive), OND); match Some(NoDerive) { TYPE_ASCRIPTION => dbg!(TYPE_ASCRIPTION), _ => panic!("whoops"), }; //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` + //~| NOTE the traits must be derived + //~| NOTE StructuralEq.html for details const ARRAY: [OND; 2] = [None, Some(NoDerive)]; match [None, Some(NoDerive)] { ARRAY => dbg!(ARRAY), _ => panic!("whoops"), }; //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` + //~| NOTE the traits must be derived + //~| NOTE StructuralEq.html for details const REPEAT: [OND; 2] = [Some(NoDerive); 2]; match [Some(NoDerive); 2] { REPEAT => dbg!(REPEAT), _ => panic!("whoops"), }; //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` + //~| NOTE the traits must be derived + //~| NOTE StructuralEq.html for details //~| ERROR must be annotated with `#[derive(PartialEq, Eq)]` + //~| NOTE the traits must be derived + //~| NOTE StructuralEq.html for details trait Trait: Sized { const ASSOC: Option; } impl Trait for NoDerive { const ASSOC: Option = Some(NoDerive); } match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), }; //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` + //~| NOTE the traits must be derived + //~| NOTE StructuralEq.html for details const BLOCK: OND = { NoDerive; Some(NoDerive) }; match Some(NoDerive) { BLOCK => dbg!(BLOCK), _ => panic!("whoops"), }; //~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` + //~| NOTE the traits must be derived + //~| NOTE StructuralEq.html for details const ADDR_OF: &OND = &Some(NoDerive); match &Some(NoDerive) { ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops"), }; //~^ WARN must be annotated with `#[derive(PartialEq, Eq)]` + //~| NOTE the traits must be derived + //~| NOTE StructuralEq.html for details //~| WARN previously accepted by the compiler but is being phased out //~| NOTE for more information, see issue #62411 } diff --git a/tests/ui/consts/const_in_pattern/reject_non_structural.stderr b/tests/ui/consts/const_in_pattern/reject_non_structural.stderr index 66019834997..b6e439f2139 100644 --- a/tests/ui/consts/const_in_pattern/reject_non_structural.stderr +++ b/tests/ui/consts/const_in_pattern/reject_non_structural.stderr @@ -3,69 +3,101 @@ error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be ann | LL | match Derive::Some(NoDerive) { ENUM => dbg!(ENUM), _ => panic!("whoops"), }; | ^^^^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/reject_non_structural.rs:44:28 + --> $DIR/reject_non_structural.rs:46:28 | LL | match Some(NoDerive) { FIELD => dbg!(FIELD), _ => panic!("whoops"), }; | ^^^^^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/reject_non_structural.rs:49:27 + --> $DIR/reject_non_structural.rs:53:27 | LL | match Some(NoDerive) {INDIRECT => dbg!(INDIRECT), _ => panic!("whoops"), }; | ^^^^^^^^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/reject_non_structural.rs:53:36 + --> $DIR/reject_non_structural.rs:59:36 | LL | match (None, Some(NoDerive)) { TUPLE => dbg!(TUPLE), _ => panic!("whoops"), }; | ^^^^^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/reject_non_structural.rs:57:28 + --> $DIR/reject_non_structural.rs:65:28 | LL | match Some(NoDerive) { TYPE_ASCRIPTION => dbg!(TYPE_ASCRIPTION), _ => panic!("whoops"), }; | ^^^^^^^^^^^^^^^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/reject_non_structural.rs:61:36 + --> $DIR/reject_non_structural.rs:71:36 | LL | match [None, Some(NoDerive)] { ARRAY => dbg!(ARRAY), _ => panic!("whoops"), }; | ^^^^^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/reject_non_structural.rs:65:33 + --> $DIR/reject_non_structural.rs:77:33 | LL | match [Some(NoDerive); 2] { REPEAT => dbg!(REPEAT), _ => panic!("whoops"), }; | ^^^^^^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/reject_non_structural.rs:65:33 + --> $DIR/reject_non_structural.rs:77:33 | LL | match [Some(NoDerive); 2] { REPEAT => dbg!(REPEAT), _ => panic!("whoops"), }; | ^^^^^^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/reject_non_structural.rs:71:28 + --> $DIR/reject_non_structural.rs:87:28 | LL | match Some(NoDerive) { NoDerive::ASSOC => dbg!(NoDerive::ASSOC), _ => panic!("whoops"), }; | ^^^^^^^^^^^^^^^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/reject_non_structural.rs:75:28 + --> $DIR/reject_non_structural.rs:93:28 | LL | match Some(NoDerive) { BLOCK => dbg!(BLOCK), _ => panic!("whoops"), }; | ^^^^^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]` - --> $DIR/reject_non_structural.rs:79:29 + --> $DIR/reject_non_structural.rs:99:29 | LL | match &Some(NoDerive) { ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops"), }; | ^^^^^^^ | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #62411 + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details note: the lint level is defined here --> $DIR/reject_non_structural.rs:12:9 | diff --git a/tests/ui/consts/const_in_pattern/warn_corner_cases.stderr b/tests/ui/consts/const_in_pattern/warn_corner_cases.stderr index e957a43a13d..8c01d2f65ec 100644 --- a/tests/ui/consts/const_in_pattern/warn_corner_cases.stderr +++ b/tests/ui/consts/const_in_pattern/warn_corner_cases.stderr @@ -6,6 +6,8 @@ LL | match None { Some(_) => panic!("whoops"), INDEX => dbg!(INDEX), }; | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #73448 + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details = note: `#[warn(nontrivial_structural_match)]` on by default warning: to use a constant of type `NoDerive` in a pattern, the constant's initializer must be trivial or `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]` @@ -16,6 +18,8 @@ LL | match None { Some(_) => panic!("whoops"), CALL => dbg!(CALL), }; | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #73448 + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details warning: to use a constant of type `NoDerive` in a pattern, the constant's initializer must be trivial or `NoDerive` must be annotated with `#[derive(PartialEq, Eq)]` --> $DIR/warn_corner_cases.rs:38:47 @@ -25,6 +29,8 @@ LL | match None { Some(_) => panic!("whoops"), METHOD_CALL => dbg!(METHOD_CA | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #73448 + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details warning: 3 warnings emitted diff --git a/tests/ui/consts/match_ice.stderr b/tests/ui/consts/match_ice.stderr index 699b4a5e200..342d94ed31c 100644 --- a/tests/ui/consts/match_ice.stderr +++ b/tests/ui/consts/match_ice.stderr @@ -3,6 +3,9 @@ error: to use a constant of type `S` in a pattern, `S` must be annotated with `# | LL | C => {} | ^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: aborting due to previous error diff --git a/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr b/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr index 358421cd6d2..dbd46da4413 100644 --- a/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr +++ b/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr @@ -3,6 +3,9 @@ error: to use a constant of type `MyType` in a pattern, `MyType` must be annotat | LL | if let CONSTANT = &&MyType { | ^^^^^^^^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: aborting due to previous error diff --git a/tests/ui/pattern/usefulness/consts-opaque.stderr b/tests/ui/pattern/usefulness/consts-opaque.stderr index 35396751abe..08e3d76b538 100644 --- a/tests/ui/pattern/usefulness/consts-opaque.stderr +++ b/tests/ui/pattern/usefulness/consts-opaque.stderr @@ -3,6 +3,9 @@ error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated wit | LL | FOO => {} | ^^^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: unreachable pattern --> $DIR/consts-opaque.rs:32:9 @@ -24,6 +27,9 @@ error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated wit | LL | FOO_REF => {} | ^^^^^^^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: unreachable pattern --> $DIR/consts-opaque.rs:39:9 @@ -42,6 +48,8 @@ LL | FOO_REF_REF => {} | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #62411 + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details = note: `#[warn(indirect_structural_match)]` on by default error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]` @@ -49,6 +57,9 @@ error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated wit | LL | BAR => {} // should not be emitting unreachable warning | ^^^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: unreachable pattern --> $DIR/consts-opaque.rs:53:9 @@ -72,6 +83,9 @@ error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated wit | LL | BAR => {} | ^^^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: unreachable pattern --> $DIR/consts-opaque.rs:63:9 @@ -96,12 +110,18 @@ error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated wit | LL | BAR => {} | ^^^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: to use a constant of type `Bar` in a pattern, `Bar` must be annotated with `#[derive(PartialEq, Eq)]` --> $DIR/consts-opaque.rs:72:9 | LL | BAR => {} // should not be emitting unreachable warning | ^^^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: unreachable pattern --> $DIR/consts-opaque.rs:72:9 @@ -126,6 +146,9 @@ error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated wit | LL | BAZ => {} | ^^^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: unreachable pattern --> $DIR/consts-opaque.rs:82:9 @@ -150,6 +173,9 @@ error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated wit | LL | BAZ => {} | ^^^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: unreachable pattern --> $DIR/consts-opaque.rs:92:9 @@ -165,6 +191,9 @@ error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated wit | LL | BAZ => {} | ^^^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: unreachable pattern --> $DIR/consts-opaque.rs:99:9 diff --git a/tests/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.stderr b/tests/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.stderr index c73a6cf1326..f08ba522a93 100644 --- a/tests/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.stderr +++ b/tests/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-embedded.stderr @@ -3,6 +3,9 @@ error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be ann | LL | WRAP_DIRECT_INLINE => { panic!("WRAP_DIRECT_INLINE matched itself"); } | ^^^^^^^^^^^^^^^^^^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: aborting due to previous error diff --git a/tests/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.stderr b/tests/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.stderr index 6fdf9db89b8..012ccab176c 100644 --- a/tests/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.stderr +++ b/tests/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-direct-struct-param.stderr @@ -3,6 +3,9 @@ error: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be ann | LL | WRAP_DIRECT_PARAM => { panic!("WRAP_DIRECT_PARAM matched itself"); } | ^^^^^^^^^^^^^^^^^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: aborting due to previous error diff --git a/tests/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr b/tests/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr index 10dd635ff96..94ee2216e9e 100644 --- a/tests/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr +++ b/tests/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr @@ -6,6 +6,8 @@ LL | WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLIN | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #62411 + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details note: the lint level is defined here --> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:7:9 | diff --git a/tests/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr b/tests/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr index 66aecbc4f30..666b7b95ec9 100644 --- a/tests/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr +++ b/tests/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr @@ -6,6 +6,8 @@ LL | WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #62411 + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details note: the lint level is defined here --> $DIR/cant-hide-behind-doubly-indirect-param.rs:7:9 | diff --git a/tests/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr b/tests/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr index ee92954a693..ecbe83f3dec 100644 --- a/tests/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr +++ b/tests/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr @@ -6,6 +6,8 @@ LL | WRAP_INDIRECT_INLINE => { panic!("WRAP_INDIRECT_INLINE matched itse | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #62411 + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details note: the lint level is defined here --> $DIR/cant-hide-behind-indirect-struct-embedded.rs:7:9 | diff --git a/tests/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr b/tests/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr index f0c492d6a73..2119908013b 100644 --- a/tests/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr +++ b/tests/ui/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr @@ -6,6 +6,8 @@ LL | WRAP_INDIRECT_PARAM => { panic!("WRAP_INDIRECT_PARAM matched itself | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #62411 + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details note: the lint level is defined here --> $DIR/cant-hide-behind-indirect-struct-param.rs:7:9 | diff --git a/tests/ui/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.stderr b/tests/ui/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.stderr index 0bf369fa8cb..46600e7b215 100644 --- a/tests/ui/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.stderr +++ b/tests/ui/rfc-1445-restrict-constants-in-patterns/issue-61188-match-slice-forbidden-without-eq.stderr @@ -3,6 +3,9 @@ error: to use a constant of type `B` in a pattern, `B` must be annotated with `# | LL | A => (), | ^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: aborting due to previous error diff --git a/tests/ui/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr b/tests/ui/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr index 955ab4b548b..435812306de 100644 --- a/tests/ui/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr +++ b/tests/ui/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr @@ -6,6 +6,8 @@ LL | RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0); | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #62411 + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details note: the lint level is defined here --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:13:9 | @@ -20,6 +22,8 @@ LL | RR_B1 => { println!("CLAIM RR1: {:?} matches {:?}", RR_B1, RR_B1); | = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #62411 + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details warning: 2 warnings emitted diff --git a/tests/ui/rfc-1445-restrict-constants-in-patterns/match-forbidden-without-eq.stderr b/tests/ui/rfc-1445-restrict-constants-in-patterns/match-forbidden-without-eq.stderr index 616ed9e484b..1c4fb914688 100644 --- a/tests/ui/rfc-1445-restrict-constants-in-patterns/match-forbidden-without-eq.stderr +++ b/tests/ui/rfc-1445-restrict-constants-in-patterns/match-forbidden-without-eq.stderr @@ -3,6 +3,9 @@ error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated wit | LL | FOO => { } | ^^^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details warning: floating-point types cannot be used in patterns --> $DIR/match-forbidden-without-eq.rs:18:9 diff --git a/tests/ui/rfc-1445-restrict-constants-in-patterns/match-nonempty-array-forbidden-without-eq.stderr b/tests/ui/rfc-1445-restrict-constants-in-patterns/match-nonempty-array-forbidden-without-eq.stderr index 371f8a0aa1d..6adebada043 100644 --- a/tests/ui/rfc-1445-restrict-constants-in-patterns/match-nonempty-array-forbidden-without-eq.stderr +++ b/tests/ui/rfc-1445-restrict-constants-in-patterns/match-nonempty-array-forbidden-without-eq.stderr @@ -3,6 +3,9 @@ error: to use a constant of type `B` in a pattern, `B` must be annotated with `# | LL | FOO => { } | ^^^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: aborting due to previous error diff --git a/tests/ui/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.stderr b/tests/ui/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.stderr index 4157cf65283..f5b10f0626b 100644 --- a/tests/ui/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.stderr +++ b/tests/ui/rfc-1445-restrict-constants-in-patterns/match-requires-both-partialeq-and-eq.stderr @@ -3,6 +3,9 @@ error: to use a constant of type `Foo` in a pattern, `Foo` must be annotated wit | LL | FOO => { } | ^^^ + | + = note: the traits must be derived, manual `impl`s are not sufficient + = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralEq.html for details error: aborting due to previous error From ed5c0f66ac18696c1b6388559b03ffc30b33e355 Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Sat, 11 Dec 2021 15:24:38 +0000 Subject: [PATCH 183/346] socket ancillary data implementation for FreeBSD (from 13 and above). introducing new build config as well. --- library/std/build.rs | 3 + library/std/src/os/unix/net/ancillary.rs | 139 +++++++++++++++++++++-- library/std/src/os/unix/net/datagram.rs | 36 +++++- library/std/src/os/unix/net/stream.rs | 36 +++++- library/std/src/os/unix/net/tests.rs | 2 +- library/std/src/sys/unix/net.rs | 11 ++ src/bootstrap/lib.rs | 1 + 7 files changed, 208 insertions(+), 20 deletions(-) diff --git a/library/std/build.rs b/library/std/build.rs index ea879667558..cf708db6f27 100644 --- a/library/std/build.rs +++ b/library/std/build.rs @@ -6,6 +6,9 @@ fn main() { if target.contains("freebsd") { if env::var("RUST_STD_FREEBSD_12_ABI").is_ok() { println!("cargo:rustc-cfg=freebsd12"); + } else if env::var("RUST_STD_FREEBSD_13_ABI").is_ok() { + println!("cargo:rustc-cfg=freebsd12"); + println!("cargo:rustc-cfg=freebsd13"); } } else if target.contains("linux") || target.contains("netbsd") diff --git a/library/std/src/os/unix/net/ancillary.rs b/library/std/src/os/unix/net/ancillary.rs index 7cc901a7944..7565fbc0d09 100644 --- a/library/std/src/os/unix/net/ancillary.rs +++ b/library/std/src/os/unix/net/ancillary.rs @@ -86,7 +86,12 @@ fn add_to_ancillary_data( cmsg_level: libc::c_int, cmsg_type: libc::c_int, ) -> bool { - let source_len = if let Some(source_len) = source.len().checked_mul(size_of::()) { + #[cfg(not(target_os = "freebsd"))] + let cmsg_size = source.len().checked_mul(size_of::()); + #[cfg(target_os = "freebsd")] + let cmsg_size = Some(unsafe { libc::SOCKCRED2SIZE(1) }); + + let source_len = if let Some(source_len) = cmsg_size { if let Ok(source_len) = u32::try_from(source_len) { source_len } else { @@ -178,7 +183,13 @@ impl<'a, T> Iterator for AncillaryDataIter<'a, T> { } } -#[cfg(all(doc, not(target_os = "android"), not(target_os = "linux"), not(target_os = "netbsd")))] +#[cfg(all( + doc, + not(target_os = "android"), + not(target_os = "linux"), + not(target_os = "netbsd"), + not(target_os = "freebsd") +))] #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] #[derive(Clone)] pub struct SocketCred(()); @@ -194,6 +205,11 @@ pub struct SocketCred(libc::ucred); #[derive(Clone)] pub struct SocketCred(libc::sockcred); +#[cfg(target_os = "freebsd")] +#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] +#[derive(Clone)] +pub struct SocketCred(libc::sockcred2); + #[doc(cfg(any(target_os = "android", target_os = "linux")))] #[cfg(any(target_os = "android", target_os = "linux"))] impl SocketCred { @@ -246,6 +262,66 @@ impl SocketCred { } } +#[cfg(target_os = "freebsd")] +impl SocketCred { + /// Create a Unix credential struct. + /// + /// PID, UID and GID is set to 0. + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + #[must_use] + pub fn new() -> SocketCred { + SocketCred(libc::sockcred2 { + sc_version: 0, + sc_pid: 0, + sc_uid: 0, + sc_euid: 0, + sc_gid: 0, + sc_egid: 0, + sc_ngroups: 0, + sc_groups: [0; 1], + }) + } + + /// Set the PID. + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn set_pid(&mut self, pid: libc::pid_t) { + self.0.sc_pid = pid; + } + + /// Get the current PID. + #[must_use] + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn get_pid(&self) -> libc::pid_t { + self.0.sc_pid + } + + /// Set the UID. + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn set_uid(&mut self, uid: libc::uid_t) { + self.0.sc_euid = uid; + } + + /// Get the current UID. + #[must_use] + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn get_uid(&self) -> libc::uid_t { + self.0.sc_euid + } + + /// Set the GID. + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn set_gid(&mut self, gid: libc::gid_t) { + self.0.sc_egid = gid; + } + + /// Get the current GID. + #[must_use] + #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] + pub fn get_gid(&self) -> libc::gid_t { + self.0.sc_egid + } +} + #[cfg(target_os = "netbsd")] impl SocketCred { /// Create a Unix credential struct. @@ -271,6 +347,7 @@ impl SocketCred { } /// Get the current PID. + #[must_use] #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] pub fn get_pid(&self) -> libc::pid_t { self.0.sc_pid @@ -283,6 +360,7 @@ impl SocketCred { } /// Get the current UID. + #[must_use] #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] pub fn get_uid(&self) -> libc::uid_t { self.0.sc_uid @@ -295,6 +373,7 @@ impl SocketCred { } /// Get the current GID. + #[must_use] #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] pub fn get_gid(&self) -> libc::gid_t { self.0.sc_gid @@ -316,7 +395,13 @@ impl<'a> Iterator for ScmRights<'a> { } } -#[cfg(all(doc, not(target_os = "android"), not(target_os = "linux"), not(target_os = "netbsd")))] +#[cfg(all( + doc, + not(target_os = "android"), + not(target_os = "linux"), + not(target_os = "netbsd"), + not(target_os = "freebsd") +))] #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] pub struct ScmCredentials<'a>(AncillaryDataIter<'a, ()>); @@ -327,11 +412,21 @@ pub struct ScmCredentials<'a>(AncillaryDataIter<'a, ()>); #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] pub struct ScmCredentials<'a>(AncillaryDataIter<'a, libc::ucred>); +#[cfg(target_os = "freebsd")] +#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] +pub struct ScmCredentials<'a>(AncillaryDataIter<'a, libc::sockcred2>); + #[cfg(target_os = "netbsd")] #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] pub struct ScmCredentials<'a>(AncillaryDataIter<'a, libc::sockcred>); -#[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "netbsd",))] +#[cfg(any( + doc, + target_os = "android", + target_os = "linux", + target_os = "netbsd", + target_os = "freebsd" +))] #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] impl<'a> Iterator for ScmCredentials<'a> { type Item = SocketCred; @@ -353,7 +448,13 @@ pub enum AncillaryError { #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] pub enum AncillaryData<'a> { ScmRights(ScmRights<'a>), - #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "netbsd",))] + #[cfg(any( + doc, + target_os = "android", + target_os = "linux", + target_os = "netbsd", + target_os = "freebsd" + ))] ScmCredentials(ScmCredentials<'a>), } @@ -376,7 +477,13 @@ impl<'a> AncillaryData<'a> { /// /// `data` must contain a valid control message and the control message must be type of /// `SOL_SOCKET` and level of `SCM_CREDENTIALS` or `SCM_CREDS`. - #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "netbsd",))] + #[cfg(any( + doc, + target_os = "android", + target_os = "linux", + target_os = "netbsd", + target_os = "freebsd" + ))] unsafe fn as_credentials(data: &'a [u8]) -> Self { let ancillary_data_iter = AncillaryDataIter::new(data); let scm_credentials = ScmCredentials(ancillary_data_iter); @@ -395,6 +502,8 @@ impl<'a> AncillaryData<'a> { libc::SCM_RIGHTS => Ok(AncillaryData::as_rights(data)), #[cfg(any(target_os = "android", target_os = "linux",))] libc::SCM_CREDENTIALS => Ok(AncillaryData::as_credentials(data)), + #[cfg(target_os = "freebsd")] + libc::SCM_CREDS2 => Ok(AncillaryData::as_credentials(data)), #[cfg(target_os = "netbsd")] libc::SCM_CREDS => Ok(AncillaryData::as_credentials(data)), cmsg_type => { @@ -603,12 +712,18 @@ impl<'a> SocketAncillary<'a> { /// Add credentials to the ancillary data. /// - /// The function returns `true` if there was enough space in the buffer. - /// If there was not enough space then no credentials was appended. + /// The function returns `true` if there is enough space in the buffer. + /// If there is not enough space then no credentials will be appended. /// Technically, that means this operation adds a control message with the level `SOL_SOCKET` - /// and type `SCM_CREDENTIALS` or `SCM_CREDS`. + /// and type `SCM_CREDENTIALS`, `SCM_CREDS`, or `SCM_CREDS2`. /// - #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "netbsd",))] + #[cfg(any( + doc, + target_os = "android", + target_os = "linux", + target_os = "netbsd", + target_os = "freebsd" + ))] #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] pub fn add_creds(&mut self, creds: &[SocketCred]) -> bool { self.truncated = false; @@ -617,8 +732,10 @@ impl<'a> SocketAncillary<'a> { &mut self.length, creds, libc::SOL_SOCKET, - #[cfg(not(target_os = "netbsd"))] + #[cfg(not(any(target_os = "netbsd", target_os = "freebsd")))] libc::SCM_CREDENTIALS, + #[cfg(target_os = "freebsd")] + libc::SCM_CREDS2, #[cfg(target_os = "netbsd")] libc::SCM_CREDS, ) diff --git a/library/std/src/os/unix/net/datagram.rs b/library/std/src/os/unix/net/datagram.rs index e64569758a0..41cdcda4613 100644 --- a/library/std/src/os/unix/net/datagram.rs +++ b/library/std/src/os/unix/net/datagram.rs @@ -808,8 +808,24 @@ impl UnixDatagram { /// /// # Examples /// - #[cfg_attr(any(target_os = "android", target_os = "linux"), doc = "```no_run")] - #[cfg_attr(not(any(target_os = "android", target_os = "linux")), doc = "```ignore")] + #[cfg_attr( + any( + target_os = "android", + target_os = "linux", + target_os = "netbsd", + target_os = "freebsd", + ), + doc = "```no_run" + )] + #[cfg_attr( + not(any( + target_os = "android", + target_os = "linux", + target_os = "netbsd", + target_os = "freebsd" + )), + doc = "```ignore" + )] /// #![feature(unix_socket_ancillary_data)] /// use std::os::unix::net::UnixDatagram; /// @@ -819,7 +835,13 @@ impl UnixDatagram { /// Ok(()) /// } /// ``` - #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "netbsd",))] + #[cfg(any( + doc, + target_os = "android", + target_os = "linux", + target_os = "netbsd", + target_os = "freebsd" + ))] #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] pub fn set_passcred(&self, passcred: bool) -> io::Result<()> { self.0.set_passcred(passcred) @@ -831,7 +853,13 @@ impl UnixDatagram { /// Get the socket option `SO_PASSCRED`. /// /// [`set_passcred`]: UnixDatagram::set_passcred - #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "netbsd",))] + #[cfg(any( + doc, + target_os = "android", + target_os = "linux", + target_os = "netbsd", + target_os = "freebsd" + ))] #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] pub fn passcred(&self) -> io::Result { self.0.passcred() diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs index 65cb4ae07a5..5aa3fb92576 100644 --- a/library/std/src/os/unix/net/stream.rs +++ b/library/std/src/os/unix/net/stream.rs @@ -397,8 +397,24 @@ impl UnixStream { /// /// # Examples /// - #[cfg_attr(any(target_os = "android", target_os = "linux"), doc = "```no_run")] - #[cfg_attr(not(any(target_os = "android", target_os = "linux")), doc = "```ignore")] + #[cfg_attr( + any( + target_os = "android", + target_os = "linux", + target_os = "netbsd", + target_os = "freebsd" + ), + doc = "```no_run" + )] + #[cfg_attr( + not(any( + target_os = "android", + target_os = "linux", + target_os = "netbsd", + target_os = "freebsd" + )), + doc = "```ignore" + )] /// #![feature(unix_socket_ancillary_data)] /// use std::os::unix::net::UnixStream; /// @@ -408,7 +424,13 @@ impl UnixStream { /// Ok(()) /// } /// ``` - #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "netbsd",))] + #[cfg(any( + doc, + target_os = "android", + target_os = "linux", + target_os = "netbsd", + target_os = "freebsd" + ))] #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] pub fn set_passcred(&self, passcred: bool) -> io::Result<()> { self.0.set_passcred(passcred) @@ -420,7 +442,13 @@ impl UnixStream { /// Get the socket option `SO_PASSCRED`. /// /// [`set_passcred`]: UnixStream::set_passcred - #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "netbsd",))] + #[cfg(any( + doc, + target_os = "android", + target_os = "linux", + target_os = "netbsd", + target_os = "freebsd" + ))] #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")] pub fn passcred(&self) -> io::Result { self.0.passcred() diff --git a/library/std/src/os/unix/net/tests.rs b/library/std/src/os/unix/net/tests.rs index f8c29a6d3a1..39f10c50dc4 100644 --- a/library/std/src/os/unix/net/tests.rs +++ b/library/std/src/os/unix/net/tests.rs @@ -646,7 +646,7 @@ fn test_send_vectored_fds_unix_stream() { } } -#[cfg(any(target_os = "android", target_os = "linux",))] +#[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))] #[test] fn test_send_vectored_with_ancillary_to_unix_datagram() { fn getpid() -> libc::pid_t { diff --git a/library/std/src/sys/unix/net.rs b/library/std/src/sys/unix/net.rs index f84240d268f..573bfa6587e 100644 --- a/library/std/src/sys/unix/net.rs +++ b/library/std/src/sys/unix/net.rs @@ -443,6 +443,17 @@ impl Socket { Ok(passcred != 0) } + #[cfg(target_os = "freebsd")] + pub fn set_passcred(&self, passcred: bool) -> io::Result<()> { + setsockopt(self, libc::AF_LOCAL, libc::LOCAL_CREDS_PERSISTENT, passcred as libc::c_int) + } + + #[cfg(target_os = "freebsd")] + pub fn passcred(&self) -> io::Result { + let passcred: libc::c_int = getsockopt(self, libc::AF_LOCAL, libc::LOCAL_CREDS_PERSISTENT)?; + Ok(passcred != 0) + } + #[cfg(not(any(target_os = "solaris", target_os = "illumos")))] pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { let mut nonblocking = nonblocking as libc::c_int; diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 54aa5a585bb..4c95169722a 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -125,6 +125,7 @@ const EXTRA_CHECK_CFGS: &[(Option, &'static str, Option<&[&'static str]>)] (Some(Mode::Std), "no_rc", None), (Some(Mode::Std), "no_sync", None), (Some(Mode::Std), "freebsd12", None), + (Some(Mode::Std), "freebsd13", None), (Some(Mode::Std), "backtrace_in_libstd", None), /* Extra values not defined in the built-in targets yet, but used in std */ (Some(Mode::Std), "target_env", Some(&["libnx"])), From 3f80529c643be8449fc755adc6bb37e2ea92114b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 27 Mar 2023 15:52:17 +0000 Subject: [PATCH 184/346] make InitMask lazy for fully init/uninit cases Avoid materializing bits in the InitMask bitset when a single value would be enough: when the mask represents a fully initialized or fully uninitialized const allocation. --- .../src/mir/interpret/allocation/init_mask.rs | 283 ++++++++++++++---- 1 file changed, 225 insertions(+), 58 deletions(-) diff --git a/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs b/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs index 82e9a961a2b..3f7e2523106 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs @@ -10,20 +10,185 @@ type Block = u64; /// A bitmask where each bit refers to the byte with the same index. If the bit is `true`, the byte /// is initialized. If it is `false` the byte is uninitialized. -// Note: for performance reasons when interning, some of the `InitMask` fields can be partially -// hashed. (see the `Hash` impl below for more details), so the impl is not derived. -#[derive(Clone, Debug, Eq, PartialEq, TyEncodable, TyDecodable)] -#[derive(HashStable)] +/// The actual bits are only materialized when needed, and we try to keep this data lazy as long as +/// possible. Currently, if all the blocks have the same value, then the mask represents either a +/// fully initialized or fully uninitialized const allocation, so we can only store that single +/// value. +#[derive(Clone, Debug, Eq, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)] pub struct InitMask { - blocks: Vec, + pub(crate) blocks: InitMaskBlocks, len: Size, } +#[derive(Clone, Debug, Eq, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)] +pub(crate) enum InitMaskBlocks { + Lazy { + /// Whether the lazy init mask is fully initialized or uninitialized. + state: bool, + }, + Materialized(InitMaskMaterialized), +} + +impl InitMask { + pub fn new(size: Size, state: bool) -> Self { + // Blocks start lazily allocated, until we have to materialize them. + let blocks = InitMaskBlocks::Lazy { state }; + InitMask { len: size, blocks } + } + + /// Checks whether the `range` is entirely initialized. + /// + /// Returns `Ok(())` if it's initialized. Otherwise returns a range of byte + /// indexes for the first contiguous span of the uninitialized access. + #[inline] + pub fn is_range_initialized(&self, range: AllocRange) -> Result<(), AllocRange> { + let end = range.end(); + if end > self.len { + return Err(AllocRange::from(self.len..end)); + } + + match self.blocks { + InitMaskBlocks::Lazy { state } => { + // Lazily allocated blocks represent the full mask, and cover the requested range by + // definition. + if state { Ok(()) } else { Err(range) } + } + InitMaskBlocks::Materialized(ref blocks) => { + blocks.is_range_initialized(range.start, end) + } + } + } + + /// Sets a specified range to a value. If the range is out-of-bounds, the mask will grow to + /// accomodate it entirely. + pub fn set_range(&mut self, range: AllocRange, new_state: bool) { + let start = range.start; + let end = range.end(); + + let is_full_overwrite = start == Size::ZERO && end >= self.len; + + // Optimize the cases of a full init/uninit state, while handling growth if needed. + match self.blocks { + InitMaskBlocks::Lazy { ref mut state } if is_full_overwrite => { + // This is fully overwriting the mask, and we'll still have a single initialization + // state: the blocks can stay lazy. + *state = new_state; + self.len = end; + } + InitMaskBlocks::Materialized(_) if is_full_overwrite => { + // This is also fully overwriting materialized blocks with a single initialization + // state: we'll have no need for these blocks anymore and can make them lazy. + self.blocks = InitMaskBlocks::Lazy { state: new_state }; + self.len = end; + } + InitMaskBlocks::Lazy { state } if state == new_state => { + // Here we're partially overwriting the mask but the initialization state doesn't + // change: the blocks can stay lazy. + if end > self.len { + self.len = end; + } + } + _ => { + // Otherwise, we have a partial overwrite that can result in a mix of initialization + // states, so we'll need materialized blocks. + let len = self.len; + let blocks = self.materialize_blocks(); + + // There are 3 cases of interest here, if we have: + // + // [--------] + // ^ ^ + // 0 len + // + // 1) the range to set can be in-bounds: + // + // xxxx = [start, end] + // [--------] + // ^ ^ + // 0 len + // + // Here, we'll simply set the single `start` to `end` range. + // + // 2) the range to set can be partially out-of-bounds: + // + // xxxx = [start, end] + // [--------] + // ^ ^ + // 0 len + // + // We have 2 subranges to handle: + // - we'll set the existing `start` to `len` range. + // - we'll grow and set the `len` to `end` range. + // + // 3) the range to set can be fully out-of-bounds: + // + // ---xxxx = [start, end] + // [--------] + // ^ ^ + // 0 len + // + // Since we're growing the mask to a single `new_state` value, we consider the gap + // from `len` to `start` to be part of the range, and have a single subrange to + // handle: we'll grow and set the `len` to `end` range. + // + // Note that we have to materialize, set blocks, and grow the mask. We could + // therefore slightly optimize things in situations where these writes overlap. + // However, as of writing this, growing the mask doesn't happen in practice yet, so + // we don't do this micro-optimization. + + if end <= len { + // Handle case 1. + blocks.set_range_inbounds(start, end, new_state); + } else { + if start < len { + // Handle the first subrange of case 2. + blocks.set_range_inbounds(start, len, new_state); + } + + // Handle the second subrange of case 2, and case 3. + blocks.grow(len, end - len, new_state); // `Size` operation + self.len = end; + } + } + } + } + + /// Materializes this mask's blocks when the mask is lazy. + #[inline] + fn materialize_blocks(&mut self) -> &mut InitMaskMaterialized { + if let InitMaskBlocks::Lazy { state } = self.blocks { + self.blocks = InitMaskBlocks::Materialized(InitMaskMaterialized::new(self.len, state)); + } + + let InitMaskBlocks::Materialized(ref mut blocks) = self.blocks else { + bug!("initmask blocks must be materialized here") + }; + blocks + } + + /// Returns the initialization state at the specified in-bounds index. + #[inline] + pub fn get(&self, idx: Size) -> bool { + match self.blocks { + InitMaskBlocks::Lazy { state } => state, + InitMaskBlocks::Materialized(ref blocks) => blocks.get(idx), + } + } +} + +/// The actual materialized blocks of the bitmask, when we can't keep the `InitMask` lazy. +// Note: for performance reasons when interning, some of the fields can be partially +// hashed. (see the `Hash` impl below for more details), so the impl is not derived. +#[derive(Clone, Debug, Eq, PartialEq, TyEncodable, TyDecodable, HashStable)] +pub(crate) struct InitMaskMaterialized { + pub(crate) blocks: Vec, +} + // Const allocations are only hashed for interning. However, they can be large, making the hashing // expensive especially since it uses `FxHash`: it's better suited to short keys, not potentially // big buffers like the allocation's init mask. We can partially hash some fields when they're // large. -impl hash::Hash for InitMask { +impl hash::Hash for InitMaskMaterialized { fn hash(&self, state: &mut H) { const MAX_BLOCKS_TO_HASH: usize = super::MAX_BYTES_TO_HASH / std::mem::size_of::(); const MAX_BLOCKS_LEN: usize = super::MAX_HASHED_BUFFER_LEN / std::mem::size_of::(); @@ -41,18 +206,15 @@ impl hash::Hash for InitMask { } else { self.blocks.hash(state); } - - // Hash the other fields as usual. - self.len.hash(state); } } -impl InitMask { +impl InitMaskMaterialized { pub const BLOCK_SIZE: u64 = 64; - pub fn new(size: Size, state: bool) -> Self { - let mut m = InitMask { blocks: vec![], len: Size::ZERO }; - m.grow(size, state); + fn new(size: Size, state: bool) -> Self { + let mut m = InitMaskMaterialized { blocks: vec![] }; + m.grow(Size::ZERO, size, state); m } @@ -62,8 +224,8 @@ impl InitMask { // Each bit in a `Block` represents the initialization state of one byte of an allocation, // so we use `.bytes()` here. let bits = bits.bytes(); - let a = bits / InitMask::BLOCK_SIZE; - let b = bits % InitMask::BLOCK_SIZE; + let a = bits / Self::BLOCK_SIZE; + let b = bits % Self::BLOCK_SIZE; (usize::try_from(a).unwrap(), usize::try_from(b).unwrap()) } @@ -71,7 +233,7 @@ impl InitMask { fn size_from_bit_index(block: impl TryInto, bit: impl TryInto) -> Size { let block = block.try_into().ok().unwrap(); let bit = bit.try_into().ok().unwrap(); - Size::from_bytes(block * InitMask::BLOCK_SIZE + bit) + Size::from_bytes(block * Self::BLOCK_SIZE + bit) } /// Checks whether the `range` is entirely initialized. @@ -79,13 +241,8 @@ impl InitMask { /// Returns `Ok(())` if it's initialized. Otherwise returns a range of byte /// indexes for the first contiguous span of the uninitialized access. #[inline] - pub fn is_range_initialized(&self, range: AllocRange) -> Result<(), AllocRange> { - let end = range.end(); - if end > self.len { - return Err(AllocRange::from(self.len..end)); - } - - let uninit_start = self.find_bit(range.start, end, false); + fn is_range_initialized(&self, start: Size, end: Size) -> Result<(), AllocRange> { + let uninit_start = self.find_bit(start, end, false); match uninit_start { Some(uninit_start) => { @@ -96,15 +253,6 @@ impl InitMask { } } - pub fn set_range(&mut self, range: AllocRange, new_state: bool) { - let end = range.end(); - let len = self.len; - if end > len { - self.grow(end - len, new_state); - } - self.set_range_inbounds(range.start, end, new_state); - } - fn set_range_inbounds(&mut self, start: Size, end: Size, new_state: bool) { let (blocka, bita) = Self::bit_index(start); let (blockb, bitb) = Self::bit_index(end); @@ -150,27 +298,35 @@ impl InitMask { } #[inline] - pub fn get(&self, i: Size) -> bool { + fn get(&self, i: Size) -> bool { let (block, bit) = Self::bit_index(i); (self.blocks[block] & (1 << bit)) != 0 } - fn grow(&mut self, amount: Size, new_state: bool) { + fn grow(&mut self, len: Size, amount: Size, new_state: bool) { if amount.bytes() == 0 { return; } let unused_trailing_bits = - u64::try_from(self.blocks.len()).unwrap() * Self::BLOCK_SIZE - self.len.bytes(); + u64::try_from(self.blocks.len()).unwrap() * Self::BLOCK_SIZE - len.bytes(); + + // If there's not enough capacity in the currently allocated blocks, allocate some more. if amount.bytes() > unused_trailing_bits { let additional_blocks = amount.bytes() / Self::BLOCK_SIZE + 1; - self.blocks.extend( - // FIXME(oli-obk): optimize this by repeating `new_state as Block`. - iter::repeat(0).take(usize::try_from(additional_blocks).unwrap()), - ); + + // We allocate the blocks to the correct value for the requested init state, so we won't + // have to manually set them with another write. + let block = if new_state { u64::MAX } else { 0 }; + self.blocks + .extend(iter::repeat(block).take(usize::try_from(additional_blocks).unwrap())); + } + + // New blocks have already been set here, so we only need to set the unused trailing bits, + // if any. + if unused_trailing_bits > 0 { + let in_bounds_tail = Size::from_bytes(unused_trailing_bits); + self.set_range_inbounds(len, len + in_bounds_tail, new_state); // `Size` operation } - let start = self.len; - self.len += amount; - self.set_range_inbounds(start, start + amount, new_state); // `Size` operation } /// Returns the index of the first bit in `start..end` (end-exclusive) that is equal to is_init. @@ -188,7 +344,7 @@ impl InitMask { /// ``` /// Also, if not stated, assume that `is_init = true`, that is, we are searching for the first 1 bit. fn find_bit_fast( - init_mask: &InitMask, + init_mask: &InitMaskMaterialized, start: Size, end: Size, is_init: bool, @@ -223,7 +379,7 @@ impl InitMask { None } else { let bit = bits.trailing_zeros(); - Some(InitMask::size_from_bit_index(block, bit)) + Some(InitMaskMaterialized::size_from_bit_index(block, bit)) } } @@ -253,9 +409,9 @@ impl InitMask { // This provides the desired behavior of searching blocks 0 and 1 for (a), // and searching only block 0 for (b). // There is no concern of overflows since we checked for `start >= end` above. - let (start_block, start_bit) = InitMask::bit_index(start); + let (start_block, start_bit) = InitMaskMaterialized::bit_index(start); let end_inclusive = Size::from_bytes(end.bytes() - 1); - let (end_block_inclusive, _) = InitMask::bit_index(end_inclusive); + let (end_block_inclusive, _) = InitMaskMaterialized::bit_index(end_inclusive); // Handle first block: need to skip `start_bit` bits. // @@ -340,7 +496,7 @@ impl InitMask { #[cfg_attr(not(debug_assertions), allow(dead_code))] fn find_bit_slow( - init_mask: &InitMask, + init_mask: &InitMaskMaterialized, start: Size, end: Size, is_init: bool, @@ -436,10 +592,19 @@ impl<'a> Iterator for InitChunkIter<'a> { return None; } - let end_of_chunk = - self.init_mask.find_bit(self.start, self.end, !self.is_init).unwrap_or(self.end); + let end_of_chunk = match self.init_mask.blocks { + InitMaskBlocks::Lazy { .. } => { + // If we're iterating over the chunks of lazy blocks, we just emit a single + // full-size chunk. + self.end + } + InitMaskBlocks::Materialized(ref blocks) => { + let end_of_chunk = + blocks.find_bit(self.start, self.end, !self.is_init).unwrap_or(self.end); + end_of_chunk + } + }; let range = self.start..end_of_chunk; - let ret = Some(if self.is_init { InitChunk::Init(range) } else { InitChunk::Uninit(range) }); @@ -504,17 +669,19 @@ impl InitMask { /// Applies multiple instances of the run-length encoding to the initialization mask. pub fn apply_copy(&mut self, defined: InitCopy, range: AllocRange, repeat: u64) { - // An optimization where we can just overwrite an entire range of initialization - // bits if they are going to be uniformly `1` or `0`. + // An optimization where we can just overwrite an entire range of initialization bits if + // they are going to be uniformly `1` or `0`. If this happens to be a full-range overwrite, + // we won't need materialized blocks either. if defined.ranges.len() <= 1 { - self.set_range_inbounds( - range.start, - range.start + range.size * repeat, // `Size` operations - defined.initial, - ); + let start = range.start; + let end = range.start + range.size * repeat; // `Size` operations + self.set_range(AllocRange::from(start..end), defined.initial); return; } + // We're about to do one or more partial writes, so we ensure the blocks are materialized. + let blocks = self.materialize_blocks(); + for mut j in 0..repeat { j *= range.size.bytes(); j += range.start.bytes(); @@ -522,7 +689,7 @@ impl InitMask { for range in &defined.ranges { let old_j = j; j += range; - self.set_range_inbounds(Size::from_bytes(old_j), Size::from_bytes(j), cur); + blocks.set_range_inbounds(Size::from_bytes(old_j), Size::from_bytes(j), cur); cur = !cur; } } From a69642015ab1cd5115ffc0cfd481ccc3bb95ec44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 27 Mar 2023 15:55:19 +0000 Subject: [PATCH 185/346] add more InitMask test coverage --- .../src/mir/interpret/allocation/tests.rs | 175 ++++++++++++++++++ 1 file changed, 175 insertions(+) diff --git a/compiler/rustc_middle/src/mir/interpret/allocation/tests.rs b/compiler/rustc_middle/src/mir/interpret/allocation/tests.rs index c9c3c50c537..171ed4d93bb 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation/tests.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation/tests.rs @@ -17,3 +17,178 @@ fn uninit_mask() { assert!(!mask.get(Size::from_bytes(i)), "{i} should not be set"); } } + +/// Returns the number of materialized blocks for this mask. +fn materialized_block_count(mask: &InitMask) -> usize { + match mask.blocks { + InitMaskBlocks::Lazy { .. } => 0, + InitMaskBlocks::Materialized(ref blocks) => blocks.blocks.len(), + } +} + +#[test] +fn materialize_mask_within_range() { + // To have spare bits, we use a mask size smaller than its block size of 64. + let mut mask = InitMask::new(Size::from_bytes(16), false); + assert_eq!(materialized_block_count(&mask), 0); + + // Forces materialization, but doesn't require growth. This is case #1 documented in the + // `set_range` method. + mask.set_range((8..16).into(), true); + assert_eq!(materialized_block_count(&mask), 1); + + for i in 0..8 { + assert!(!mask.get(Size::from_bytes(i)), "{i} should not be set"); + } + for i in 8..16 { + assert!(mask.get(Size::from_bytes(i)), "{i} should be set"); + } +} + +#[test] +fn grow_within_unused_bits_with_full_overwrite() { + // To have spare bits, we use a mask size smaller than its block size of 64. + let mut mask = InitMask::new(Size::from_bytes(16), true); + for i in 0..16 { + assert!(mask.get(Size::from_bytes(i)), "{i} should be set"); + } + + // Grow without requiring an additional block. Full overwrite. + // This can be fully handled without materialization. + let range = (0..32).into(); + mask.set_range(range, true); + + for i in 0..32 { + assert!(mask.get(Size::from_bytes(i)), "{i} should be set"); + } + + assert_eq!(materialized_block_count(&mask), 0); +} + +// This test checks that an initmask's spare capacity is correctly used when growing within block +// capacity. This can be fully handled without materialization. +#[test] +fn grow_same_state_within_unused_bits() { + // To have spare bits, we use a mask size smaller than its block size of 64. + let mut mask = InitMask::new(Size::from_bytes(16), true); + for i in 0..16 { + assert!(mask.get(Size::from_bytes(i)), "{i} should be set"); + } + + // Grow without requiring an additional block. The gap between the current length and the + // range's beginning should be set to the same value as the range. + let range = (24..32).into(); + mask.set_range(range, true); + + // We want to make sure the unused bits in the first block are correct + for i in 16..24 { + assert!(mask.get(Size::from_bytes(i)), "{i} should be set"); + } + + for i in 24..32 { + assert!(mask.get(Size::from_bytes(i)), "{i} should be set"); + } + + assert_eq!(1, mask.range_as_init_chunks((0..32).into()).count()); + assert_eq!(materialized_block_count(&mask), 0); +} + +// This is the same test as `grow_same_state_within_unused_bits` but with both init and uninit +// states: this forces materialization; otherwise the mask could stay lazy even when needing to +// grow. +#[test] +fn grow_mixed_state_within_unused_bits() { + // To have spare bits, we use a mask size smaller than its block size of 64. + let mut mask = InitMask::new(Size::from_bytes(16), true); + for i in 0..16 { + assert!(mask.get(Size::from_bytes(i)), "{i} should be set"); + } + + // Grow without requiring an additional block. The gap between the current length and the + // range's beginning should be set to the same value as the range. Note: since this is fully + // out-of-bounds of the current mask, this is case #3 described in the `set_range` method. + let range = (24..32).into(); + mask.set_range(range, false); + + // We want to make sure the unused bits in the first block are correct + for i in 16..24 { + assert!(!mask.get(Size::from_bytes(i)), "{i} should not be set"); + } + + for i in 24..32 { + assert!(!mask.get(Size::from_bytes(i)), "{i} should not be set"); + } + + assert_eq!(1, mask.range_as_init_chunks((0..16).into()).count()); + assert_eq!(2, mask.range_as_init_chunks((0..32).into()).count()); + assert_eq!(materialized_block_count(&mask), 1); +} + +// This is similar to `grow_mixed_state_within_unused_bits` to force materialization, but the range +// to set partially overlaps the mask, so this requires a different growth + write pattern in the +// mask. +#[test] +fn grow_within_unused_bits_with_overlap() { + // To have spare bits, we use a mask size smaller than its block size of 64. + let mut mask = InitMask::new(Size::from_bytes(16), true); + for i in 0..16 { + assert!(mask.get(Size::from_bytes(i)), "{i} should be set"); + } + + // Grow without requiring an additional block, but leave no gap after the current len. Note: + // since this is partially out-of-bounds of the current mask, this is case #2 described in the + // `set_range` method. + let range = (8..24).into(); + mask.set_range(range, false); + + // We want to make sure the unused bits in the first block are correct + for i in 8..24 { + assert!(!mask.get(Size::from_bytes(i)), "{i} should not be set"); + } + + assert_eq!(1, mask.range_as_init_chunks((0..8).into()).count()); + assert_eq!(2, mask.range_as_init_chunks((0..24).into()).count()); + assert_eq!(materialized_block_count(&mask), 1); +} + +// Force materialization before a full overwrite: the mask can now become lazy. +#[test] +fn grow_mixed_state_within_unused_bits_and_full_overwrite() { + // To have spare bits, we use a mask size smaller than its block size of 64. + let mut mask = InitMask::new(Size::from_bytes(16), true); + let range = (0..16).into(); + assert!(mask.is_range_initialized(range).is_ok()); + + // Force materialization. + let range = (8..24).into(); + mask.set_range(range, false); + assert!(mask.is_range_initialized(range).is_err()); + assert_eq!(materialized_block_count(&mask), 1); + + // Full overwrite, lazy blocks would be enough from now on. + let range = (0..32).into(); + mask.set_range(range, true); + assert!(mask.is_range_initialized(range).is_ok()); + + assert_eq!(1, mask.range_as_init_chunks((0..32).into()).count()); + assert_eq!(materialized_block_count(&mask), 0); +} + +// Check that growth outside the current capacity can still be lazy: if the init state doesn't +// change, we don't need materialized blocks. +#[test] +fn grow_same_state_outside_capacity() { + // To have spare bits, we use a mask size smaller than its block size of 64. + let mut mask = InitMask::new(Size::from_bytes(16), true); + for i in 0..16 { + assert!(mask.get(Size::from_bytes(i)), "{i} should be set"); + } + assert_eq!(materialized_block_count(&mask), 0); + + // Grow to 10 blocks with the same init state. + let range = (24..640).into(); + mask.set_range(range, true); + + assert_eq!(1, mask.range_as_init_chunks((0..640).into()).count()); + assert_eq!(materialized_block_count(&mask), 0); +} From a2be7a1bb44e4a33421c1397d018a97ae7ec63eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 27 Mar 2023 16:02:53 +0000 Subject: [PATCH 186/346] readability tweaks --- .../src/mir/interpret/allocation/init_mask.rs | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs b/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs index 3f7e2523106..312fecea5da 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs @@ -254,44 +254,44 @@ impl InitMaskMaterialized { } fn set_range_inbounds(&mut self, start: Size, end: Size, new_state: bool) { - let (blocka, bita) = Self::bit_index(start); - let (blockb, bitb) = Self::bit_index(end); - if blocka == blockb { - // First set all bits except the first `bita`, - // then unset the last `64 - bitb` bits. - let range = if bitb == 0 { - u64::MAX << bita + let (block_a, bit_a) = Self::bit_index(start); + let (block_b, bit_b) = Self::bit_index(end); + if block_a == block_b { + // First set all bits except the first `bit_a`, + // then unset the last `64 - bit_b` bits. + let range = if bit_b == 0 { + u64::MAX << bit_a } else { - (u64::MAX << bita) & (u64::MAX >> (64 - bitb)) + (u64::MAX << bit_a) & (u64::MAX >> (64 - bit_b)) }; if new_state { - self.blocks[blocka] |= range; + self.blocks[block_a] |= range; } else { - self.blocks[blocka] &= !range; + self.blocks[block_a] &= !range; } return; } // across block boundaries if new_state { - // Set `bita..64` to `1`. - self.blocks[blocka] |= u64::MAX << bita; - // Set `0..bitb` to `1`. - if bitb != 0 { - self.blocks[blockb] |= u64::MAX >> (64 - bitb); + // Set `bit_a..64` to `1`. + self.blocks[block_a] |= u64::MAX << bit_a; + // Set `0..bit_b` to `1`. + if bit_b != 0 { + self.blocks[block_b] |= u64::MAX >> (64 - bit_b); } // Fill in all the other blocks (much faster than one bit at a time). - for block in (blocka + 1)..blockb { + for block in (block_a + 1)..block_b { self.blocks[block] = u64::MAX; } } else { - // Set `bita..64` to `0`. - self.blocks[blocka] &= !(u64::MAX << bita); - // Set `0..bitb` to `0`. - if bitb != 0 { - self.blocks[blockb] &= !(u64::MAX >> (64 - bitb)); + // Set `bit_a..64` to `0`. + self.blocks[block_a] &= !(u64::MAX << bit_a); + // Set `0..bit_b` to `0`. + if bit_b != 0 { + self.blocks[block_b] &= !(u64::MAX >> (64 - bit_b)); } // Fill in all the other blocks (much faster than one bit at a time). - for block in (blocka + 1)..blockb { + for block in (block_a + 1)..block_b { self.blocks[block] = 0; } } From 9fc7eca935a00f06c3e47b29a4bb8e313eb47e7a Mon Sep 17 00:00:00 2001 From: clubby789 Date: Mon, 27 Mar 2023 17:11:58 +0100 Subject: [PATCH 187/346] Always set `RUSTC_BOOTSTRAP` with `x doc` --- src/bootstrap/doc.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 36fdd4abf4f..be43affa404 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -1027,10 +1027,11 @@ impl Step for RustcBook { if self.validate { cmd.arg("--validate"); } - if !builder.unstable_features() { - // We need to validate nightly features, even on the stable channel. - cmd.env("RUSTC_BOOTSTRAP", "1"); - } + // We need to validate nightly features, even on the stable channel. + // Set this unconditionally as the stage0 compiler may be being used to + // document. + cmd.env("RUSTC_BOOTSTRAP", "1"); + // If the lib directories are in an unusual location (changed in // config.toml), then this needs to explicitly update the dylib search // path. From 7cba12c5a9fc3ffc2d90276a53084ee510c3aeaa Mon Sep 17 00:00:00 2001 From: rustbot <47979223+rustbot@users.noreply.github.com> Date: Mon, 27 Mar 2023 13:00:59 -0400 Subject: [PATCH 188/346] Update books --- src/doc/nomicon | 2 +- src/doc/reference | 2 +- src/doc/rust-by-example | 2 +- src/doc/rustc-dev-guide | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/doc/nomicon b/src/doc/nomicon index 1f3e4cd4fd8..b5f7500fc40 160000 --- a/src/doc/nomicon +++ b/src/doc/nomicon @@ -1 +1 @@ -Subproject commit 1f3e4cd4fd88b5b5d45feb86a11b6d2f93e5a974 +Subproject commit b5f7500fc40775096c2bbd204eae096612cf9047 diff --git a/src/doc/reference b/src/doc/reference index 24c87f6663a..3c47807a313 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 24c87f6663aed55b05d2cc286878f28f21918825 +Subproject commit 3c47807a3131b3c7cacb508f52632078d253cd0a diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index af0998b7473..cfbfd648ce3 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit af0998b7473839ca75563ba3d3e7fd0160bef235 +Subproject commit cfbfd648ce33926c3490f24de9a5b56cce404b88 diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide index b1b6d693cd1..d08baa166b4 160000 --- a/src/doc/rustc-dev-guide +++ b/src/doc/rustc-dev-guide @@ -1 +1 @@ -Subproject commit b1b6d693cd1461e53de4132c1b183ace31cd36e5 +Subproject commit d08baa166b463537229eeb737c4ccadabd83cf78 From 9f16a81bc86e4b3c851abd58a4852e6dad7eb17e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Mon, 27 Mar 2023 17:44:33 +0000 Subject: [PATCH 189/346] update codegen test expectations Changing the layout of the InitMask changed the const allocations' hashes. --- tests/codegen/consts.rs | 2 +- tests/codegen/remap_path_prefix/main.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/codegen/consts.rs b/tests/codegen/consts.rs index dd22fd0f7e8..8a135039c06 100644 --- a/tests/codegen/consts.rs +++ b/tests/codegen/consts.rs @@ -9,7 +9,7 @@ // CHECK: @STATIC = {{.*}}, align 4 // This checks the constants from inline_enum_const -// CHECK: @alloc_76bfe2f13a3e3b01074971d122eac57e = {{.*}}, align 2 +// CHECK: @alloc_701ed935fbda2002838d0a2cbbc171e5 = {{.*}}, align 2 // This checks the constants from {low,high}_align_const, they share the same // constant, but the alignment differs, so the higher one should be used diff --git a/tests/codegen/remap_path_prefix/main.rs b/tests/codegen/remap_path_prefix/main.rs index 6c0cd6997d0..85523d053b5 100644 --- a/tests/codegen/remap_path_prefix/main.rs +++ b/tests/codegen/remap_path_prefix/main.rs @@ -12,7 +12,7 @@ mod aux_mod; include!("aux_mod.rs"); // Here we check that the expansion of the file!() macro is mapped. -// CHECK: @alloc_92a59126a55aa3c0019b6c8a007fe001 = private unnamed_addr constant <{ [34 x i8] }> <{ [34 x i8] c"/the/src/remap_path_prefix/main.rs" }> +// CHECK: @alloc_af9d0c7bc6ca3c31bb051d2862714536 = private unnamed_addr constant <{ [34 x i8] }> <{ [34 x i8] c"/the/src/remap_path_prefix/main.rs" }> pub static FILE_PATH: &'static str = file!(); fn main() { From 3c4fabc341c1fa854104b95a8daf8465a3c50a7a Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 24 Mar 2023 13:14:10 +0000 Subject: [PATCH 190/346] Improve documentation for E0223 --- .../src/error_codes/E0223.md | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_error_codes/src/error_codes/E0223.md b/compiler/rustc_error_codes/src/error_codes/E0223.md index 0d49f514ccf..ba5f0052821 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0223.md +++ b/compiler/rustc_error_codes/src/error_codes/E0223.md @@ -3,31 +3,33 @@ An attempt was made to retrieve an associated type, but the type was ambiguous. Erroneous code example: ```compile_fail,E0223 -trait MyTrait {type X; } +trait Trait { type X; } fn main() { - let foo: MyTrait::X; + let foo: Trait::X; } ``` -The problem here is that we're attempting to take the type of X from MyTrait. -Unfortunately, the type of X is not defined, because it's only made concrete in -implementations of the trait. A working version of this code might look like: +The problem here is that we're attempting to take the associated type of `X` +from `Trait`. Unfortunately, the type of `X` is not defined, because it's only +made concrete in implementations of the trait. A working version of this code +might look like: ``` -trait MyTrait {type X; } -struct MyStruct; +trait Trait { type X; } -impl MyTrait for MyStruct { +struct Struct; +impl Trait for Struct { type X = u32; } fn main() { - let foo: ::X; + let foo: ::X; } ``` -This syntax specifies that we want the X type from MyTrait, as made concrete in -MyStruct. The reason that we cannot simply use `MyStruct::X` is that MyStruct -might implement two different traits with identically-named associated types. -This syntax allows disambiguation between the two. +This syntax specifies that we want the associated type `X` from `Struct`'s +implementation of `Trait`. + +Due to internal limitations of the current compiler implementation we cannot +simply use `Struct::X`. From 436afdf1feab1a928538e8360ab6bfd3e1fef2ab Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Tue, 21 Mar 2023 11:44:50 +0000 Subject: [PATCH 191/346] Don't skip all directories when tidy-checking --- .../replace-version-placeholder/src/main.rs | 2 +- src/tools/tidy/src/alphabetical.rs | 2 +- src/tools/tidy/src/bins.rs | 58 ++++++++++--------- src/tools/tidy/src/debug_artifacts.rs | 22 +++++-- src/tools/tidy/src/edition.rs | 2 +- src/tools/tidy/src/error_codes.rs | 4 +- src/tools/tidy/src/features.rs | 4 +- src/tools/tidy/src/mir_opt_tests.rs | 2 +- src/tools/tidy/src/pal.rs | 2 +- src/tools/tidy/src/rustdoc_gui_tests.rs | 5 +- src/tools/tidy/src/style.rs | 11 +++- src/tools/tidy/src/target_specific_tests.rs | 2 +- src/tools/tidy/src/ui_tests.rs | 2 +- src/tools/tidy/src/unit_tests.rs | 4 +- src/tools/tidy/src/walk.rs | 10 ++-- 15 files changed, 76 insertions(+), 56 deletions(-) diff --git a/src/tools/replace-version-placeholder/src/main.rs b/src/tools/replace-version-placeholder/src/main.rs index 864e68de55d..0aebfc4aad2 100644 --- a/src/tools/replace-version-placeholder/src/main.rs +++ b/src/tools/replace-version-placeholder/src/main.rs @@ -10,7 +10,7 @@ fn main() { let version_str = version_str.trim(); walk::walk( &root_path, - |path| { + |path, _is_dir| { walk::filter_dirs(path) // We exempt these as they require the placeholder // for their operation diff --git a/src/tools/tidy/src/alphabetical.rs b/src/tools/tidy/src/alphabetical.rs index 9bfee1efc0b..fdc411c8925 100644 --- a/src/tools/tidy/src/alphabetical.rs +++ b/src/tools/tidy/src/alphabetical.rs @@ -95,7 +95,7 @@ fn check_section<'a>( } pub fn check(path: &Path, bad: &mut bool) { - walk(path, filter_dirs, &mut |entry, contents| { + walk(path, |path, _is_dir| filter_dirs(path), &mut |entry, contents| { let file = &entry.path().display(); let mut lines = contents.lines().enumerate().peekable(); diff --git a/src/tools/tidy/src/bins.rs b/src/tools/tidy/src/bins.rs index 070ce93f97c..7e5b4d810ba 100644 --- a/src/tools/tidy/src/bins.rs +++ b/src/tools/tidy/src/bins.rs @@ -103,36 +103,40 @@ mod os_impl { // FIXME: we don't need to look at all binaries, only files that have been modified in this branch // (e.g. using `git ls-files`). - walk_no_read(&[path], |path| filter_dirs(path) || path.ends_with("src/etc"), &mut |entry| { - let file = entry.path(); - let extension = file.extension(); - let scripts = ["py", "sh", "ps1"]; - if scripts.into_iter().any(|e| extension == Some(OsStr::new(e))) { - return; - } - - if t!(is_executable(&file), file) { - let rel_path = file.strip_prefix(path).unwrap(); - let git_friendly_path = rel_path.to_str().unwrap().replace("\\", "/"); - - if ALLOWED.contains(&git_friendly_path.as_str()) { + walk_no_read( + &[path], + |path, _is_dir| filter_dirs(path) || path.ends_with("src/etc"), + &mut |entry| { + let file = entry.path(); + let extension = file.extension(); + let scripts = ["py", "sh", "ps1"]; + if scripts.into_iter().any(|e| extension == Some(OsStr::new(e))) { return; } - let output = Command::new("git") - .arg("ls-files") - .arg(&git_friendly_path) - .current_dir(path) - .stderr(Stdio::null()) - .output() - .unwrap_or_else(|e| { - panic!("could not run git ls-files: {e}"); - }); - let path_bytes = rel_path.as_os_str().as_bytes(); - if output.status.success() && output.stdout.starts_with(path_bytes) { - tidy_error!(bad, "binary checked into source: {}", file.display()); + if t!(is_executable(&file), file) { + let rel_path = file.strip_prefix(path).unwrap(); + let git_friendly_path = rel_path.to_str().unwrap().replace("\\", "/"); + + if ALLOWED.contains(&git_friendly_path.as_str()) { + return; + } + + let output = Command::new("git") + .arg("ls-files") + .arg(&git_friendly_path) + .current_dir(path) + .stderr(Stdio::null()) + .output() + .unwrap_or_else(|e| { + panic!("could not run git ls-files: {e}"); + }); + let path_bytes = rel_path.as_os_str().as_bytes(); + if output.status.success() && output.stdout.starts_with(path_bytes) { + tidy_error!(bad, "binary checked into source: {}", file.display()); + } } - } - }) + }, + ) } } diff --git a/src/tools/tidy/src/debug_artifacts.rs b/src/tools/tidy/src/debug_artifacts.rs index 84b13306805..582014d5059 100644 --- a/src/tools/tidy/src/debug_artifacts.rs +++ b/src/tools/tidy/src/debug_artifacts.rs @@ -6,11 +6,21 @@ use std::path::Path; const GRAPHVIZ_POSTFLOW_MSG: &str = "`borrowck_graphviz_postflow` attribute in test"; pub fn check(test_dir: &Path, bad: &mut bool) { - walk(test_dir, |path| filter_dirs(path) || filter_not_rust(path), &mut |entry, contents| { - for (i, line) in contents.lines().enumerate() { - if line.contains("borrowck_graphviz_postflow") { - tidy_error!(bad, "{}:{}: {}", entry.path().display(), i + 1, GRAPHVIZ_POSTFLOW_MSG); + walk( + test_dir, + |path, _is_dir| filter_dirs(path) || filter_not_rust(path), + &mut |entry, contents| { + for (i, line) in contents.lines().enumerate() { + if line.contains("borrowck_graphviz_postflow") { + tidy_error!( + bad, + "{}:{}: {}", + entry.path().display(), + i + 1, + GRAPHVIZ_POSTFLOW_MSG + ); + } } - } - }); + }, + ); } diff --git a/src/tools/tidy/src/edition.rs b/src/tools/tidy/src/edition.rs index 67d9c30a04f..f28f677e0ff 100644 --- a/src/tools/tidy/src/edition.rs +++ b/src/tools/tidy/src/edition.rs @@ -9,7 +9,7 @@ fn is_edition_2021(mut line: &str) -> bool { } pub fn check(path: &Path, bad: &mut bool) { - walk(path, |path| filter_dirs(path), &mut |entry, contents| { + walk(path, |path, _is_dir| filter_dirs(path), &mut |entry, contents| { let file = entry.path(); let filename = file.file_name().unwrap(); if filename != "Cargo.toml" { diff --git a/src/tools/tidy/src/error_codes.rs b/src/tools/tidy/src/error_codes.rs index a8375050614..417ace58c32 100644 --- a/src/tools/tidy/src/error_codes.rs +++ b/src/tools/tidy/src/error_codes.rs @@ -129,7 +129,7 @@ fn check_error_codes_docs( let mut no_longer_emitted_codes = Vec::new(); - walk(&docs_path, |_| false, &mut |entry, contents| { + walk(&docs_path, |_, _| false, &mut |entry, contents| { let path = entry.path(); // Error if the file isn't markdown. @@ -321,7 +321,7 @@ fn check_error_codes_used( let mut found_codes = Vec::new(); - walk_many(search_paths, filter_dirs, &mut |entry, contents| { + walk_many(search_paths, |path, _is_dir| filter_dirs(path), &mut |entry, contents| { let path = entry.path(); // Return early if we aren't looking at a source file. diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index f18feda533c..2fd4c797b43 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -102,7 +102,7 @@ pub fn check( &tests_path.join("rustdoc-ui"), &tests_path.join("rustdoc"), ], - |path| { + |path, _is_dir| { filter_dirs(path) || filter_not_rust(path) || path.file_name() == Some(OsStr::new("features.rs")) @@ -478,7 +478,7 @@ fn map_lib_features( ) { walk( base_src_path, - |path| filter_dirs(path) || path.ends_with("tests"), + |path, _is_dir| filter_dirs(path) || path.ends_with("tests"), &mut |entry, contents| { let file = entry.path(); let filename = file.file_name().unwrap().to_string_lossy(); diff --git a/src/tools/tidy/src/mir_opt_tests.rs b/src/tools/tidy/src/mir_opt_tests.rs index b316e9e9009..2f6918510e8 100644 --- a/src/tools/tidy/src/mir_opt_tests.rs +++ b/src/tools/tidy/src/mir_opt_tests.rs @@ -11,7 +11,7 @@ fn check_unused_files(path: &Path, bless: bool, bad: &mut bool) { walk_no_read( &[&path.join("mir-opt")], - |path| path.file_name() == Some("README.md".as_ref()), + |path, _is_dir| path.file_name() == Some("README.md".as_ref()), &mut |file| { let filepath = file.path(); if filepath.extension() == Some("rs".as_ref()) { diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs index 6b7b27fd526..d40c4ad0711 100644 --- a/src/tools/tidy/src/pal.rs +++ b/src/tools/tidy/src/pal.rs @@ -67,7 +67,7 @@ pub fn check(path: &Path, bad: &mut bool) { // Sanity check that the complex parsing here works. let mut saw_target_arch = false; let mut saw_cfg_bang = false; - walk(path, filter_dirs, &mut |entry, contents| { + walk(path, |path, _is_dir| filter_dirs(path), &mut |entry, contents| { let file = entry.path(); let filestr = file.to_string_lossy().replace("\\", "/"); if !filestr.ends_with(".rs") { diff --git a/src/tools/tidy/src/rustdoc_gui_tests.rs b/src/tools/tidy/src/rustdoc_gui_tests.rs index d7db5c02297..91776bc989e 100644 --- a/src/tools/tidy/src/rustdoc_gui_tests.rs +++ b/src/tools/tidy/src/rustdoc_gui_tests.rs @@ -5,10 +5,7 @@ use std::path::Path; pub fn check(path: &Path, bad: &mut bool) { crate::walk::walk( &path.join("rustdoc-gui"), - |p| { - // If there is no extension, it's very likely a folder and we want to go into it. - p.extension().map(|e| e != "goml").unwrap_or(false) - }, + |p, is_dir| !is_dir && p.extension().map_or(true, |e| e != "goml"), &mut |entry, content| { for line in content.lines() { if !line.starts_with("// ") { diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index a965c98f484..a2012db903a 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -227,7 +227,7 @@ fn is_unexplained_ignore(extension: &str, line: &str) -> bool { } pub fn check(path: &Path, bad: &mut bool) { - fn skip(path: &Path) -> bool { + fn skip(path: &Path, is_dir: bool) -> bool { if path.file_name().map_or(false, |name| name.to_string_lossy().starts_with(".#")) { // vim or emacs temporary file return true; @@ -237,8 +237,15 @@ pub fn check(path: &Path, bad: &mut bool) { return true; } + // Don't check extensions for directories + if is_dir { + return false; + } + let extensions = ["rs", "py", "js", "sh", "c", "cpp", "h", "md", "css", "ftl", "goml"]; - if extensions.iter().all(|e| path.extension() != Some(OsStr::new(e))) { + + // NB: don't skip paths without extensions (or else we'll skip all directories and will only check top level files) + if path.extension().map_or(true, |ext| !extensions.iter().any(|e| ext == OsStr::new(e))) { return true; } diff --git a/src/tools/tidy/src/target_specific_tests.rs b/src/tools/tidy/src/target_specific_tests.rs index e0fa6aceb85..de022be2894 100644 --- a/src/tools/tidy/src/target_specific_tests.rs +++ b/src/tools/tidy/src/target_specific_tests.rs @@ -37,7 +37,7 @@ struct RevisionInfo<'a> { } pub fn check(path: &Path, bad: &mut bool) { - crate::walk::walk(path, filter_not_rust, &mut |entry, content| { + crate::walk::walk(path, |path, _is_dir| filter_not_rust(path), &mut |entry, content| { let file = entry.path().display(); let mut header_map = BTreeMap::new(); iter_header(content, &mut |cfg, directive| { diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 66f5c932be2..20b8a2c3b24 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -51,7 +51,7 @@ pub fn check(path: &Path, bad: &mut bool) { check_entries(&path, bad); let (ui, ui_fulldeps) = (path.join("ui"), path.join("ui-fulldeps")); let paths = [ui.as_path(), ui_fulldeps.as_path()]; - crate::walk::walk_no_read(&paths, |_| false, &mut |entry| { + crate::walk::walk_no_read(&paths, |_, _| false, &mut |entry| { let file_path = entry.path(); if let Some(ext) = file_path.extension() { if ext == "stderr" || ext == "stdout" { diff --git a/src/tools/tidy/src/unit_tests.rs b/src/tools/tidy/src/unit_tests.rs index 3da200a8a93..0a5dad88789 100644 --- a/src/tools/tidy/src/unit_tests.rs +++ b/src/tools/tidy/src/unit_tests.rs @@ -20,9 +20,9 @@ pub fn check(root_path: &Path, bad: &mut bool) { && !(path.starts_with(&core_tests) || path.starts_with(&core_benches)) }; - let skip = move |path: &Path| { + let skip = move |path: &Path, is_dir| { let file_name = path.file_name().unwrap_or_default(); - if path.is_dir() { + if is_dir { filter_dirs(path) || path.ends_with("src/doc") || (file_name == "tests" || file_name == "benches") && !is_core(path) diff --git a/src/tools/tidy/src/walk.rs b/src/tools/tidy/src/walk.rs index 67a4df19fcc..95a35801d7d 100644 --- a/src/tools/tidy/src/walk.rs +++ b/src/tools/tidy/src/walk.rs @@ -41,7 +41,7 @@ pub fn filter_not_rust(path: &Path) -> bool { pub fn walk( path: &Path, - skip: impl Clone + Send + Sync + 'static + Fn(&Path) -> bool, + skip: impl Clone + Send + Sync + 'static + Fn(&Path, bool) -> bool, f: &mut dyn FnMut(&DirEntry, &str), ) { walk_many(&[path], skip, f); @@ -49,7 +49,7 @@ pub fn walk( pub fn walk_many( paths: &[&Path], - skip: impl Clone + Send + Sync + 'static + Fn(&Path) -> bool, + skip: impl Clone + Send + Sync + 'static + Fn(&Path, bool) -> bool, f: &mut dyn FnMut(&DirEntry, &str), ) { let mut contents = Vec::new(); @@ -67,14 +67,16 @@ pub fn walk_many( pub(crate) fn walk_no_read( paths: &[&Path], - skip: impl Send + Sync + 'static + Fn(&Path) -> bool, + skip: impl Send + Sync + 'static + Fn(&Path, bool) -> bool, f: &mut dyn FnMut(&DirEntry), ) { let mut walker = ignore::WalkBuilder::new(paths[0]); for path in &paths[1..] { walker.add(path); } - let walker = walker.filter_entry(move |e| !skip(e.path())); + let walker = walker.filter_entry(move |e| { + !skip(e.path(), e.file_type().map(|ft| ft.is_dir()).unwrap_or(false)) + }); for entry in walker.build() { if let Ok(entry) = entry { if entry.file_type().map_or(true, |kind| kind.is_dir() || kind.is_symlink()) { From 8af42f695d493ed868098e3d1c02318f631998e4 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Tue, 21 Mar 2023 12:01:47 +0000 Subject: [PATCH 192/346] Remove useless Clone bounds --- src/tools/tidy/src/walk.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/tidy/src/walk.rs b/src/tools/tidy/src/walk.rs index 95a35801d7d..3539943ebef 100644 --- a/src/tools/tidy/src/walk.rs +++ b/src/tools/tidy/src/walk.rs @@ -41,7 +41,7 @@ pub fn filter_not_rust(path: &Path) -> bool { pub fn walk( path: &Path, - skip: impl Clone + Send + Sync + 'static + Fn(&Path, bool) -> bool, + skip: impl Send + Sync + 'static + Fn(&Path, bool) -> bool, f: &mut dyn FnMut(&DirEntry, &str), ) { walk_many(&[path], skip, f); @@ -49,7 +49,7 @@ pub fn walk( pub fn walk_many( paths: &[&Path], - skip: impl Clone + Send + Sync + 'static + Fn(&Path, bool) -> bool, + skip: impl Send + Sync + 'static + Fn(&Path, bool) -> bool, f: &mut dyn FnMut(&DirEntry, &str), ) { let mut contents = Vec::new(); From 904dd2c3987028f0270db306b9964bc465689de8 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Thu, 23 Mar 2023 11:12:03 +0000 Subject: [PATCH 193/346] Bless tidy --- compiler/rustc_attr/src/builtin.rs | 4 ++-- compiler/rustc_codegen_ssa/src/back/linker.rs | 2 +- compiler/rustc_error_codes/src/error_codes/E0080.md | 3 ++- compiler/rustc_error_codes/src/error_codes/E0794.md | 6 +++--- compiler/rustc_mir_build/src/build/expr/as_rvalue.rs | 2 +- src/doc/unstable-book/src/compiler-flags/sanitizer.md | 2 +- tests/rustdoc/issue-108925.rs | 1 - .../generic_const_exprs/typeid-equality-by-subtyping.rs | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index a29e389953e..cb217be6654 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -227,7 +227,7 @@ impl UnstableReason { } /// Collects stability info from `stable`/`unstable`/`rustc_allowed_through_unstable_modules` -/// attributes in `attrs`. Returns `None` if no stability attributes are found. +/// attributes in `attrs`. Returns `None` if no stability attributes are found. pub fn find_stability( sess: &Session, attrs: &[Attribute], @@ -281,7 +281,7 @@ pub fn find_stability( } /// Collects stability info from `rustc_const_stable`/`rustc_const_unstable`/`rustc_promotable` -/// attributes in `attrs`. Returns `None` if no stability attributes are found. +/// attributes in `attrs`. Returns `None` if no stability attributes are found. pub fn find_const_stability( sess: &Session, attrs: &[Attribute], diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index dd117681950..69bb00f804d 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -1621,7 +1621,7 @@ impl<'a> Linker for AixLinker<'a> { let path = tmpdir.join("list.exp"); let res: io::Result<()> = try { let mut f = BufWriter::new(File::create(&path)?); - // TODO: use llvm-nm to generate export list. + // FIXME: use llvm-nm to generate export list. for symbol in symbols { debug!(" _{}", symbol); writeln!(f, " {}", symbol)?; diff --git a/compiler/rustc_error_codes/src/error_codes/E0080.md b/compiler/rustc_error_codes/src/error_codes/E0080.md index 71d6c6fe2ef..c05324a5a2c 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0080.md +++ b/compiler/rustc_error_codes/src/error_codes/E0080.md @@ -16,7 +16,8 @@ or causing an integer overflow are two ways to induce this error. Ensure that the expressions given can be evaluated as the desired integer type. See the [Discriminants] section of the Reference for more information about -setting custom integer types on enums using the [`repr` attribute][repr-attribute]. +setting custom integer types on enums using the +[`repr` attribute][repr-attribute]. [discriminants]: https://doc.rust-lang.org/reference/items/enumerations.html#discriminants [repr-attribute]: https://doc.rust-lang.org/reference/type-layout.html#representations diff --git a/compiler/rustc_error_codes/src/error_codes/E0794.md b/compiler/rustc_error_codes/src/error_codes/E0794.md index 4377a292473..c8f73de95a2 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0794.md +++ b/compiler/rustc_error_codes/src/error_codes/E0794.md @@ -59,6 +59,6 @@ In the definition of `bar`, the lifetime parameter `'a` is late-bound, while where `'a` is universally quantified and `'b` is substituted by a specific lifetime. It is not allowed to explicitly specify early-bound lifetime arguments when late-bound lifetime parameters are present (as for `bar_fn2`, -see [issue #42868](https://github.com/rust-lang/rust/issues/42868)), although the -types that are constrained by early-bound parameters can be specified (as for -`bar_fn3`). +see [issue #42868](https://github.com/rust-lang/rust/issues/42868)), although +the types that are constrained by early-bound parameters can be specified (as +for `bar_fn3`). diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index 3b775f590a4..7fff801b169 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -568,7 +568,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { BinOp::Shl | BinOp::Shr if self.check_overflow && ty.is_integral() => { // For an unsigned RHS, the shift is in-range for `rhs < bits`. // For a signed RHS, `IntToInt` cast to the equivalent unsigned - // type and do that same comparison. Because the type is the + // type and do that same comparison. Because the type is the // same size, there's no negative shift amount that ends up // overlapping with valid ones, thus it catches negatives too. let (lhs_size, _) = ty.int_size_and_signed(self.tcx); diff --git a/src/doc/unstable-book/src/compiler-flags/sanitizer.md b/src/doc/unstable-book/src/compiler-flags/sanitizer.md index f71aceff455..b55348b7889 100644 --- a/src/doc/unstable-book/src/compiler-flags/sanitizer.md +++ b/src/doc/unstable-book/src/compiler-flags/sanitizer.md @@ -213,7 +213,7 @@ See the [Clang ControlFlowIntegrity documentation][clang-cfi] for more details. ## Example -```rust,ignore +```rust,ignore (making doc tests pass cross-platform is hard) #![feature(naked_functions)] use std::arch::asm; diff --git a/tests/rustdoc/issue-108925.rs b/tests/rustdoc/issue-108925.rs index 88aeb3c7f75..9c36d0d71c4 100644 --- a/tests/rustdoc/issue-108925.rs +++ b/tests/rustdoc/issue-108925.rs @@ -8,4 +8,3 @@ pub enum MyThing { #[doc(hidden)] NotShown, } - diff --git a/tests/ui/const-generics/generic_const_exprs/typeid-equality-by-subtyping.rs b/tests/ui/const-generics/generic_const_exprs/typeid-equality-by-subtyping.rs index 64317b9d39a..85345d65c4a 100644 --- a/tests/ui/const-generics/generic_const_exprs/typeid-equality-by-subtyping.rs +++ b/tests/ui/const-generics/generic_const_exprs/typeid-equality-by-subtyping.rs @@ -17,7 +17,7 @@ const fn to_usize() -> usize { match TypeId::of::() { WHAT_A_TYPE => 0, _ => 1000, - } + } } impl AssocCt for T { const ASSOC: usize = to_usize::(); From f738b44c6d0b7401fb12baa335e09c7392e15ebb Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 27 Mar 2023 20:47:15 +0000 Subject: [PATCH 194/346] no shadow plz --- compiler/rustc_query_system/src/query/plumbing.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs index 0326869826b..519ea5ffed1 100644 --- a/compiler/rustc_query_system/src/query/plumbing.rs +++ b/compiler/rustc_query_system/src/query/plumbing.rs @@ -703,8 +703,7 @@ fn incremental_verify_ich_failed( }; let dep_node = tcx.dep_graph().data().unwrap().prev_node_of(prev_index); - - let dep_node = tcx.sess().emit_err(crate::error::IncrementCompilation { + tcx.sess().emit_err(crate::error::IncrementCompilation { run_cmd, dep_node: format!("{dep_node:?}"), }); From f995003ec5053c85efca895d0506392d3be88286 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Mon, 27 Mar 2023 22:23:10 +0100 Subject: [PATCH 195/346] Fix subslice capture in closure --- compiler/rustc_hir_typeck/src/upvar.rs | 5 ++-- .../2229_closure_analysis/array_subslice.rs | 13 ++++++++++ .../array_subslice.stderr | 26 +++++++++++++++++++ 3 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 tests/ui/closures/2229_closure_analysis/array_subslice.rs create mode 100644 tests/ui/closures/2229_closure_analysis/array_subslice.stderr diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 8fe5a3cc789..61c4535365a 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -1893,14 +1893,13 @@ fn restrict_capture_precision( for (i, proj) in place.projections.iter().enumerate() { match proj.kind { - ProjectionKind::Index => { - // Arrays are completely captured, so we drop Index projections + ProjectionKind::Index | ProjectionKind::Subslice => { + // Arrays are completely captured, so we drop Index and Subslice projections truncate_place_to_len_and_update_capture_kind(&mut place, &mut curr_mode, i); return (place, curr_mode); } ProjectionKind::Deref => {} ProjectionKind::Field(..) => {} // ignore - ProjectionKind::Subslice => {} // We never capture this } } diff --git a/tests/ui/closures/2229_closure_analysis/array_subslice.rs b/tests/ui/closures/2229_closure_analysis/array_subslice.rs new file mode 100644 index 00000000000..5f244ea8936 --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/array_subslice.rs @@ -0,0 +1,13 @@ +// regression test for #109298 +// edition: 2021 + +pub fn subslice_array(x: [u8; 3]) { + let f = || { + let [_x @ ..] = x; + let [ref y, ref mut z @ ..] = x; //~ ERROR cannot borrow `x[..]` as mutable + }; + + f(); //~ ERROR cannot borrow `f` as mutable +} + +fn main() {} diff --git a/tests/ui/closures/2229_closure_analysis/array_subslice.stderr b/tests/ui/closures/2229_closure_analysis/array_subslice.stderr new file mode 100644 index 00000000000..888c60d5e91 --- /dev/null +++ b/tests/ui/closures/2229_closure_analysis/array_subslice.stderr @@ -0,0 +1,26 @@ +error[E0596]: cannot borrow `x[..]` as mutable, as `x` is not declared as mutable + --> $DIR/array_subslice.rs:7:21 + | +LL | pub fn subslice_array(x: [u8; 3]) { + | - help: consider changing this to be mutable: `mut x` +... +LL | let [ref y, ref mut z @ ..] = x; + | ^^^^^^^^^ cannot borrow as mutable + +error[E0596]: cannot borrow `f` as mutable, as it is not declared as mutable + --> $DIR/array_subslice.rs:10:5 + | +LL | let [ref y, ref mut z @ ..] = x; + | - calling `f` requires mutable binding due to mutable borrow of `x` +... +LL | f(); + | ^ cannot borrow as mutable + | +help: consider changing this to be mutable + | +LL | let mut f = || { + | +++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0596`. From 901f10899c32db30f36afe9908284737ad5775e9 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Mon, 27 Mar 2023 23:56:28 +0100 Subject: [PATCH 196/346] Add `#[inline]` to CStr trait implementations --- library/core/src/ffi/c_str.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs index fe8abdf7fad..4a5306ccaa7 100644 --- a/library/core/src/ffi/c_str.rs +++ b/library/core/src/ffi/c_str.rs @@ -172,6 +172,7 @@ impl fmt::Debug for CStr { #[stable(feature = "cstr_default", since = "1.10.0")] impl Default for &CStr { + #[inline] fn default() -> Self { const SLICE: &[c_char] = &[0]; // SAFETY: `SLICE` is indeed pointing to a valid nul-terminated string. @@ -623,6 +624,7 @@ impl CStr { #[stable(feature = "rust1", since = "1.0.0")] impl PartialEq for CStr { + #[inline] fn eq(&self, other: &CStr) -> bool { self.to_bytes().eq(other.to_bytes()) } @@ -631,12 +633,14 @@ impl PartialEq for CStr { impl Eq for CStr {} #[stable(feature = "rust1", since = "1.0.0")] impl PartialOrd for CStr { + #[inline] fn partial_cmp(&self, other: &CStr) -> Option { self.to_bytes().partial_cmp(&other.to_bytes()) } } #[stable(feature = "rust1", since = "1.0.0")] impl Ord for CStr { + #[inline] fn cmp(&self, other: &CStr) -> Ordering { self.to_bytes().cmp(&other.to_bytes()) } @@ -646,6 +650,7 @@ impl Ord for CStr { impl ops::Index> for CStr { type Output = CStr; + #[inline] fn index(&self, index: ops::RangeFrom) -> &CStr { let bytes = self.to_bytes_with_nul(); // we need to manually check the starting index to account for the null From 7bbc8ef02235d1cca7017fb33ed872d3f604bd07 Mon Sep 17 00:00:00 2001 From: est31 Date: Tue, 28 Mar 2023 02:19:46 +0200 Subject: [PATCH 197/346] Make doc comment a little bit more accurate It queries not LLVM in particular but the codegen backend *in general*. While cranelift does not provide target features, other codegen backends do. --- compiler/rustc_interface/src/util.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 043892410ce..6fb50aa3904 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -34,7 +34,7 @@ pub type MakeBackendFn = fn() -> Box; /// specific features (SSE, NEON etc.). /// /// This is performed by checking whether a set of permitted features -/// is available on the target machine, by querying LLVM. +/// is available on the target machine, by querying the codegen backend. pub fn add_configuration( cfg: &mut CrateConfig, sess: &mut Session, From ff88787ff0238ed5b5d70317e93b95b32bbde4c9 Mon Sep 17 00:00:00 2001 From: James Dietz Date: Tue, 14 Mar 2023 18:01:14 -0400 Subject: [PATCH 198/346] check for write macro and write_fmt with err msg added ui test blessed stderrs fixed typo reblessed --- .../rustc_hir_typeck/src/method/suggest.rs | 52 ++++++++++++---- tests/ui/macros/missing-writer.rs | 17 ++++++ tests/ui/macros/missing-writer.stderr | 59 +++++++++++++++++++ .../mut-borrow-needed-by-trait.stderr | 10 +++- 4 files changed, 125 insertions(+), 13 deletions(-) create mode 100644 tests/ui/macros/missing-writer.rs create mode 100644 tests/ui/macros/missing-writer.stderr diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 55f684599e7..95d1a7df698 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -245,6 +245,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { None } + fn suggest_missing_writer( + &self, + rcvr_ty: Ty<'tcx>, + args: (&'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>]), + ) -> DiagnosticBuilder<'_, ErrorGuaranteed> { + let (ty_str, _ty_file) = self.tcx.short_ty_string(rcvr_ty); + let mut err = + struct_span_err!(self.tcx.sess, args.0.span, E0599, "cannot write into `{}`", ty_str); + err.span_note( + args.0.span, + "must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method", + ); + if let ExprKind::Lit(_) = args.0.kind { + err.span_help( + args.0.span.shrink_to_lo(), + "a writer is needed before this format string", + ); + }; + + err + } + pub fn report_no_match_method_error( &self, mut span: Span, @@ -323,16 +345,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - let mut err = struct_span_err!( - tcx.sess, - span, - E0599, - "no {} named `{}` found for {} `{}` in the current scope", - item_kind, - item_name, - rcvr_ty.prefix_string(self.tcx), - ty_str_reported, - ); + let is_write = sugg_span.ctxt().outer_expn_data().macro_def_id.map_or(false, |def_id| { + tcx.is_diagnostic_item(sym::write_macro, def_id) + || tcx.is_diagnostic_item(sym::writeln_macro, def_id) + }) && item_name.name == Symbol::intern("write_fmt"); + let mut err = if is_write + && let Some(args) = args + { + self.suggest_missing_writer(rcvr_ty, args) + } else { + struct_span_err!( + tcx.sess, + span, + E0599, + "no {} named `{}` found for {} `{}` in the current scope", + item_kind, + item_name, + rcvr_ty.prefix_string(self.tcx), + ty_str_reported, + ) + }; if tcx.sess.source_map().is_multiline(sugg_span) { err.span_label(sugg_span.with_hi(span.lo()), ""); } diff --git a/tests/ui/macros/missing-writer.rs b/tests/ui/macros/missing-writer.rs new file mode 100644 index 00000000000..7df965c3684 --- /dev/null +++ b/tests/ui/macros/missing-writer.rs @@ -0,0 +1,17 @@ +// Check error for missing writer in writeln! and write! macro +fn main() { + let x = 1; + let y = 2; + write!("{}_{}", x, y); + //~^ ERROR format argument must be a string literal + //~| HELP you might be missing a string literal to format with + //~| ERROR cannot write into `&'static str` + //~| NOTE must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method + //~| HELP a writer is needed before this format string + writeln!("{}_{}", x, y); + //~^ ERROR format argument must be a string literal + //~| HELP you might be missing a string literal to format with + //~| ERROR cannot write into `&'static str` + //~| NOTE must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method + //~| HELP a writer is needed before this format string +} diff --git a/tests/ui/macros/missing-writer.stderr b/tests/ui/macros/missing-writer.stderr new file mode 100644 index 00000000000..86dfe7d65ea --- /dev/null +++ b/tests/ui/macros/missing-writer.stderr @@ -0,0 +1,59 @@ +error: format argument must be a string literal + --> $DIR/missing-writer.rs:5:21 + | +LL | write!("{}_{}", x, y); + | ^ + | +help: you might be missing a string literal to format with + | +LL | write!("{}_{}", "{} {}", x, y); + | ++++++++ + +error: format argument must be a string literal + --> $DIR/missing-writer.rs:11:23 + | +LL | writeln!("{}_{}", x, y); + | ^ + | +help: you might be missing a string literal to format with + | +LL | writeln!("{}_{}", "{} {}", x, y); + | ++++++++ + +error[E0599]: cannot write into `&'static str` + --> $DIR/missing-writer.rs:5:12 + | +LL | write!("{}_{}", x, y); + | -------^^^^^^^------- method not found in `&str` + | +note: must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method + --> $DIR/missing-writer.rs:5:12 + | +LL | write!("{}_{}", x, y); + | ^^^^^^^ +help: a writer is needed before this format string + --> $DIR/missing-writer.rs:5:12 + | +LL | write!("{}_{}", x, y); + | ^ + +error[E0599]: cannot write into `&'static str` + --> $DIR/missing-writer.rs:11:14 + | +LL | writeln!("{}_{}", x, y); + | ---------^^^^^^^------- method not found in `&str` + | +note: must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method + --> $DIR/missing-writer.rs:11:14 + | +LL | writeln!("{}_{}", x, y); + | ^^^^^^^ +help: a writer is needed before this format string + --> $DIR/missing-writer.rs:11:14 + | +LL | writeln!("{}_{}", x, y); + | ^ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0599`. diff --git a/tests/ui/suggestions/mut-borrow-needed-by-trait.stderr b/tests/ui/suggestions/mut-borrow-needed-by-trait.stderr index 6910b77d9bc..94710f4503f 100644 --- a/tests/ui/suggestions/mut-borrow-needed-by-trait.stderr +++ b/tests/ui/suggestions/mut-borrow-needed-by-trait.stderr @@ -21,18 +21,22 @@ note: required by a bound in `BufWriter` --> $SRC_DIR/std/src/io/buffered/bufwriter.rs:LL:COL error[E0599]: the method `write_fmt` exists for struct `BufWriter<&dyn Write>`, but its trait bounds were not satisfied - --> $DIR/mut-borrow-needed-by-trait.rs:21:5 + --> $DIR/mut-borrow-needed-by-trait.rs:21:14 | LL | writeln!(fp, "hello world").unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ method cannot be called on `BufWriter<&dyn Write>` due to unsatisfied trait bounds + | ---------^^---------------- method cannot be called on `BufWriter<&dyn Write>` due to unsatisfied trait bounds --> $SRC_DIR/std/src/io/buffered/bufwriter.rs:LL:COL | = note: doesn't satisfy `BufWriter<&dyn std::io::Write>: std::io::Write` | +note: must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method + --> $DIR/mut-borrow-needed-by-trait.rs:21:14 + | +LL | writeln!(fp, "hello world").unwrap(); + | ^^ = note: the following trait bounds were not satisfied: `&dyn std::io::Write: std::io::Write` which is required by `BufWriter<&dyn std::io::Write>: std::io::Write` - = note: this error originates in the macro `writeln` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 3 previous errors From f50c1e1f0587d4a7e44946a909484f75a0a4c929 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 3 Mar 2023 23:25:54 +0000 Subject: [PATCH 199/346] ParenthesizedGenericArgs::{Ok -> ParenSugar} --- compiler/rustc_ast_lowering/src/lib.rs | 2 +- compiler/rustc_ast_lowering/src/path.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 0b6b02ba00f..878763dca14 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -482,7 +482,7 @@ enum ParamMode { } enum ParenthesizedGenericArgs { - Ok, + ParenSugar, Err, } diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 592fc5aa645..6ab23206f54 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -51,7 +51,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let parenthesized_generic_args = match base_res { // `a::b::Trait(Args)` Res::Def(DefKind::Trait, _) if i + 1 == proj_start => { - ParenthesizedGenericArgs::Ok + ParenthesizedGenericArgs::ParenSugar } // `a::b::Trait(Args)::TraitItem` Res::Def(DefKind::AssocFn, _) @@ -59,10 +59,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { | Res::Def(DefKind::AssocTy, _) if i + 2 == proj_start => { - ParenthesizedGenericArgs::Ok + ParenthesizedGenericArgs::ParenSugar } // Avoid duplicated errors. - Res::Err => ParenthesizedGenericArgs::Ok, + Res::Err => ParenthesizedGenericArgs::ParenSugar, // An error _ => ParenthesizedGenericArgs::Err, }; @@ -180,7 +180,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.lower_angle_bracketed_parameter_data(data, param_mode, itctx) } GenericArgs::Parenthesized(data) => match parenthesized_generic_args { - ParenthesizedGenericArgs::Ok => { + ParenthesizedGenericArgs::ParenSugar => { self.lower_parenthesized_parameter_data(data, itctx) } ParenthesizedGenericArgs::Err => { From fb9ca9223d42a13bc15bddd1c2dce506db2fcb21 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 4 Mar 2023 02:23:36 +0000 Subject: [PATCH 200/346] Feature gate --- compiler/rustc_ast/src/ast.rs | 4 +++ compiler/rustc_ast_passes/src/feature_gate.rs | 21 +++++++---- compiler/rustc_feature/src/active.rs | 2 ++ compiler/rustc_span/src/symbol.rs | 1 + .../feature-gate-return_type_notation.rs | 15 ++++++++ .../feature-gate-return_type_notation.stderr | 36 +++++++++++++++++++ 6 files changed, 73 insertions(+), 6 deletions(-) create mode 100644 tests/ui/feature-gates/feature-gate-return_type_notation.rs create mode 100644 tests/ui/feature-gates/feature-gate-return_type_notation.stderr diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index ab8b7f632e8..710c7ad3b2e 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -174,6 +174,10 @@ impl GenericArgs { matches!(self, AngleBracketed(..)) } + pub fn is_parenthesized(&self) -> bool { + matches!(self, Parenthesized(..)) + } + pub fn span(&self) -> Span { match self { AngleBracketed(data) => data.span, diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 344a1e7f5e7..1413db64a48 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -482,12 +482,21 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { fn visit_assoc_constraint(&mut self, constraint: &'a AssocConstraint) { if let AssocConstraintKind::Bound { .. } = constraint.kind { - gate_feature_post!( - &self, - associated_type_bounds, - constraint.span, - "associated type bounds are unstable" - ) + if constraint.gen_args.as_ref().map_or(false, |args| args.is_parenthesized()) { + gate_feature_post!( + &self, + return_type_notation, + constraint.span, + "return type notation is unstable" + ) + } else { + gate_feature_post!( + &self, + associated_type_bounds, + constraint.span, + "associated type bounds are unstable" + ) + } } visit::walk_assoc_constraint(self, constraint) } diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index b7d280b8751..9c0dc938635 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -495,6 +495,8 @@ declare_features! ( (active, repr_simd, "1.4.0", Some(27731), None), /// Allows return-position `impl Trait` in traits. (incomplete, return_position_impl_trait_in_trait, "1.65.0", Some(91611), None), + /// Allows bounding the return type of AFIT/RPITIT. + (incomplete, return_type_notation, "CURRENT_RUSTC_VERSION", Some(109417), None), /// Allows `extern "rust-cold"`. (active, rust_cold_cc, "1.63.0", Some(97544), None), /// Allows the use of SIMD types in functions declared in `extern` blocks. diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 4a1abdf6318..153988d9e12 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1193,6 +1193,7 @@ symbols! { residual, result, return_position_impl_trait_in_trait, + return_type_notation, rhs, rintf32, rintf64, diff --git a/tests/ui/feature-gates/feature-gate-return_type_notation.rs b/tests/ui/feature-gates/feature-gate-return_type_notation.rs new file mode 100644 index 00000000000..fea953dcdd0 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-return_type_notation.rs @@ -0,0 +1,15 @@ +// edition: 2021 + +#![feature(async_fn_in_trait)] +//~^ WARN the feature `async_fn_in_trait` is incomplete + +trait Trait { + async fn m(); +} + +fn foo>() {} +//~^ ERROR parenthesized generic arguments cannot be used in associated type constraints +//~| ERROR associated type `m` not found for `Trait` +//~| ERROR return type notation is unstable + +fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-return_type_notation.stderr b/tests/ui/feature-gates/feature-gate-return_type_notation.stderr new file mode 100644 index 00000000000..a9373482e5a --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-return_type_notation.stderr @@ -0,0 +1,36 @@ +error[E0658]: return type notation is unstable + --> $DIR/feature-gate-return_type_notation.rs:10:17 + | +LL | fn foo>() {} + | ^^^^^^^^^ + | + = note: see issue #109417 for more information + = help: add `#![feature(return_type_notation)]` to the crate attributes to enable + +warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/feature-gate-return_type_notation.rs:3:12 + | +LL | #![feature(async_fn_in_trait)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #91611 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: parenthesized generic arguments cannot be used in associated type constraints + --> $DIR/feature-gate-return_type_notation.rs:10:17 + | +LL | fn foo>() {} + | ^-- + | | + | help: remove these parentheses + +error[E0220]: associated type `m` not found for `Trait` + --> $DIR/feature-gate-return_type_notation.rs:10:17 + | +LL | fn foo>() {} + | ^ associated type `m` not found + +error: aborting due to 3 previous errors; 1 warning emitted + +Some errors have detailed explanations: E0220, E0658. +For more information about an error, try `rustc --explain E0220`. From 773e8a5ad1fa012bc1574c6733a700e094a48e3d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 5 Mar 2023 01:08:17 +0000 Subject: [PATCH 201/346] RTN --- compiler/rustc_ast_lowering/src/lib.rs | 12 ++ .../rustc_hir_analysis/src/astconv/mod.rs | 153 ++++++++++++------ compiler/rustc_parse/src/parser/path.rs | 6 +- 3 files changed, 120 insertions(+), 51 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 878763dca14..97b87b985d0 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -987,8 +987,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { GenericArgs::AngleBracketed(data) => { self.lower_angle_bracketed_parameter_data(data, ParamMode::Explicit, itctx).0 } + GenericArgs::Parenthesized(data) + if self.tcx.features().return_type_notation => + { + // TODO: Check the parens + no return type + GenericArgsCtor { + args: Default::default(), + bindings: &[], + parenthesized: true, + span: data.span, + } + } GenericArgs::Parenthesized(data) => { self.emit_bad_parenthesized_trait_in_assoc_ty(data); + // TODO: Add a RTN feature error if the parens are shaped correctly self.lower_angle_bracketed_parameter_data( &data.as_angle_bracketed_args(), ParamMode::Explicit, diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 4ab6bb5908b..0565bc6dffe 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -854,16 +854,15 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ) } - fn trait_defines_associated_type_named(&self, trait_def_id: DefId, assoc_name: Ident) -> bool { + fn trait_defines_associated_item_named( + &self, + trait_def_id: DefId, + assoc_kind: ty::AssocKind, + assoc_name: Ident, + ) -> bool { self.tcx() .associated_items(trait_def_id) - .find_by_name_and_kind(self.tcx(), assoc_name, ty::AssocKind::Type, trait_def_id) - .is_some() - } - fn trait_defines_associated_const_named(&self, trait_def_id: DefId, assoc_name: Ident) -> bool { - self.tcx() - .associated_items(trait_def_id) - .find_by_name_and_kind(self.tcx(), assoc_name, ty::AssocKind::Const, trait_def_id) + .find_by_name_and_kind(self.tcx(), assoc_name, assoc_kind, trait_def_id) .is_some() } @@ -1087,24 +1086,42 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let tcx = self.tcx(); - let candidate = - if self.trait_defines_associated_type_named(trait_ref.def_id(), binding.item_name) { - // Simple case: X is defined in the current trait. + // TODO: rtn comment goes here + let associated_return_type_bound = + binding.gen_args.parenthesized && self.tcx().features().associated_return_type_bounds; + + let candidate = if return_type_notation { + if self.trait_defines_associated_item_named( + trait_ref.def_id(), + ty::AssocKind::Fn, + binding.item_name, + ) { trait_ref } else { - // Otherwise, we have to walk through the supertraits to find - // those that do. - self.one_bound_for_assoc_type( - || traits::supertraits(tcx, trait_ref), - trait_ref.print_only_trait_path(), - binding.item_name, - path_span, - match binding.kind { - ConvertedBindingKind::Equality(term) => Some(term), - _ => None, - }, - )? - }; + // TODO: error + todo!() + } + } else if self.trait_defines_associated_item_named( + trait_ref.def_id(), + ty::AssocKind::Type, + binding.item_name, + ) { + // Simple case: X is defined in the current trait. + trait_ref + } else { + // Otherwise, we have to walk through the supertraits to find + // those that do. + self.one_bound_for_assoc_type( + || traits::supertraits(tcx, trait_ref), + trait_ref.print_only_trait_path(), + binding.item_name, + path_span, + match binding.kind { + ConvertedBindingKind::Equality(term) => Some(term), + _ => None, + }, + )? + }; let (assoc_ident, def_scope) = tcx.adjust_ident_and_get_scope(binding.item_name, candidate.def_id(), hir_ref_id); @@ -1116,9 +1133,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .filter_by_name_unhygienic(assoc_ident.name) .find(|i| i.kind == kind && i.ident(tcx).normalize_to_macros_2_0() == assoc_ident) }; - let assoc_item = find_item_of_kind(ty::AssocKind::Type) - .or_else(|| find_item_of_kind(ty::AssocKind::Const)) - .expect("missing associated type"); + let assoc_item = if return_type_notation { + find_item_of_kind(ty::AssocKind::Fn) + } else { + find_item_of_kind(ty::AssocKind::Type) + .or_else(|| find_item_of_kind(ty::AssocKind::Const)) + } + .expect("missing associated type"); if !assoc_item.visibility(tcx).is_accessible_from(def_scope, tcx) { tcx.sess @@ -1145,28 +1166,54 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .or_insert(binding.span); } - // Include substitutions for generic parameters of associated types - let projection_ty = candidate.map_bound(|trait_ref| { - let ident = Ident::new(assoc_item.name, binding.item_name.span); - let item_segment = hir::PathSegment { - ident, - hir_id: binding.hir_id, - res: Res::Err, - args: Some(binding.gen_args), - infer_args: false, + let projection_ty = if associated_return_type_bound { + let generics = self.tcx().generics_of(assoc_item.def_id); + if !generics.params.is_empty() { + todo!(); + } + let output = self.tcx().fn_sig(assoc_item.def_id).skip_binder().output(); + let fn_bound_vars = output.bound_vars(); + + let output = if let ty::Alias(ty::Projection, alias_ty) = *output.skip_binder().kind() + && tcx.def_kind(alias_ty.def_id) == DefKind::ImplTraitPlaceholder + { + alias_ty + } else { + todo!("found return type of {output:?}"); }; - let substs_trait_ref_and_assoc_item = self.create_substs_for_associated_item( - path_span, - assoc_item.def_id, - &item_segment, - trait_ref.substs, - ); + let trait_bound_vars = candidate.bound_vars(); + let shifted_output = tcx.shift_bound_var_indices(trait_bound_vars.len(), output); + let subst_output = + ty::EarlyBinder(shifted_output).subst(tcx, candidate.skip_binder().substs); + let bound_vars = + tcx.mk_bound_variable_kinds_from_iter(trait_bound_vars.iter().chain(fn_bound_vars)); - debug!(?substs_trait_ref_and_assoc_item); + ty::Binder::bind_with_vars(subst_output, bound_vars) + } else { + // Include substitutions for generic parameters of associated types + candidate.map_bound(|trait_ref| { + let ident = Ident::new(assoc_item.name, binding.item_name.span); + let item_segment = hir::PathSegment { + ident, + hir_id: binding.hir_id, + res: Res::Err, + args: Some(binding.gen_args), + infer_args: false, + }; - self.tcx().mk_alias_ty(assoc_item.def_id, substs_trait_ref_and_assoc_item) - }); + let substs_trait_ref_and_assoc_item = self.create_substs_for_associated_item( + path_span, + assoc_item.def_id, + &item_segment, + trait_ref.substs, + ); + + debug!(?substs_trait_ref_and_assoc_item); + + self.tcx().mk_alias_ty(assoc_item.def_id, substs_trait_ref_and_assoc_item) + }) + }; if !speculative { // Find any late-bound regions declared in `ty` that are not @@ -1206,6 +1253,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } match binding.kind { + ConvertedBindingKind::Equality(..) if associated_return_type_bound => { + // TODO: error + todo!() + } ConvertedBindingKind::Equality(mut term) => { // "Desugar" a constraint like `T: Iterator` this to // the "projection predicate" for: @@ -1267,7 +1318,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // Calling `skip_binder` is okay, because `add_bounds` expects the `param_ty` // parameter to have a skipped binder. let param_ty = tcx.mk_alias(ty::Projection, projection_ty.skip_binder()); - self.add_bounds(param_ty, ast_bounds.iter(), bounds, candidate.bound_vars()); + self.add_bounds(param_ty, ast_bounds.iter(), bounds, projection_ty.bound_vars()); } } Ok(()) @@ -1808,10 +1859,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { where I: Iterator>, { - let mut matching_candidates = all_candidates() - .filter(|r| self.trait_defines_associated_type_named(r.def_id(), assoc_name)); - let mut const_candidates = all_candidates() - .filter(|r| self.trait_defines_associated_const_named(r.def_id(), assoc_name)); + let mut matching_candidates = all_candidates().filter(|r| { + self.trait_defines_associated_item_named(r.def_id(), ty::AssocKind::Type, assoc_name) + }); + let mut const_candidates = all_candidates().filter(|r| { + self.trait_defines_associated_item_named(r.def_id(), ty::AssocKind::Const, assoc_name) + }); let (bound, next_cand) = match (matching_candidates.next(), const_candidates.next()) { (Some(bound), _) => (bound, matching_candidates.next()), diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index b50d2984a4e..72f230e628d 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -550,7 +550,11 @@ impl<'a> Parser<'a> { // Gate associated type bounds, e.g., `Iterator`. if let AssocConstraintKind::Bound { .. } = kind { - self.sess.gated_spans.gate(sym::associated_type_bounds, span); + if gen_args.as_ref().map_or(false, |args| args.is_parenthesized()) { + self.sess.gated_spans.gate(sym::return_type_notation, span); + } else { + self.sess.gated_spans.gate(sym::associated_type_bounds, span); + } } let constraint = AssocConstraint { id: ast::DUMMY_NODE_ID, ident, gen_args, kind, span }; From 0308d4ad187e7715d2bb7efcfce58e6d93362f07 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 10 Mar 2023 21:41:11 +0000 Subject: [PATCH 202/346] Compute bound vars correctly --- .../rustc_hir_analysis/src/astconv/mod.rs | 71 ++++++++++++++----- .../src/collect/resolve_bound_vars.rs | 54 +++++++++++++- 2 files changed, 108 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 0565bc6dffe..83343930010 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -1088,7 +1088,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // TODO: rtn comment goes here let associated_return_type_bound = - binding.gen_args.parenthesized && self.tcx().features().associated_return_type_bounds; + binding.gen_args.parenthesized && tcx.features().associated_return_type_bounds; let candidate = if return_type_notation { if self.trait_defines_associated_item_named( @@ -1156,7 +1156,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { dup_bindings .entry(assoc_item.def_id) .and_modify(|prev_span| { - self.tcx().sess.emit_err(ValueOfAssociatedStructAlreadySpecified { + tcx.sess.emit_err(ValueOfAssociatedStructAlreadySpecified { span: binding.span, prev_span: *prev_span, item_name: binding.item_name, @@ -1166,14 +1166,53 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .or_insert(binding.span); } - let projection_ty = if associated_return_type_bound { - let generics = self.tcx().generics_of(assoc_item.def_id); - if !generics.params.is_empty() { - todo!(); - } - let output = self.tcx().fn_sig(assoc_item.def_id).skip_binder().output(); - let fn_bound_vars = output.bound_vars(); + let projection_ty = if return_type_notation { + // If we have an method return type bound, then we need to substitute + // the method's early bound params with suitable late-bound params. + let mut num_bound_vars = candidate.bound_vars().len(); + let substs = + candidate.skip_binder().substs.extend_to(tcx, assoc_item.def_id, |param, _| { + let subst = match param.kind { + GenericParamDefKind::Lifetime => tcx + .mk_re_late_bound( + ty::INNERMOST, + ty::BoundRegion { + var: ty::BoundVar::from_usize(num_bound_vars), + kind: ty::BoundRegionKind::BrNamed(param.def_id, param.name), + }, + ) + .into(), + GenericParamDefKind::Type { .. } => tcx + .mk_bound( + ty::INNERMOST, + ty::BoundTy { + var: ty::BoundVar::from_usize(num_bound_vars), + kind: ty::BoundTyKind::Param(param.def_id, param.name), + }, + ) + .into(), + GenericParamDefKind::Const { .. } => { + let ty = tcx + .type_of(param.def_id) + .no_bound_vars() + .expect("ct params cannot have early bound vars"); + tcx.mk_const( + ty::ConstKind::Bound( + ty::INNERMOST, + ty::BoundVar::from_usize(num_bound_vars), + ), + ty, + ) + .into() + } + }; + num_bound_vars += 1; + subst + }); + // Next, we need to check that the return-type notation is being used on + // an RPITIT (return-position impl trait in trait) or AFIT (async fn in trait). + let output = tcx.fn_sig(assoc_item.def_id).skip_binder().output(); let output = if let ty::Alias(ty::Projection, alias_ty) = *output.skip_binder().kind() && tcx.def_kind(alias_ty.def_id) == DefKind::ImplTraitPlaceholder { @@ -1182,13 +1221,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { todo!("found return type of {output:?}"); }; - let trait_bound_vars = candidate.bound_vars(); - let shifted_output = tcx.shift_bound_var_indices(trait_bound_vars.len(), output); - let subst_output = - ty::EarlyBinder(shifted_output).subst(tcx, candidate.skip_binder().substs); - let bound_vars = - tcx.mk_bound_variable_kinds_from_iter(trait_bound_vars.iter().chain(fn_bound_vars)); + // Finally, move the fn return type's bound vars over to account for the early bound + // params (and trait ref's late bound params). This logic is very similar to + // `Predicate::subst_supertrait`, and it's no coincidence why. + let shifted_output = tcx.shift_bound_var_indices(num_bound_vars, output); + let subst_output = ty::EarlyBinder(shifted_output).subst(tcx, substs); + let bound_vars = tcx.late_bound_vars(binding.hir_id); ty::Binder::bind_with_vars(subst_output, bound_vars) } else { // Include substitutions for generic parameters of associated types @@ -1211,7 +1250,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { debug!(?substs_trait_ref_and_assoc_item); - self.tcx().mk_alias_ty(assoc_item.def_id, substs_trait_ref_and_assoc_item) + tcx.mk_alias_ty(assoc_item.def_id, substs_trait_ref_and_assoc_item) }) }; diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index f1769415797..1a4a1636071 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -1640,7 +1640,59 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { }, s: self.scope, }; - if let Some(type_def_id) = type_def_id { + // If the binding is parenthesized, then this must be `feature(return_type_notation)`. + // In that case, introduce a binder over all of the function's early and late bound vars. + // + // For example, given + // ``` + // trait Foo { + // async fn x<'r, T>(); + // } + // ``` + // and a bound that looks like: + // `for<'a> T::Trait<'a, x(): for<'b> Other<'b>>` + // this is going to expand to something like: + // `for<'a> for<'r, T> >::x::<'r, T>::{opaque#0}: for<'b> Other<'b>`. + if binding.gen_args.parenthesized { + let bound_vars = if let Some(type_def_id) = type_def_id + && self.tcx.def_kind(type_def_id) == DefKind::Trait + // FIXME(return_type_notation): We could bound supertrait methods. + && let Some(assoc_fn) = self + .tcx + .associated_items(type_def_id) + .find_by_name_and_kind(self.tcx, binding.ident, ty::AssocKind::Fn, type_def_id) + { + self.tcx + .generics_of(assoc_fn.def_id) + .params + .iter() + .map(|param| match param.kind { + ty::GenericParamDefKind::Lifetime => ty::BoundVariableKind::Region( + ty::BoundRegionKind::BrNamed(param.def_id, param.name), + ), + ty::GenericParamDefKind::Type { .. } => ty::BoundVariableKind::Ty( + ty::BoundTyKind::Param(param.def_id, param.name), + ), + ty::GenericParamDefKind::Const { .. } => ty::BoundVariableKind::Const, + }) + .chain(self.tcx.fn_sig(assoc_fn.def_id).subst_identity().bound_vars()) + .collect() + } else { + self.tcx.sess.delay_span_bug( + binding.ident.span, + "bad return type notation here", + ); + vec![] + }; + self.with(scope, |this| { + let scope = Scope::Supertrait { bound_vars, s: this.scope }; + this.with(scope, |this| { + let (bound_vars, _) = this.poly_trait_ref_binder_info(); + this.record_late_bound_vars(binding.hir_id, bound_vars); + this.visit_assoc_type_binding(binding) + }); + }); + } else if let Some(type_def_id) = type_def_id { let bound_vars = BoundVarContext::supertrait_hrtb_vars(self.tcx, type_def_id, binding.ident); self.with(scope, |this| { From 104aacb49fb37265fb923e3b779de3c388abd92c Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 11 Mar 2023 04:10:09 +0000 Subject: [PATCH 203/346] Add tests and error messages --- compiler/rustc_ast_lowering/messages.ftl | 8 ++++ compiler/rustc_ast_lowering/src/errors.rs | 16 ++++++++ compiler/rustc_ast_lowering/src/lib.rs | 17 ++++++--- compiler/rustc_hir_analysis/messages.ftl | 11 ++++++ .../rustc_hir_analysis/src/astconv/mod.rs | 28 +++++++++----- compiler/rustc_hir_analysis/src/errors.rs | 28 ++++++++++++++ .../bad-inputs-and-output.rs | 17 +++++++++ .../bad-inputs-and-output.stderr | 31 ++++++++++++++++ .../return-type-notation/basic.rs | 28 ++++++++++++++ .../return-type-notation/basic.with.stderr | 19 ++++++++++ .../return-type-notation/basic.without.stderr | 37 +++++++++++++++++++ .../return-type-notation/equality.rs | 16 ++++++++ .../return-type-notation/equality.stderr | 25 +++++++++++++ .../return-type-notation/missing.rs | 14 +++++++ .../return-type-notation/missing.stderr | 25 +++++++++++++ .../return-type-notation/non-rpitit.rs | 11 ++++++ .../return-type-notation/non-rpitit.stderr | 22 +++++++++++ 17 files changed, 339 insertions(+), 14 deletions(-) create mode 100644 tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs create mode 100644 tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr create mode 100644 tests/ui/associated-type-bounds/return-type-notation/basic.rs create mode 100644 tests/ui/associated-type-bounds/return-type-notation/basic.with.stderr create mode 100644 tests/ui/associated-type-bounds/return-type-notation/basic.without.stderr create mode 100644 tests/ui/associated-type-bounds/return-type-notation/equality.rs create mode 100644 tests/ui/associated-type-bounds/return-type-notation/equality.stderr create mode 100644 tests/ui/associated-type-bounds/return-type-notation/missing.rs create mode 100644 tests/ui/associated-type-bounds/return-type-notation/missing.stderr create mode 100644 tests/ui/associated-type-bounds/return-type-notation/non-rpitit.rs create mode 100644 tests/ui/associated-type-bounds/return-type-notation/non-rpitit.stderr diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl index 3ccd84398ec..dac61ec975e 100644 --- a/compiler/rustc_ast_lowering/messages.ftl +++ b/compiler/rustc_ast_lowering/messages.ftl @@ -139,3 +139,11 @@ ast_lowering_trait_fn_async = .label = `async` because of this .note = `async` trait functions are not currently supported .note2 = consider using the `async-trait` crate: https://crates.io/crates/async-trait + +ast_lowering_bad_return_type_notation_inputs = + argument types not allowed with return type notation + .suggestion = remove the input types + +ast_lowering_bad_return_type_notation_output = + return type not allowed with return type notation + .suggestion = remove the return type diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index 5e6b6050bc0..4eefd951b24 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -347,3 +347,19 @@ pub struct TraitFnAsync { #[label] pub span: Span, } + +#[derive(Diagnostic)] +pub enum BadReturnTypeNotation { + #[diag(ast_lowering_bad_return_type_notation_inputs)] + Inputs { + #[primary_span] + #[suggestion(code = "()", applicability = "maybe-incorrect")] + span: Span, + }, + #[diag(ast_lowering_bad_return_type_notation_output)] + Output { + #[primary_span] + #[suggestion(code = "", applicability = "maybe-incorrect")] + span: Span, + }, +} diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 97b87b985d0..aa4ff2882b2 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -987,10 +987,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { GenericArgs::AngleBracketed(data) => { self.lower_angle_bracketed_parameter_data(data, ParamMode::Explicit, itctx).0 } - GenericArgs::Parenthesized(data) - if self.tcx.features().return_type_notation => - { - // TODO: Check the parens + no return type + GenericArgs::Parenthesized(data) if self.tcx.features().return_type_notation => { + if !data.inputs.is_empty() { + self.tcx.sess.emit_err(errors::BadReturnTypeNotation::Inputs { + span: data.inputs_span, + }); + } else if let FnRetTy::Ty(ty) = &data.output { + self.tcx.sess.emit_err(errors::BadReturnTypeNotation::Output { + span: data.inputs_span.shrink_to_hi().to(ty.span), + }); + } GenericArgsCtor { args: Default::default(), bindings: &[], @@ -1000,7 +1006,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { } GenericArgs::Parenthesized(data) => { self.emit_bad_parenthesized_trait_in_assoc_ty(data); - // TODO: Add a RTN feature error if the parens are shaped correctly + // FIXME(return_type_notation): we could issue a feature error + // if the parens are empty and there's no return type. self.lower_angle_bracketed_parameter_data( &data.as_angle_bracketed_args(), ParamMode::Explicit, diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl index 0105cbf36de..a57f3987849 100644 --- a/compiler/rustc_hir_analysis/messages.ftl +++ b/compiler/rustc_hir_analysis/messages.ftl @@ -178,3 +178,14 @@ hir_analysis_invalid_union_field = hir_analysis_invalid_union_field_sugg = wrap the field type in `ManuallyDrop<...>` + +hir_analysis_return_type_notation_on_non_rpitit = + return type notation used on function that is not `async` and does not return `impl Trait` + .note = function returns `{$ty}`, which is not compatible with associated type return bounds + .label = this function must be `async` or return `impl Trait` + +hir_analysis_return_type_notation_equality_bound = + return type notation is not allowed to use type equality + +hir_analysis_return_type_notation_missing_method = + cannot find associated function `{$assoc_name}` in trait `{$trait_name}` diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 83343930010..1e590d93c8c 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -1086,9 +1086,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let tcx = self.tcx(); - // TODO: rtn comment goes here - let associated_return_type_bound = - binding.gen_args.parenthesized && tcx.features().associated_return_type_bounds; + let return_type_notation = + binding.gen_args.parenthesized && tcx.features().return_type_notation; let candidate = if return_type_notation { if self.trait_defines_associated_item_named( @@ -1098,8 +1097,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ) { trait_ref } else { - // TODO: error - todo!() + return Err(tcx.sess.emit_err(crate::errors::ReturnTypeNotationMissingMethod { + span: binding.span, + trait_name: tcx.item_name(trait_ref.def_id()), + assoc_name: binding.item_name.name, + })); } } else if self.trait_defines_associated_item_named( trait_ref.def_id(), @@ -1218,7 +1220,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { { alias_ty } else { - todo!("found return type of {output:?}"); + return Err(self.tcx().sess.emit_err( + crate::errors::ReturnTypeNotationOnNonRpitit { + span: binding.span, + ty: tcx.liberate_late_bound_regions(assoc_item.def_id, output), + fn_span: tcx.hir().span_if_local(assoc_item.def_id), + note: (), + }, + )); }; // Finally, move the fn return type's bound vars over to account for the early bound @@ -1292,9 +1301,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } match binding.kind { - ConvertedBindingKind::Equality(..) if associated_return_type_bound => { - // TODO: error - todo!() + ConvertedBindingKind::Equality(..) if return_type_notation => { + return Err(self.tcx().sess.emit_err( + crate::errors::ReturnTypeNotationEqualityBound { span: binding.span }, + )); } ConvertedBindingKind::Equality(mut term) => { // "Desugar" a constraint like `T: Iterator` this to diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs index f57197edeb7..c71ce9a0bc7 100644 --- a/compiler/rustc_hir_analysis/src/errors.rs +++ b/compiler/rustc_hir_analysis/src/errors.rs @@ -471,6 +471,18 @@ pub(crate) struct InvalidUnionField { pub note: (), } +#[derive(Diagnostic)] +#[diag(hir_analysis_return_type_notation_on_non_rpitit)] +pub(crate) struct ReturnTypeNotationOnNonRpitit<'tcx> { + #[primary_span] + pub span: Span, + pub ty: Ty<'tcx>, + #[label] + pub fn_span: Option, + #[note] + pub note: (), +} + #[derive(Subdiagnostic)] #[multipart_suggestion(hir_analysis_invalid_union_field_sugg, applicability = "machine-applicable")] pub(crate) struct InvalidUnionFieldSuggestion { @@ -479,3 +491,19 @@ pub(crate) struct InvalidUnionFieldSuggestion { #[suggestion_part(code = ">")] pub hi: Span, } + +#[derive(Diagnostic)] +#[diag(hir_analysis_return_type_notation_equality_bound)] +pub(crate) struct ReturnTypeNotationEqualityBound { + #[primary_span] + pub span: Span, +} + +#[derive(Diagnostic)] +#[diag(hir_analysis_return_type_notation_missing_method)] +pub(crate) struct ReturnTypeNotationMissingMethod { + #[primary_span] + pub span: Span, + pub trait_name: Symbol, + pub assoc_name: Symbol, +} diff --git a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs new file mode 100644 index 00000000000..68e991de51f --- /dev/null +++ b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs @@ -0,0 +1,17 @@ +// edition: 2021 + +#![feature(return_type_notation, async_fn_in_trait)] +//~^ WARN the feature `return_type_notation` is incomplete +//~| WARN the feature `async_fn_in_trait` is incomplete + +trait Trait { + async fn method() {} +} + +fn foo>() {} +//~^ ERROR argument types not allowed with return type notation + +fn bar (): Send>>() {} +//~^ ERROR return type not allowed with return type notation + +fn main() {} diff --git a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr new file mode 100644 index 00000000000..03d97743271 --- /dev/null +++ b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr @@ -0,0 +1,31 @@ +warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/bad-inputs-and-output.rs:3:12 + | +LL | #![feature(return_type_notation, async_fn_in_trait)] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #109417 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/bad-inputs-and-output.rs:3:34 + | +LL | #![feature(return_type_notation, async_fn_in_trait)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #91611 for more information + +error: argument types not allowed with return type notation + --> $DIR/bad-inputs-and-output.rs:11:23 + | +LL | fn foo>() {} + | ^^^^^ help: remove the input types: `()` + +error: return type not allowed with return type notation + --> $DIR/bad-inputs-and-output.rs:14:25 + | +LL | fn bar (): Send>>() {} + | ^^^^^^ help: remove the return type + +error: aborting due to 2 previous errors; 2 warnings emitted + diff --git a/tests/ui/associated-type-bounds/return-type-notation/basic.rs b/tests/ui/associated-type-bounds/return-type-notation/basic.rs new file mode 100644 index 00000000000..0b7530b65d7 --- /dev/null +++ b/tests/ui/associated-type-bounds/return-type-notation/basic.rs @@ -0,0 +1,28 @@ +// revisions: with without +// edition: 2021 +//[with] check-pass + +#![feature(return_type_notation, async_fn_in_trait)] +//~^ WARN the feature `return_type_notation` is incomplete +//~| WARN the feature `async_fn_in_trait` is incomplete + +trait Foo { + async fn method() -> Result<(), ()>; +} + +async fn foo() -> Result<(), ()> { + T::method().await?; + Ok(()) +} + +fn is_send(_: impl Send) {} + +fn test< + #[cfg(with)] T: Foo, + #[cfg(without)] T: Foo, +>() { + is_send(foo::()); + //[without]~^ ERROR future cannot be sent between threads safely +} + +fn main() {} diff --git a/tests/ui/associated-type-bounds/return-type-notation/basic.with.stderr b/tests/ui/associated-type-bounds/return-type-notation/basic.with.stderr new file mode 100644 index 00000000000..722c774cb33 --- /dev/null +++ b/tests/ui/associated-type-bounds/return-type-notation/basic.with.stderr @@ -0,0 +1,19 @@ +warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/basic.rs:5:12 + | +LL | #![feature(return_type_notation, async_fn_in_trait)] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #109417 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/basic.rs:5:34 + | +LL | #![feature(return_type_notation, async_fn_in_trait)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #91611 for more information + +warning: 2 warnings emitted + diff --git a/tests/ui/associated-type-bounds/return-type-notation/basic.without.stderr b/tests/ui/associated-type-bounds/return-type-notation/basic.without.stderr new file mode 100644 index 00000000000..1645d8c2650 --- /dev/null +++ b/tests/ui/associated-type-bounds/return-type-notation/basic.without.stderr @@ -0,0 +1,37 @@ +warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/basic.rs:5:12 + | +LL | #![feature(return_type_notation, async_fn_in_trait)] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #109417 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/basic.rs:5:34 + | +LL | #![feature(return_type_notation, async_fn_in_trait)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #91611 for more information + +error: future cannot be sent between threads safely + --> $DIR/basic.rs:24:13 + | +LL | is_send(foo::()); + | ^^^^^^^^^^ future returned by `foo` is not `Send` + | + = help: within `impl Future>`, the trait `Send` is not implemented for `impl Future>` +note: future is not `Send` as it awaits another future which is not `Send` + --> $DIR/basic.rs:14:5 + | +LL | T::method().await?; + | ^^^^^^^^^^^ await occurs here on type `impl Future>`, which is not `Send` +note: required by a bound in `is_send` + --> $DIR/basic.rs:18:20 + | +LL | fn is_send(_: impl Send) {} + | ^^^^ required by this bound in `is_send` + +error: aborting due to previous error; 2 warnings emitted + diff --git a/tests/ui/associated-type-bounds/return-type-notation/equality.rs b/tests/ui/associated-type-bounds/return-type-notation/equality.rs new file mode 100644 index 00000000000..75f757e9025 --- /dev/null +++ b/tests/ui/associated-type-bounds/return-type-notation/equality.rs @@ -0,0 +1,16 @@ +// edition: 2021 + +#![feature(return_type_notation, async_fn_in_trait)] +//~^ WARN the feature `return_type_notation` is incomplete +//~| WARN the feature `async_fn_in_trait` is incomplete + +use std::future::Future; + +trait Trait { + async fn method() {} +} + +fn test>>>() {} +//~^ ERROR return type notation is not allowed to use type equality + +fn main() {} diff --git a/tests/ui/associated-type-bounds/return-type-notation/equality.stderr b/tests/ui/associated-type-bounds/return-type-notation/equality.stderr new file mode 100644 index 00000000000..c5b2e5710d4 --- /dev/null +++ b/tests/ui/associated-type-bounds/return-type-notation/equality.stderr @@ -0,0 +1,25 @@ +warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/equality.rs:3:12 + | +LL | #![feature(return_type_notation, async_fn_in_trait)] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #109417 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/equality.rs:3:34 + | +LL | #![feature(return_type_notation, async_fn_in_trait)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #91611 for more information + +error: return type notation is not allowed to use type equality + --> $DIR/equality.rs:13:18 + | +LL | fn test>>>() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error; 2 warnings emitted + diff --git a/tests/ui/associated-type-bounds/return-type-notation/missing.rs b/tests/ui/associated-type-bounds/return-type-notation/missing.rs new file mode 100644 index 00000000000..7b98a5cdafd --- /dev/null +++ b/tests/ui/associated-type-bounds/return-type-notation/missing.rs @@ -0,0 +1,14 @@ +// edition: 2021 + +#![feature(return_type_notation, async_fn_in_trait)] +//~^ WARN the feature `return_type_notation` is incomplete +//~| WARN the feature `async_fn_in_trait` is incomplete + +trait Trait { + async fn method() {} +} + +fn bar>() {} +//~^ ERROR cannot find associated function `methid` in trait `Trait` + +fn main() {} diff --git a/tests/ui/associated-type-bounds/return-type-notation/missing.stderr b/tests/ui/associated-type-bounds/return-type-notation/missing.stderr new file mode 100644 index 00000000000..34f5bda884d --- /dev/null +++ b/tests/ui/associated-type-bounds/return-type-notation/missing.stderr @@ -0,0 +1,25 @@ +warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/missing.rs:3:12 + | +LL | #![feature(return_type_notation, async_fn_in_trait)] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #109417 for more information + = note: `#[warn(incomplete_features)]` on by default + +warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/missing.rs:3:34 + | +LL | #![feature(return_type_notation, async_fn_in_trait)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #91611 for more information + +error: cannot find associated function `methid` in trait `Trait` + --> $DIR/missing.rs:11:17 + | +LL | fn bar>() {} + | ^^^^^^^^^^^^^^ + +error: aborting due to previous error; 2 warnings emitted + diff --git a/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.rs b/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.rs new file mode 100644 index 00000000000..db5f6fe389e --- /dev/null +++ b/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.rs @@ -0,0 +1,11 @@ +#![feature(return_type_notation)] +//~^ WARN the feature `return_type_notation` is incomplete + +trait Trait { + fn method() {} +} + +fn test>() {} +//~^ ERROR return type notation used on function that is not `async` and does not return `impl Trait` + +fn main() {} diff --git a/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.stderr b/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.stderr new file mode 100644 index 00000000000..31b793995f8 --- /dev/null +++ b/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.stderr @@ -0,0 +1,22 @@ +warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/non-rpitit.rs:1:12 + | +LL | #![feature(return_type_notation)] + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #109417 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: return type notation used on function that is not `async` and does not return `impl Trait` + --> $DIR/non-rpitit.rs:8:18 + | +LL | fn method() {} + | ----------- this function must be `async` or return `impl Trait` +... +LL | fn test>() {} + | ^^^^^^^^^^^^^^ + | + = note: function returns `()`, which is not compatible with associated type return bounds + +error: aborting due to previous error; 1 warning emitted + From 8b592db27afdc9edac084520bca98508da53c996 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 16 Mar 2023 22:00:08 +0000 Subject: [PATCH 204/346] Add `(..)` syntax for RTN --- compiler/rustc_ast/src/ast.rs | 20 ++-- compiler/rustc_ast/src/mut_visit.rs | 1 + compiler/rustc_ast/src/visit.rs | 1 + compiler/rustc_ast_lowering/messages.ftl | 4 + compiler/rustc_ast_lowering/src/errors.rs | 8 +- compiler/rustc_ast_lowering/src/lib.rs | 85 +++++++++------ compiler/rustc_ast_lowering/src/path.rs | 30 +++++- .../rustc_ast_passes/src/ast_validation.rs | 14 ++- compiler/rustc_ast_passes/src/feature_gate.rs | 20 ++-- compiler/rustc_ast_pretty/src/pprust/state.rs | 4 + compiler/rustc_expand/src/build.rs | 2 +- compiler/rustc_hir/src/hir.rs | 22 +++- .../rustc_hir_analysis/src/astconv/errors.rs | 22 ++-- .../rustc_hir_analysis/src/astconv/mod.rs | 2 +- .../src/collect/resolve_bound_vars.rs | 4 +- .../wrong_number_of_generic_args.rs | 8 +- compiler/rustc_hir_pretty/src/lib.rs | 100 +++++++++--------- compiler/rustc_parse/messages.ftl | 4 + compiler/rustc_parse/src/errors.rs | 8 ++ .../rustc_parse/src/parser/diagnostics.rs | 3 +- compiler/rustc_parse/src/parser/path.rs | 29 ++++- compiler/rustc_parse/src/parser/ty.rs | 7 +- compiler/rustc_passes/src/hir_stats.rs | 2 +- compiler/rustc_resolve/src/late.rs | 1 + compiler/rustc_resolve/src/lib.rs | 1 + src/librustdoc/clean/mod.rs | 3 +- .../clippy/clippy_lints/src/ref_option_ref.rs | 4 +- .../clippy_lints/src/types/borrowed_box.rs | 2 +- .../clippy/clippy_lints/src/types/utils.rs | 4 +- src/tools/clippy/clippy_lints/src/use_self.rs | 5 +- .../clippy/clippy_utils/src/hir_utils.rs | 7 +- .../bad-inputs-and-output.rs | 5 +- .../bad-inputs-and-output.stderr | 18 ++-- .../return-type-notation/basic.rs | 2 +- .../return-type-notation/equality.rs | 2 +- .../return-type-notation/equality.stderr | 4 +- .../return-type-notation/missing.rs | 2 +- .../return-type-notation/missing.stderr | 4 +- .../return-type-notation/non-rpitit.rs | 2 +- .../return-type-notation/non-rpitit.stderr | 4 +- ...ature-gate-return_type_notation.cfg.stderr | 21 ++++ ...eature-gate-return_type_notation.no.stderr | 21 ++++ .../feature-gate-return_type_notation.rs | 8 +- .../feature-gate-return_type_notation.stderr | 36 ------- 44 files changed, 355 insertions(+), 201 deletions(-) create mode 100644 tests/ui/feature-gates/feature-gate-return_type_notation.cfg.stderr create mode 100644 tests/ui/feature-gates/feature-gate-return_type_notation.no.stderr delete mode 100644 tests/ui/feature-gates/feature-gate-return_type_notation.stderr diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 710c7ad3b2e..f8f639d982f 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -167,6 +167,9 @@ pub enum GenericArgs { AngleBracketed(AngleBracketedArgs), /// The `(A, B)` and `C` in `Foo(A, B) -> C`. Parenthesized(ParenthesizedArgs), + /// Associated return type bounds, like `T: Trait` + /// which applies the `Send` bound to the return-type of `method`. + ReturnTypeNotation(Span), } impl GenericArgs { @@ -174,14 +177,11 @@ impl GenericArgs { matches!(self, AngleBracketed(..)) } - pub fn is_parenthesized(&self) -> bool { - matches!(self, Parenthesized(..)) - } - pub fn span(&self) -> Span { match self { AngleBracketed(data) => data.span, Parenthesized(data) => data.span, + ReturnTypeNotation(span) => *span, } } } @@ -235,15 +235,15 @@ impl AngleBracketedArg { } } -impl Into>> for AngleBracketedArgs { - fn into(self) -> Option> { - Some(P(GenericArgs::AngleBracketed(self))) +impl Into> for AngleBracketedArgs { + fn into(self) -> P { + P(GenericArgs::AngleBracketed(self)) } } -impl Into>> for ParenthesizedArgs { - fn into(self) -> Option> { - Some(P(GenericArgs::Parenthesized(self))) +impl Into> for ParenthesizedArgs { + fn into(self) -> P { + P(GenericArgs::Parenthesized(self)) } } diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 46e46ab575e..514978f5569 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -561,6 +561,7 @@ pub fn noop_visit_generic_args(generic_args: &mut GenericArgs, vi match generic_args { GenericArgs::AngleBracketed(data) => vis.visit_angle_bracketed_parameter_data(data), GenericArgs::Parenthesized(data) => vis.visit_parenthesized_parameter_data(data), + GenericArgs::ReturnTypeNotation(_span) => {} } } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 608f87ab6eb..e5a0ad1f1e4 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -481,6 +481,7 @@ where walk_list!(visitor, visit_ty, &data.inputs); walk_fn_ret_ty(visitor, &data.output); } + GenericArgs::ReturnTypeNotation(_span) => {} } } diff --git a/compiler/rustc_ast_lowering/messages.ftl b/compiler/rustc_ast_lowering/messages.ftl index dac61ec975e..21b2a3c22fa 100644 --- a/compiler/rustc_ast_lowering/messages.ftl +++ b/compiler/rustc_ast_lowering/messages.ftl @@ -144,6 +144,10 @@ ast_lowering_bad_return_type_notation_inputs = argument types not allowed with return type notation .suggestion = remove the input types +ast_lowering_bad_return_type_notation_needs_dots = + return type notation arguments must be elided with `..` + .suggestion = add `..` + ast_lowering_bad_return_type_notation_output = return type not allowed with return type notation .suggestion = remove the return type diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs index 4eefd951b24..f4e55619ebb 100644 --- a/compiler/rustc_ast_lowering/src/errors.rs +++ b/compiler/rustc_ast_lowering/src/errors.rs @@ -353,7 +353,13 @@ pub enum BadReturnTypeNotation { #[diag(ast_lowering_bad_return_type_notation_inputs)] Inputs { #[primary_span] - #[suggestion(code = "()", applicability = "maybe-incorrect")] + #[suggestion(code = "(..)", applicability = "maybe-incorrect")] + span: Span, + }, + #[diag(ast_lowering_bad_return_type_notation_needs_dots)] + NeedsDots { + #[primary_span] + #[suggestion(code = "(..)", applicability = "maybe-incorrect")] span: Span, }, #[diag(ast_lowering_bad_return_type_notation_output)] diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index aa4ff2882b2..c5d39634c44 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -66,7 +66,7 @@ use rustc_middle::{ span_bug, ty::{ResolverAstLowering, TyCtxt}, }; -use rustc_session::parse::feature_err; +use rustc_session::parse::{add_feature_diagnostics, feature_err}; use rustc_span::hygiene::MacroKind; use rustc_span::source_map::DesugaringKind; use rustc_span::symbol::{kw, sym, Ident, Symbol}; @@ -987,33 +987,56 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { GenericArgs::AngleBracketed(data) => { self.lower_angle_bracketed_parameter_data(data, ParamMode::Explicit, itctx).0 } - GenericArgs::Parenthesized(data) if self.tcx.features().return_type_notation => { - if !data.inputs.is_empty() { - self.tcx.sess.emit_err(errors::BadReturnTypeNotation::Inputs { - span: data.inputs_span, - }); - } else if let FnRetTy::Ty(ty) = &data.output { - self.tcx.sess.emit_err(errors::BadReturnTypeNotation::Output { - span: data.inputs_span.shrink_to_hi().to(ty.span), - }); - } - GenericArgsCtor { - args: Default::default(), - bindings: &[], - parenthesized: true, - span: data.span, - } - } + &GenericArgs::ReturnTypeNotation(span) => GenericArgsCtor { + args: Default::default(), + bindings: &[], + parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation, + span, + }, GenericArgs::Parenthesized(data) => { - self.emit_bad_parenthesized_trait_in_assoc_ty(data); - // FIXME(return_type_notation): we could issue a feature error - // if the parens are empty and there's no return type. - self.lower_angle_bracketed_parameter_data( - &data.as_angle_bracketed_args(), - ParamMode::Explicit, - itctx, - ) - .0 + if let Some(start_char) = constraint.ident.as_str().chars().next() + && start_char.is_ascii_lowercase() + { + let mut err = if !data.inputs.is_empty() { + self.tcx.sess.create_err(errors::BadReturnTypeNotation::Inputs { + span: data.inputs_span, + }) + } else if let FnRetTy::Ty(ty) = &data.output { + self.tcx.sess.create_err(errors::BadReturnTypeNotation::Output { + span: data.inputs_span.shrink_to_hi().to(ty.span), + }) + } else { + self.tcx.sess.create_err(errors::BadReturnTypeNotation::NeedsDots { + span: data.inputs_span, + }) + }; + if !self.tcx.features().return_type_notation + && self.tcx.sess.is_nightly_build() + { + add_feature_diagnostics( + &mut err, + &self.tcx.sess.parse_sess, + sym::return_type_notation, + ); + } + err.emit(); + GenericArgsCtor { + args: Default::default(), + bindings: &[], + parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation, + span: data.span, + } + } else { + self.emit_bad_parenthesized_trait_in_assoc_ty(data); + // FIXME(return_type_notation): we could issue a feature error + // if the parens are empty and there's no return type. + self.lower_angle_bracketed_parameter_data( + &data.as_angle_bracketed_args(), + ParamMode::Explicit, + itctx, + ) + .0 + } } }; gen_args_ctor.into_generic_args(self) @@ -2094,7 +2117,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let future_args = self.arena.alloc(hir::GenericArgs { args: &[], bindings: arena_vec![self; self.output_ty_binding(span, output_ty)], - parenthesized: false, + parenthesized: hir::GenericArgsParentheses::No, span_ext: DUMMY_SP, }); @@ -2614,13 +2637,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { struct GenericArgsCtor<'hir> { args: SmallVec<[hir::GenericArg<'hir>; 4]>, bindings: &'hir [hir::TypeBinding<'hir>], - parenthesized: bool, + parenthesized: hir::GenericArgsParentheses, span: Span, } impl<'hir> GenericArgsCtor<'hir> { fn is_empty(&self) -> bool { - self.args.is_empty() && self.bindings.is_empty() && !self.parenthesized + self.args.is_empty() + && self.bindings.is_empty() + && self.parenthesized == hir::GenericArgsParentheses::No } fn into_generic_args(self, this: &LoweringContext<'_, 'hir>) -> &'hir hir::GenericArgs<'hir> { diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index 6ab23206f54..1c47a969696 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -13,6 +13,7 @@ use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::{BytePos, Span, DUMMY_SP}; use smallvec::{smallvec, SmallVec}; +use thin_vec::ThinVec; impl<'a, 'hir> LoweringContext<'a, 'hir> { #[instrument(level = "trace", skip(self))] @@ -218,13 +219,25 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) } }, + &GenericArgs::ReturnTypeNotation(span) => { + self.tcx.sess.emit_err(GenericTypeWithParentheses { span, sub: None }); + ( + self.lower_angle_bracketed_parameter_data( + &AngleBracketedArgs { span, args: ThinVec::default() }, + param_mode, + itctx, + ) + .0, + false, + ) + } } } else { ( GenericArgsCtor { args: Default::default(), bindings: &[], - parenthesized: false, + parenthesized: hir::GenericArgsParentheses::No, span: path_span.shrink_to_hi(), }, param_mode == ParamMode::Optional, @@ -233,7 +246,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let has_lifetimes = generic_args.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_))); - if !generic_args.parenthesized && !has_lifetimes { + + // FIXME(return_type_notation): Is this correct? I think so. + if generic_args.parenthesized != hir::GenericArgsParentheses::ParenSugar && !has_lifetimes { self.maybe_insert_elided_lifetimes_in_path( path_span, segment.id, @@ -328,7 +343,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { AngleBracketedArg::Constraint(c) => Some(self.lower_assoc_ty_constraint(c, itctx)), AngleBracketedArg::Arg(_) => None, })); - let ctor = GenericArgsCtor { args, bindings, parenthesized: false, span: data.span }; + let ctor = GenericArgsCtor { + args, + bindings, + parenthesized: hir::GenericArgsParentheses::No, + span: data.span, + }; (ctor, !has_non_lt_args && param_mode == ParamMode::Optional) } @@ -376,7 +396,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { GenericArgsCtor { args, bindings: arena_vec![self; binding], - parenthesized: true, + parenthesized: hir::GenericArgsParentheses::ParenSugar, span: data.inputs_span, }, false, @@ -396,7 +416,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let gen_args = self.arena.alloc(hir::GenericArgs { args, bindings, - parenthesized: false, + parenthesized: hir::GenericArgsParentheses::No, span_ext: DUMMY_SP, }); hir::TypeBinding { diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 93c854cc809..44b6c77fc41 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -1075,6 +1075,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.with_impl_trait(None, |this| this.visit_ty(ty)); } } + GenericArgs::ReturnTypeNotation(_span) => {} } } @@ -1387,16 +1388,19 @@ fn deny_equality_constraints( match &mut assoc_path.segments[len].args { Some(args) => match args.deref_mut() { GenericArgs::Parenthesized(_) => continue, + GenericArgs::ReturnTypeNotation(_span) => continue, GenericArgs::AngleBracketed(args) => { args.args.push(arg); } }, empty_args => { - *empty_args = AngleBracketedArgs { - span: ident.span, - args: thin_vec![arg], - } - .into(); + *empty_args = Some( + AngleBracketedArgs { + span: ident.span, + args: thin_vec![arg], + } + .into(), + ); } } err.assoc = Some(errors::AssociatedSuggestion { diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 1413db64a48..de94c1bc477 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -482,13 +482,20 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { fn visit_assoc_constraint(&mut self, constraint: &'a AssocConstraint) { if let AssocConstraintKind::Bound { .. } = constraint.kind { - if constraint.gen_args.as_ref().map_or(false, |args| args.is_parenthesized()) { - gate_feature_post!( - &self, - return_type_notation, - constraint.span, - "return type notation is unstable" + if let Some(args) = constraint.gen_args.as_ref() + && matches!( + args, + ast::GenericArgs::ReturnTypeNotation(..) | ast::GenericArgs::Parenthesized(..) ) + { + // RTN is gated elsewhere, and parenthesized args will turn into + // another error. + if matches!(args, ast::GenericArgs::Parenthesized(..)) { + self.sess.delay_span_bug( + constraint.span, + "should have emitted a parenthesized generics error", + ); + } } else { gate_feature_post!( &self, @@ -586,6 +593,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) { gate_all!(yeet_expr, "`do yeet` expression is experimental"); gate_all!(dyn_star, "`dyn*` trait objects are experimental"); gate_all!(const_closures, "const closures are experimental"); + gate_all!(return_type_notation, "return type notation is experimental"); // All uses of `gate_all!` below this point were added in #65742, // and subsequently disabled (with the non-early gating readded). diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 694d688bf1f..80c451d6753 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -936,6 +936,10 @@ impl<'a> PrintState<'a> for State<'a> { self.word(")"); self.print_fn_ret_ty(&data.output); } + + ast::GenericArgs::ReturnTypeNotation(_span) => { + self.word("(..)"); + } } } } diff --git a/compiler/rustc_expand/src/build.rs b/compiler/rustc_expand/src/build.rs index 8a78c3296f9..8a16143311b 100644 --- a/compiler/rustc_expand/src/build.rs +++ b/compiler/rustc_expand/src/build.rs @@ -36,7 +36,7 @@ impl<'a> ExtCtxt<'a> { ); let args = if !args.is_empty() { let args = args.into_iter().map(ast::AngleBracketedArg::Arg).collect(); - ast::AngleBracketedArgs { args, span }.into() + Some(ast::AngleBracketedArgs { args, span }.into()) } else { None }; diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index f4b46b9a131..35a72f868fb 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -328,7 +328,7 @@ pub struct GenericArgs<'hir> { /// Were arguments written in parenthesized form `Fn(T) -> U`? /// This is required mostly for pretty-printing and diagnostics, /// but also for changing lifetime elision rules to be "function-like". - pub parenthesized: bool, + pub parenthesized: GenericArgsParentheses, /// The span encompassing arguments and the surrounding brackets `<>` or `()` /// Foo Fn(T, U, V) -> W /// ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^ @@ -340,11 +340,16 @@ pub struct GenericArgs<'hir> { impl<'hir> GenericArgs<'hir> { pub const fn none() -> Self { - Self { args: &[], bindings: &[], parenthesized: false, span_ext: DUMMY_SP } + Self { + args: &[], + bindings: &[], + parenthesized: GenericArgsParentheses::No, + span_ext: DUMMY_SP, + } } pub fn inputs(&self) -> &[Ty<'hir>] { - if self.parenthesized { + if self.parenthesized == GenericArgsParentheses::ParenSugar { for arg in self.args { match arg { GenericArg::Lifetime(_) => {} @@ -417,6 +422,17 @@ impl<'hir> GenericArgs<'hir> { } } +#[derive(Copy, Clone, PartialEq, Eq, Encodable, Hash, Debug)] +#[derive(HashStable_Generic)] +pub enum GenericArgsParentheses { + No, + /// Bounds for `feature(return_type_notation)`, like `T: Trait`, + /// where the args are explicitly elided with `..` + ReturnTypeNotation, + /// parenthesized function-family traits, like `T: Fn(u32) -> i32` + ParenSugar, +} + /// A modifier on a bound, currently this is only used for `?Sized`, where the /// modifier is `Maybe`. Negative bounds should also be handled here. #[derive(Copy, Clone, PartialEq, Eq, Encodable, Hash, Debug)] diff --git a/compiler/rustc_hir_analysis/src/astconv/errors.rs b/compiler/rustc_hir_analysis/src/astconv/errors.rs index 156334fe785..672e7176fde 100644 --- a/compiler/rustc_hir_analysis/src/astconv/errors.rs +++ b/compiler/rustc_hir_analysis/src/astconv/errors.rs @@ -55,7 +55,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let trait_def = self.tcx().trait_def(trait_def_id); if !trait_def.paren_sugar { - if trait_segment.args().parenthesized { + if trait_segment.args().parenthesized == hir::GenericArgsParentheses::ParenSugar { // For now, require that parenthetical notation be used only with `Fn()` etc. let mut err = feature_err( &self.tcx().sess.parse_sess, @@ -71,7 +71,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let sess = self.tcx().sess; - if !trait_segment.args().parenthesized { + if trait_segment.args().parenthesized != hir::GenericArgsParentheses::ParenSugar { // For now, require that parenthetical notation be used only with `Fn()` etc. let mut err = feature_err( &sess.parse_sess, @@ -607,11 +607,19 @@ pub fn prohibit_assoc_ty_binding( span: Span, segment: Option<(&hir::PathSegment<'_>, Span)>, ) { - tcx.sess.emit_err(AssocTypeBindingNotAllowed { span, fn_trait_expansion: if let Some((segment, span)) = segment && segment.args().parenthesized { - Some(ParenthesizedFnTraitExpansion { span, expanded_type: fn_trait_to_string(tcx, segment, false) }) - } else { - None - }}); + tcx.sess.emit_err(AssocTypeBindingNotAllowed { + span, + fn_trait_expansion: if let Some((segment, span)) = segment + && segment.args().parenthesized == hir::GenericArgsParentheses::ParenSugar + { + Some(ParenthesizedFnTraitExpansion { + span, + expanded_type: fn_trait_to_string(tcx, segment, false), + }) + } else { + None + }, + }); } pub(crate) fn fn_trait_to_string( diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 1e590d93c8c..e25b07d9392 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -1087,7 +1087,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { let tcx = self.tcx(); let return_type_notation = - binding.gen_args.parenthesized && tcx.features().return_type_notation; + binding.gen_args.parenthesized == hir::GenericArgsParentheses::ReturnTypeNotation; let candidate = if return_type_notation { if self.trait_defines_associated_item_named( diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 1a4a1636071..5e4f377a1e7 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -1461,7 +1461,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { depth: usize, generic_args: &'tcx hir::GenericArgs<'tcx>, ) { - if generic_args.parenthesized { + if generic_args.parenthesized == hir::GenericArgsParentheses::ParenSugar { self.visit_fn_like_elision( generic_args.inputs(), Some(generic_args.bindings[0].ty()), @@ -1653,7 +1653,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { // `for<'a> T::Trait<'a, x(): for<'b> Other<'b>>` // this is going to expand to something like: // `for<'a> for<'r, T> >::x::<'r, T>::{opaque#0}: for<'b> Other<'b>`. - if binding.gen_args.parenthesized { + if binding.gen_args.parenthesized == hir::GenericArgsParentheses::ReturnTypeNotation { let bound_vars = if let Some(type_def_id) = type_def_id && self.tcx.def_kind(type_def_id) == DefKind::Trait // FIXME(return_type_notation): We could bound supertrait methods. diff --git a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs index cae884ae8fb..8f4d81ec3a9 100644 --- a/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs @@ -565,7 +565,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { /// type Map = HashMap; /// ``` fn suggest_adding_args(&self, err: &mut Diagnostic) { - if self.gen_args.parenthesized { + if self.gen_args.parenthesized != hir::GenericArgsParentheses::No { return; } @@ -962,7 +962,11 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { let msg = format!( "remove these {}generics", - if self.gen_args.parenthesized { "parenthetical " } else { "" }, + if self.gen_args.parenthesized == hir::GenericArgsParentheses::ParenSugar { + "parenthetical " + } else { + "" + }, ); err.span_suggestion(span, &msg, "", Applicability::MaybeIncorrect); diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 63ea6c90477..4f27c01fad2 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1652,61 +1652,65 @@ impl<'a> State<'a> { generic_args: &hir::GenericArgs<'_>, colons_before_params: bool, ) { - if generic_args.parenthesized { - self.word("("); - self.commasep(Inconsistent, generic_args.inputs(), |s, ty| s.print_type(ty)); - self.word(")"); + match generic_args.parenthesized { + hir::GenericArgsParentheses::No => { + let start = if colons_before_params { "::<" } else { "<" }; + let empty = Cell::new(true); + let start_or_comma = |this: &mut Self| { + if empty.get() { + empty.set(false); + this.word(start) + } else { + this.word_space(",") + } + }; - self.space_if_not_bol(); - self.word_space("->"); - self.print_type(generic_args.bindings[0].ty()); - } else { - let start = if colons_before_params { "::<" } else { "<" }; - let empty = Cell::new(true); - let start_or_comma = |this: &mut Self| { - if empty.get() { - empty.set(false); - this.word(start) - } else { - this.word_space(",") - } - }; + let mut nonelided_generic_args: bool = false; + let elide_lifetimes = generic_args.args.iter().all(|arg| match arg { + GenericArg::Lifetime(lt) if lt.is_elided() => true, + GenericArg::Lifetime(_) => { + nonelided_generic_args = true; + false + } + _ => { + nonelided_generic_args = true; + true + } + }); - let mut nonelided_generic_args: bool = false; - let elide_lifetimes = generic_args.args.iter().all(|arg| match arg { - GenericArg::Lifetime(lt) if lt.is_elided() => true, - GenericArg::Lifetime(_) => { - nonelided_generic_args = true; - false + if nonelided_generic_args { + start_or_comma(self); + self.commasep(Inconsistent, generic_args.args, |s, generic_arg| { + match generic_arg { + GenericArg::Lifetime(lt) if !elide_lifetimes => s.print_lifetime(lt), + GenericArg::Lifetime(_) => {} + GenericArg::Type(ty) => s.print_type(ty), + GenericArg::Const(ct) => s.print_anon_const(&ct.value), + GenericArg::Infer(_inf) => s.word("_"), + } + }); } - _ => { - nonelided_generic_args = true; - true - } - }); - if nonelided_generic_args { - start_or_comma(self); - self.commasep( - Inconsistent, - generic_args.args, - |s, generic_arg| match generic_arg { - GenericArg::Lifetime(lt) if !elide_lifetimes => s.print_lifetime(lt), - GenericArg::Lifetime(_) => {} - GenericArg::Type(ty) => s.print_type(ty), - GenericArg::Const(ct) => s.print_anon_const(&ct.value), - GenericArg::Infer(_inf) => s.word("_"), - }, - ); + for binding in generic_args.bindings { + start_or_comma(self); + self.print_type_binding(binding); + } + + if !empty.get() { + self.word(">") + } } + hir::GenericArgsParentheses::ParenSugar => { + self.word("("); + self.commasep(Inconsistent, generic_args.inputs(), |s, ty| s.print_type(ty)); + self.word(")"); - for binding in generic_args.bindings { - start_or_comma(self); - self.print_type_binding(binding); + self.space_if_not_bol(); + self.word_space("->"); + self.print_type(generic_args.bindings[0].ty()); } - - if !empty.get() { - self.word(">") + hir::GenericArgsParentheses::ReturnTypeNotation => { + self.word("(..)"); } } } diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index 96765c296e7..e21bbd0217b 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -734,3 +734,7 @@ parse_unknown_start_of_token = unknown start of token: {$escaped} parse_box_syntax_removed = `box_syntax` has been removed .suggestion = use `Box::new()` instead + +parse_bad_return_type_notation_output = + return type not allowed with return type notation + .suggestion = remove the return type diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index a9d116012ae..aead216b61c 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -2316,3 +2316,11 @@ pub struct BoxSyntaxRemoved<'a> { pub span: Span, pub code: &'a str, } + +#[derive(Diagnostic)] +#[diag(parse_bad_return_type_notation_output)] +pub(crate) struct BadReturnTypeNotationOutput { + #[primary_span] + #[suggestion(code = "", applicability = "maybe-incorrect")] + pub span: Span, +} diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 9544afd3d6d..5210b8fe69d 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -989,8 +989,7 @@ impl<'a> Parser<'a> { } if self.token.kind == token::OpenDelim(Delimiter::Parenthesis) { // Recover from bad turbofish: `foo.collect::Vec<_>()`. - let args = AngleBracketedArgs { args, span }.into(); - segment.args = args; + segment.args = Some(AngleBracketedArgs { args, span }.into()); self.sess.emit_err(GenericParamsWithoutAngleBrackets { span, diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 72f230e628d..f1c9f0109f8 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -1,6 +1,6 @@ use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign}; use super::{Parser, Restrictions, TokenType}; -use crate::maybe_whole; +use crate::{errors, maybe_whole}; use rustc_ast::ptr::P; use rustc_ast::token::{self, Delimiter, Token, TokenKind}; use rustc_ast::{ @@ -290,6 +290,25 @@ impl<'a> Parser<'a> { })?; let span = lo.to(self.prev_token.span); AngleBracketedArgs { args, span }.into() + } else if self.token.kind == token::OpenDelim(Delimiter::Parenthesis) + // FIXME(return_type_notation): Could also recover `...` here. + && self.look_ahead(1, |tok| tok.kind == token::DotDot) + { + let lo = self.token.span; + self.bump(); + self.bump(); + self.expect(&token::CloseDelim(Delimiter::Parenthesis))?; + let span = lo.to(self.prev_token.span); + self.sess.gated_spans.gate(sym::return_type_notation, span); + + if self.eat_noexpect(&token::RArrow) { + let lo = self.prev_token.span; + let ty = self.parse_ty()?; + self.sess + .emit_err(errors::BadReturnTypeNotationOutput { span: lo.to(ty.span) }); + } + + P(GenericArgs::ReturnTypeNotation(span)) } else { // `(T, U) -> R` let (inputs, _) = self.parse_paren_comma_seq(|p| p.parse_ty())?; @@ -300,7 +319,7 @@ impl<'a> Parser<'a> { ParenthesizedArgs { span, inputs, inputs_span, output }.into() }; - PathSegment { ident, args, id: ast::DUMMY_NODE_ID } + PathSegment { ident, args: Some(args), id: ast::DUMMY_NODE_ID } } else { // Generic arguments are not found. PathSegment::from_ident(ident) @@ -550,8 +569,10 @@ impl<'a> Parser<'a> { // Gate associated type bounds, e.g., `Iterator`. if let AssocConstraintKind::Bound { .. } = kind { - if gen_args.as_ref().map_or(false, |args| args.is_parenthesized()) { - self.sess.gated_spans.gate(sym::return_type_notation, span); + if gen_args.as_ref().map_or(false, |args| { + matches!(args, GenericArgs::ReturnTypeNotation(..)) + }) { + // This is already gated in `parse_path_segment` } else { self.sess.gated_spans.gate(sym::associated_type_bounds, span); } diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 3d9d2cc62e3..400c8dbe9bc 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -1059,8 +1059,11 @@ impl<'a> Parser<'a> { output, } .into(); - *fn_path_segment = - ast::PathSegment { ident: fn_path_segment.ident, args, id: ast::DUMMY_NODE_ID }; + *fn_path_segment = ast::PathSegment { + ident: fn_path_segment.ident, + args: Some(args), + id: ast::DUMMY_NODE_ID, + }; // Convert parsed `<'a>` in `Fn<'a>` into `for<'a>`. let mut generic_params = lifetimes diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs index 47e032758f2..ce44f709f3b 100644 --- a/compiler/rustc_passes/src/hir_stats.rs +++ b/compiler/rustc_passes/src/hir_stats.rs @@ -666,7 +666,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> { fn visit_generic_args(&mut self, g: &'v ast::GenericArgs) { record_variants!( (self, g, g, Id::None, ast, GenericArgs, GenericArgs), - [AngleBracketed, Parenthesized] + [AngleBracketed, Parenthesized, ReturnTypeNotation] ); ast_visit::walk_generic_args(self, g) } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 4ca54bab31a..f66bad1d429 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1110,6 +1110,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast, } } } + GenericArgs::ReturnTypeNotation(_span) => {} } } } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 0e84432a5b4..99fad22d4a1 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -312,6 +312,7 @@ impl<'a> From<&'a ast::PathSegment> for Segment { (args.span, found_lifetimes) } GenericArgs::Parenthesized(args) => (args.span, true), + GenericArgs::ReturnTypeNotation(span) => (*span, false), } } else { (DUMMY_SP, false) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 5f5521caf68..a25210d265a 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2013,7 +2013,8 @@ fn clean_generic_args<'tcx>( generic_args: &hir::GenericArgs<'tcx>, cx: &mut DocContext<'tcx>, ) -> GenericArgs { - if generic_args.parenthesized { + // FIXME(return_type_notation): Fix RTN parens rendering + if generic_args.parenthesized == hir::GenericArgsParentheses::ParenSugar { let output = clean_ty(generic_args.bindings[0].ty(), cx); let output = if output != Type::Tuple(Vec::new()) { Some(Box::new(output)) } else { None }; let inputs = diff --git a/src/tools/clippy/clippy_lints/src/ref_option_ref.rs b/src/tools/clippy/clippy_lints/src/ref_option_ref.rs index 448a32b77c0..c984a8286eb 100644 --- a/src/tools/clippy/clippy_lints/src/ref_option_ref.rs +++ b/src/tools/clippy/clippy_lints/src/ref_option_ref.rs @@ -3,7 +3,7 @@ use clippy_utils::last_path_segment; use clippy_utils::source::snippet; use if_chain::if_chain; use rustc_errors::Applicability; -use rustc_hir::{GenericArg, Mutability, Ty, TyKind}; +use rustc_hir::{GenericArg, GenericArgsParentheses, Mutability, Ty, TyKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::symbol::sym; @@ -47,7 +47,7 @@ impl<'tcx> LateLintPass<'tcx> for RefOptionRef { if cx.tcx.is_diagnostic_item(sym::Option, def_id); if let Some(params) = last_path_segment(qpath).args ; - if !params.parenthesized; + if params.parenthesized == GenericArgsParentheses::No; if let Some(inner_ty) = params.args.iter().find_map(|arg| match arg { GenericArg::Type(inner_ty) => Some(inner_ty), _ => None, diff --git a/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs b/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs index 65dfe7637ea..acdf5471069 100644 --- a/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs +++ b/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs @@ -20,7 +20,7 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, lt: &Lifetime, m if let QPath::Resolved(None, path) = *qpath; if let [ref bx] = *path.segments; if let Some(params) = bx.args; - if !params.parenthesized; + if params.parenthesized == hir::GenericArgsParentheses::No; if let Some(inner) = params.args.iter().find_map(|arg| match arg { GenericArg::Type(ty) => Some(ty), _ => None, diff --git a/src/tools/clippy/clippy_lints/src/types/utils.rs b/src/tools/clippy/clippy_lints/src/types/utils.rs index 7f43b7841ff..a30748db88f 100644 --- a/src/tools/clippy/clippy_lints/src/types/utils.rs +++ b/src/tools/clippy/clippy_lints/src/types/utils.rs @@ -1,6 +1,6 @@ use clippy_utils::last_path_segment; use if_chain::if_chain; -use rustc_hir::{GenericArg, QPath, TyKind}; +use rustc_hir::{GenericArg, GenericArgsParentheses, QPath, TyKind}; use rustc_lint::LateContext; use rustc_span::source_map::Span; @@ -8,7 +8,7 @@ pub(super) fn match_borrows_parameter(_cx: &LateContext<'_>, qpath: &QPath<'_>) let last = last_path_segment(qpath); if_chain! { if let Some(params) = last.args; - if !params.parenthesized; + if params.parenthesized == GenericArgsParentheses::No; if let Some(ty) = params.args.iter().find_map(|arg| match arg { GenericArg::Type(ty) => Some(ty), _ => None, diff --git a/src/tools/clippy/clippy_lints/src/use_self.rs b/src/tools/clippy/clippy_lints/src/use_self.rs index 8ea5475fb25..7dfb0956077 100644 --- a/src/tools/clippy/clippy_lints/src/use_self.rs +++ b/src/tools/clippy/clippy_lints/src/use_self.rs @@ -10,7 +10,7 @@ use rustc_hir::{ def::{CtorOf, DefKind, Res}, def_id::LocalDefId, intravisit::{walk_inf, walk_ty, Visitor}, - Expr, ExprKind, FnRetTy, FnSig, GenericArg, GenericParam, GenericParamKind, HirId, Impl, ImplItemKind, Item, + Expr, ExprKind, FnRetTy, FnSig, GenericArg, GenericArgsParentheses, GenericParam, GenericParamKind, HirId, Impl, ImplItemKind, Item, ItemKind, Pat, PatKind, Path, QPath, Ty, TyKind, }; use rustc_hir_analysis::hir_ty_to_ty; @@ -100,7 +100,8 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { if let TyKind::Path(QPath::Resolved(_, item_path)) = self_ty.kind; let parameters = &item_path.segments.last().expect(SEGMENTS_MSG).args; if parameters.as_ref().map_or(true, |params| { - !params.parenthesized && !params.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_))) + params.parenthesized == GenericArgsParentheses::No + && !params.args.iter().any(|arg| matches!(arg, GenericArg::Lifetime(_))) }); if !item.span.from_expansion(); if !is_from_proc_macro(cx, item); // expensive, should be last check diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 3a6d23ca5c1..3ee7147828b 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -401,14 +401,9 @@ impl HirEqInterExpr<'_, '_, '_> { } fn eq_path_parameters(&mut self, left: &GenericArgs<'_>, right: &GenericArgs<'_>) -> bool { - if !(left.parenthesized || right.parenthesized) { + if left.parenthesized == right.parenthesized { over(left.args, right.args, |l, r| self.eq_generic_arg(l, r)) // FIXME(flip1995): may not work && over(left.bindings, right.bindings, |l, r| self.eq_type_binding(l, r)) - } else if left.parenthesized && right.parenthesized { - over(left.inputs(), right.inputs(), |l, r| self.eq_ty(l, r)) - && both(&Some(&left.bindings[0].ty()), &Some(&right.bindings[0].ty()), |l, r| { - self.eq_ty(l, r) - }) } else { false } diff --git a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs index 68e991de51f..75aa25906aa 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs +++ b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs @@ -11,7 +11,10 @@ trait Trait { fn foo>() {} //~^ ERROR argument types not allowed with return type notation -fn bar (): Send>>() {} +fn bar (): Send>>() {} //~^ ERROR return type not allowed with return type notation +fn baz>() {} +//~^ ERROR return type notation arguments must be elided with `..` + fn main() {} diff --git a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr index 03d97743271..5b075a0fa29 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr @@ -1,3 +1,9 @@ +error: return type not allowed with return type notation + --> $DIR/bad-inputs-and-output.rs:14:28 + | +LL | fn bar (): Send>>() {} + | ^^^^^ help: remove the return type + warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/bad-inputs-and-output.rs:3:12 | @@ -19,13 +25,13 @@ error: argument types not allowed with return type notation --> $DIR/bad-inputs-and-output.rs:11:23 | LL | fn foo>() {} - | ^^^^^ help: remove the input types: `()` + | ^^^^^ help: remove the input types: `(..)` -error: return type not allowed with return type notation - --> $DIR/bad-inputs-and-output.rs:14:25 +error: return type notation arguments must be elided with `..` + --> $DIR/bad-inputs-and-output.rs:17:23 | -LL | fn bar (): Send>>() {} - | ^^^^^^ help: remove the return type +LL | fn baz>() {} + | ^^ help: add `..`: `(..)` -error: aborting due to 2 previous errors; 2 warnings emitted +error: aborting due to 3 previous errors; 2 warnings emitted diff --git a/tests/ui/associated-type-bounds/return-type-notation/basic.rs b/tests/ui/associated-type-bounds/return-type-notation/basic.rs index 0b7530b65d7..75d1dc745d1 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/basic.rs +++ b/tests/ui/associated-type-bounds/return-type-notation/basic.rs @@ -18,7 +18,7 @@ async fn foo() -> Result<(), ()> { fn is_send(_: impl Send) {} fn test< - #[cfg(with)] T: Foo, + #[cfg(with)] T: Foo, #[cfg(without)] T: Foo, >() { is_send(foo::()); diff --git a/tests/ui/associated-type-bounds/return-type-notation/equality.rs b/tests/ui/associated-type-bounds/return-type-notation/equality.rs index 75f757e9025..c8fc980974e 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/equality.rs +++ b/tests/ui/associated-type-bounds/return-type-notation/equality.rs @@ -10,7 +10,7 @@ trait Trait { async fn method() {} } -fn test>>>() {} +fn test>>>() {} //~^ ERROR return type notation is not allowed to use type equality fn main() {} diff --git a/tests/ui/associated-type-bounds/return-type-notation/equality.stderr b/tests/ui/associated-type-bounds/return-type-notation/equality.stderr index c5b2e5710d4..cd50ff38694 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/equality.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/equality.stderr @@ -18,8 +18,8 @@ LL | #![feature(return_type_notation, async_fn_in_trait)] error: return type notation is not allowed to use type equality --> $DIR/equality.rs:13:18 | -LL | fn test>>>() {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | fn test>>>() {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to previous error; 2 warnings emitted diff --git a/tests/ui/associated-type-bounds/return-type-notation/missing.rs b/tests/ui/associated-type-bounds/return-type-notation/missing.rs index 7b98a5cdafd..1263cae4477 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/missing.rs +++ b/tests/ui/associated-type-bounds/return-type-notation/missing.rs @@ -8,7 +8,7 @@ trait Trait { async fn method() {} } -fn bar>() {} +fn bar>() {} //~^ ERROR cannot find associated function `methid` in trait `Trait` fn main() {} diff --git a/tests/ui/associated-type-bounds/return-type-notation/missing.stderr b/tests/ui/associated-type-bounds/return-type-notation/missing.stderr index 34f5bda884d..93111b5c36b 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/missing.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/missing.stderr @@ -18,8 +18,8 @@ LL | #![feature(return_type_notation, async_fn_in_trait)] error: cannot find associated function `methid` in trait `Trait` --> $DIR/missing.rs:11:17 | -LL | fn bar>() {} - | ^^^^^^^^^^^^^^ +LL | fn bar>() {} + | ^^^^^^^^^^^^^^^^ error: aborting due to previous error; 2 warnings emitted diff --git a/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.rs b/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.rs index db5f6fe389e..d283c6eab37 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.rs +++ b/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.rs @@ -5,7 +5,7 @@ trait Trait { fn method() {} } -fn test>() {} +fn test>() {} //~^ ERROR return type notation used on function that is not `async` and does not return `impl Trait` fn main() {} diff --git a/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.stderr b/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.stderr index 31b793995f8..38c498bc2fb 100644 --- a/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.stderr +++ b/tests/ui/associated-type-bounds/return-type-notation/non-rpitit.stderr @@ -13,8 +13,8 @@ error: return type notation used on function that is not `async` and does not re LL | fn method() {} | ----------- this function must be `async` or return `impl Trait` ... -LL | fn test>() {} - | ^^^^^^^^^^^^^^ +LL | fn test>() {} + | ^^^^^^^^^^^^^^^^ | = note: function returns `()`, which is not compatible with associated type return bounds diff --git a/tests/ui/feature-gates/feature-gate-return_type_notation.cfg.stderr b/tests/ui/feature-gates/feature-gate-return_type_notation.cfg.stderr new file mode 100644 index 00000000000..85728f8e1ad --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-return_type_notation.cfg.stderr @@ -0,0 +1,21 @@ +error[E0658]: return type notation is experimental + --> $DIR/feature-gate-return_type_notation.rs:12:18 + | +LL | fn foo>() {} + | ^^^^ + | + = note: see issue #109417 for more information + = help: add `#![feature(return_type_notation)]` to the crate attributes to enable + +warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/feature-gate-return_type_notation.rs:4:12 + | +LL | #![feature(async_fn_in_trait)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #91611 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-return_type_notation.no.stderr b/tests/ui/feature-gates/feature-gate-return_type_notation.no.stderr new file mode 100644 index 00000000000..85728f8e1ad --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-return_type_notation.no.stderr @@ -0,0 +1,21 @@ +error[E0658]: return type notation is experimental + --> $DIR/feature-gate-return_type_notation.rs:12:18 + | +LL | fn foo>() {} + | ^^^^ + | + = note: see issue #109417 for more information + = help: add `#![feature(return_type_notation)]` to the crate attributes to enable + +warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/feature-gate-return_type_notation.rs:4:12 + | +LL | #![feature(async_fn_in_trait)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #91611 for more information + = note: `#[warn(incomplete_features)]` on by default + +error: aborting due to previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/feature-gates/feature-gate-return_type_notation.rs b/tests/ui/feature-gates/feature-gate-return_type_notation.rs index fea953dcdd0..b75feb130a6 100644 --- a/tests/ui/feature-gates/feature-gate-return_type_notation.rs +++ b/tests/ui/feature-gates/feature-gate-return_type_notation.rs @@ -1,4 +1,5 @@ // edition: 2021 +// revisions: cfg no #![feature(async_fn_in_trait)] //~^ WARN the feature `async_fn_in_trait` is incomplete @@ -7,9 +8,8 @@ trait Trait { async fn m(); } -fn foo>() {} -//~^ ERROR parenthesized generic arguments cannot be used in associated type constraints -//~| ERROR associated type `m` not found for `Trait` -//~| ERROR return type notation is unstable +#[cfg(cfg)] +fn foo>() {} +//~^ ERROR return type notation is experimental fn main() {} diff --git a/tests/ui/feature-gates/feature-gate-return_type_notation.stderr b/tests/ui/feature-gates/feature-gate-return_type_notation.stderr deleted file mode 100644 index a9373482e5a..00000000000 --- a/tests/ui/feature-gates/feature-gate-return_type_notation.stderr +++ /dev/null @@ -1,36 +0,0 @@ -error[E0658]: return type notation is unstable - --> $DIR/feature-gate-return_type_notation.rs:10:17 - | -LL | fn foo>() {} - | ^^^^^^^^^ - | - = note: see issue #109417 for more information - = help: add `#![feature(return_type_notation)]` to the crate attributes to enable - -warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/feature-gate-return_type_notation.rs:3:12 - | -LL | #![feature(async_fn_in_trait)] - | ^^^^^^^^^^^^^^^^^ - | - = note: see issue #91611 for more information - = note: `#[warn(incomplete_features)]` on by default - -error: parenthesized generic arguments cannot be used in associated type constraints - --> $DIR/feature-gate-return_type_notation.rs:10:17 - | -LL | fn foo>() {} - | ^-- - | | - | help: remove these parentheses - -error[E0220]: associated type `m` not found for `Trait` - --> $DIR/feature-gate-return_type_notation.rs:10:17 - | -LL | fn foo>() {} - | ^ associated type `m` not found - -error: aborting due to 3 previous errors; 1 warning emitted - -Some errors have detailed explanations: E0220, E0658. -For more information about an error, try `rustc --explain E0220`. From 1354a38afd7c7183e4e7f5f17bef7fccfc4d2a06 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Tue, 28 Mar 2023 10:49:35 +0900 Subject: [PATCH 205/346] Document the heuristics IsTerminal uses on Windows --- library/std/src/io/stdio.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs index 0455a00956e..7c1bf488a21 100644 --- a/library/std/src/io/stdio.rs +++ b/library/std/src/io/stdio.rs @@ -1054,6 +1054,10 @@ pub trait IsTerminal: crate::sealed::Sealed { /// On platforms where Rust does not know how to detect a terminal yet, this will return /// `false`. This will also return `false` if an unexpected error occurred, such as from /// passing an invalid file descriptor. + /// + /// On Windows, in addition to detecting consoles, this currently uses some heuristics to + /// detect older msys/cygwin/mingw pseudo-terminals based on device name: devices with names + /// starting with `msys-` or `cygwin-` and ending in `-pty` will be considered terminals. fn is_terminal(&self) -> bool; } From e3b0a728b4aa886fcb451b2a3bd7662942a5acaa Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 18 Mar 2023 19:05:49 +0000 Subject: [PATCH 206/346] Erase impl regions when checking for impossible to eagerly monomorphize items --- compiler/rustc_monomorphize/src/collector.rs | 48 ++++++++++++-------- tests/ui/codegen/mono-impossible-2.rs | 19 ++++++++ 2 files changed, 48 insertions(+), 19 deletions(-) create mode 100644 tests/ui/codegen/mono-impossible-2.rs diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index aff27e5664b..c286046fb67 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1326,27 +1326,40 @@ fn create_mono_items_for_default_impls<'tcx>( return; } + let Some(trait_ref) = tcx.impl_trait_ref(item.owner_id) else { + return; + }; + + // Lifetimes never affect trait selection, so we are allowed to eagerly + // instantiate an instance of an impl method if the impl (and method, + // which we check below) is only parameterized over lifetime. In that case, + // we use the ReErased, which has no lifetime information associated with + // it, to validate whether or not the impl is legal to instantiate at all. + let only_region_params = |param: &ty::GenericParamDef, _: &_| match param.kind { + GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(), + GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => { + unreachable!( + "`own_requires_monomorphization` check means that \ + we should have no type/const params" + ) + } + }; + let impl_substs = InternalSubsts::for_item(tcx, item.owner_id.to_def_id(), only_region_params); + let trait_ref = trait_ref.subst(tcx, impl_substs); + // Unlike 'lazy' monomorphization that begins by collecting items transitively // called by `main` or other global items, when eagerly monomorphizing impl // items, we never actually check that the predicates of this impl are satisfied // in a empty reveal-all param env (i.e. with no assumptions). // - // Even though this impl has no substitutions, because we don't consider higher- - // ranked predicates such as `for<'a> &'a mut [u8]: Copy` to be trivially false, - // we must now check that the impl has no impossible-to-satisfy predicates. - if tcx.subst_and_check_impossible_predicates(( - item.owner_id.to_def_id(), - &InternalSubsts::identity_for_item(tcx, item.owner_id.to_def_id()), - )) { + // Even though this impl has no type or const substitutions, because we don't + // consider higher-ranked predicates such as `for<'a> &'a mut [u8]: Copy` to + // be trivially false. We must now check that the impl has no impossible-to-satisfy + // predicates. + if tcx.subst_and_check_impossible_predicates((item.owner_id.to_def_id(), impl_substs)) { return; } - let Some(trait_ref) = tcx.impl_trait_ref(item.owner_id) else { - return; - }; - - let trait_ref = trait_ref.subst_identity(); - let param_env = ty::ParamEnv::reveal_all(); let trait_ref = tcx.normalize_erasing_regions(param_env, trait_ref); let overridden_methods = tcx.impl_item_implementor_ids(item.owner_id); @@ -1359,12 +1372,9 @@ fn create_mono_items_for_default_impls<'tcx>( continue; } - let substs = InternalSubsts::for_item(tcx, method.def_id, |param, _| match param.kind { - GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(), - GenericParamDefKind::Type { .. } | GenericParamDefKind::Const { .. } => { - trait_ref.substs[param.index as usize] - } - }); + // As mentioned above, the method is legal to eagerly instantiate if it + // only has lifetime substitutions. This is validated by + let substs = trait_ref.substs.extend_to(tcx, method.def_id, only_region_params); let instance = ty::Instance::expect_resolve(tcx, param_env, method.def_id, substs); let mono_item = create_fn_mono_item(tcx, instance, DUMMY_SP); diff --git a/tests/ui/codegen/mono-impossible-2.rs b/tests/ui/codegen/mono-impossible-2.rs new file mode 100644 index 00000000000..21eb2c9b2f2 --- /dev/null +++ b/tests/ui/codegen/mono-impossible-2.rs @@ -0,0 +1,19 @@ +//compile-flags: --crate-type=lib -Clink-dead-code=on +// build-pass + +// Make sure that we don't monomorphize the impossible method `<() as Visit>::visit`, +// which does not hold under a reveal-all param env. + +pub trait Visit { + fn visit() {} +} + +pub trait Array { + type Element; +} + +impl<'a> Visit for () where (): Array {} + +impl Array for () { + type Element = (); +} From b38732f25c326659e860a0fac81775bd07932223 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Tue, 28 Mar 2023 11:26:43 +0900 Subject: [PATCH 207/346] Add "Platform-specific behavior" heading and link to changes disclaimer --- library/std/src/io/stdio.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs index 7c1bf488a21..1a3200a5c62 100644 --- a/library/std/src/io/stdio.rs +++ b/library/std/src/io/stdio.rs @@ -1055,9 +1055,14 @@ pub trait IsTerminal: crate::sealed::Sealed { /// `false`. This will also return `false` if an unexpected error occurred, such as from /// passing an invalid file descriptor. /// + /// # Platform-specific behavior + /// /// On Windows, in addition to detecting consoles, this currently uses some heuristics to /// detect older msys/cygwin/mingw pseudo-terminals based on device name: devices with names /// starting with `msys-` or `cygwin-` and ending in `-pty` will be considered terminals. + /// Note that this [may change in the future][changes]. + /// + /// [changes]: io#platform-specific-behavior fn is_terminal(&self) -> bool; } From 82bfdc8aaa119b5d8484ae9c95f37c43509ef796 Mon Sep 17 00:00:00 2001 From: Kai Luo Date: Tue, 28 Mar 2023 10:50:23 +0800 Subject: [PATCH 208/346] Address comment --- compiler/rustc_session/src/filesearch.rs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index 9c8a28a4a7e..5d8002b493e 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -84,7 +84,14 @@ fn current_dll_path() -> Result { #[cfg(target_os = "aix")] unsafe { - let addr = current_dll_path as u64; + // On AIX, the symbol `current_dll_path` references a function descriptor. + // A function descriptor is consisted of (See https://reviews.llvm.org/D62532) + // * The address of the entry point of the function. + // * The TOC base address for the function. + // * The environment pointer. + // Deref `current_dll_path` directly so that we can get the address of `current_dll_path`'s + // entry point in text section. + let addr = *(current_dll_path as *const u64); let mut buffer = vec![std::mem::zeroed::(); 64]; loop { if libc::loadquery( @@ -103,11 +110,9 @@ fn current_dll_path() -> Result { } let mut current = buffer.as_mut_ptr() as *mut libc::ld_info; loop { - let data_base = (*current).ldinfo_dataorg as u64; - let data_end = data_base + (*current).ldinfo_datasize; let text_base = (*current).ldinfo_textorg as u64; let text_end = text_base + (*current).ldinfo_textsize; - if (data_base <= addr && addr < data_end) || (text_base <= addr && addr < text_end) { + if (text_base..text_end).contains(&addr) { let bytes = CStr::from_ptr(&(*current).ldinfo_filename[0]).to_bytes(); let os = OsStr::from_bytes(bytes); return Ok(PathBuf::from(os)); @@ -115,7 +120,8 @@ fn current_dll_path() -> Result { if (*current).ldinfo_next == 0 { break; } - current = ((current as u64) + ((*current).ldinfo_next) as u64) as *mut libc::ld_info; + current = + (current as *mut i8).offset((*current).ldinfo_next as isize) as *mut libc::ld_info; } return Err(format!("current dll's address {} is not in the load map", addr)); } From b56fcb173bbf5ae0a52f26362639b7f2b922e7e9 Mon Sep 17 00:00:00 2001 From: Kai Luo Date: Tue, 28 Mar 2023 10:59:45 +0800 Subject: [PATCH 209/346] Set LIBPATH --- src/bootstrap/bootstrap.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 013d1ab525b..d12781cc33a 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -741,6 +741,9 @@ class RustBuild(object): env["LIBRARY_PATH"] = os.path.join(self.bin_root(), "lib") + \ (os.pathsep + env["LIBRARY_PATH"]) \ if "LIBRARY_PATH" in env else "" + env["LIBPATH"] = os.path.join(self.bin_root(), "lib") + \ + (os.pathsep + env["LIBPATH"]) \ + if "LIBPATH" in env else "" # Export Stage0 snapshot compiler related env variables build_section = "target.{}".format(self.build) From b17e6680d668d136e643976c4079c7b1cac1b6b4 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Fri, 24 Mar 2023 09:17:51 +0000 Subject: [PATCH 210/346] Move const trait bounds checks to MIR constck Fixes #109543. When checking paths in HIR typeck, we don't want to check for const predicates since all we want might just be a function pointer. Therefore we move this to MIR constck and check that bounds are met during MIR constck. --- .../src/transform/check_consts/check.rs | 51 +++---- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 32 +---- tests/ui/const-generics/issue-93647.rs | 1 + tests/ui/const-generics/issue-93647.stderr | 19 ++- .../ui/consts/const-block-const-bound.stderr | 38 ++--- .../invalid-inline-const-in-match-arm.rs | 1 + .../invalid-inline-const-in-match-arm.stderr | 19 ++- tests/ui/consts/issue-28113.rs | 1 + tests/ui/consts/issue-28113.stderr | 19 ++- tests/ui/consts/issue-56164.rs | 1 + tests/ui/consts/issue-56164.stderr | 21 ++- .../issue-68542-closure-in-array-len.rs | 1 + .../issue-68542-closure-in-array-len.stderr | 19 ++- tests/ui/never_type/issue-52443.rs | 1 + tests/ui/never_type/issue-52443.stderr | 17 ++- .../call-generic-method-nonconst.stderr | 15 +- .../const-closure-trait-method-fail.stderr | 15 +- .../const-drop-fail-2.precise.stderr | 50 +++++++ .../const-drop-fail-2.rs | 44 ++++++ .../const-drop-fail-2.stock.stderr | 50 +++++++ .../const-drop-fail.precise.stderr | 131 ++++++------------ .../const-drop-fail.rs | 29 +--- .../const-drop-fail.stock.stderr | 131 ++++++------------ .../derive-const-non-const-type.rs | 1 + .../derive-const-non-const-type.stderr | 26 +++- ...-method-body-is-const-body-checking.stderr | 13 +- ...function-pointer-does-not-require-const.rs | 15 ++ 27 files changed, 438 insertions(+), 323 deletions(-) create mode 100644 tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.precise.stderr create mode 100644 tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.rs create mode 100644 tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.stock.stderr create mode 100644 tests/ui/rfc-2632-const-trait-impl/function-pointer-does-not-require-const.rs diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 0d9cd78fe12..d6110a050f2 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -722,6 +722,32 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { } }; + // Check that all trait bounds that are marked as `~const` can be satisfied. + // + // Typeck only does a "non-const" check since it operates on HIR and cannot distinguish + // which path expressions are getting called on and which path expressions are only used + // as function pointers. This is required for correctness. + let infcx = tcx.infer_ctxt().build(); + let ocx = ObligationCtxt::new(&infcx); + + let predicates = tcx.predicates_of(callee).instantiate(tcx, substs); + let cause = ObligationCause::new( + terminator.source_info.span, + self.body.source.def_id().expect_local(), + ObligationCauseCode::ItemObligation(callee), + ); + let normalized_predicates = ocx.normalize(&cause, param_env, predicates); + ocx.register_obligations(traits::predicates_for_generics( + |_, _| cause.clone(), + self.param_env, + normalized_predicates, + )); + + let errors = ocx.select_all_or_error(); + if !errors.is_empty() { + infcx.err_ctxt().report_fulfillment_errors(&errors); + } + // Attempting to call a trait method? if let Some(trait_id) = tcx.trait_of_item(callee) { trace!("attempting to call a trait method"); @@ -749,31 +775,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { selcx.select(&obligation) }; - // do a well-formedness check on the trait method being called. This is because typeck only does a - // "non-const" check. This is required for correctness here. - { - let infcx = tcx.infer_ctxt().build(); - let ocx = ObligationCtxt::new(&infcx); - - let predicates = tcx.predicates_of(callee).instantiate(tcx, substs); - let cause = ObligationCause::new( - terminator.source_info.span, - self.body.source.def_id().expect_local(), - ObligationCauseCode::ItemObligation(callee), - ); - let normalized_predicates = ocx.normalize(&cause, param_env, predicates); - ocx.register_obligations(traits::predicates_for_generics( - |_, _| cause.clone(), - self.param_env, - normalized_predicates, - )); - - let errors = ocx.select_all_or_error(); - if !errors.is_empty() { - infcx.err_ctxt().report_fulfillment_errors(&errors); - } - } - match implsrc { Ok(Some(ImplSource::Param(_, ty::BoundConstness::ConstIfConst))) => { debug!( diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 3def97bca47..50fc48f68a4 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -1416,41 +1416,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) { let param_env = self.param_env; - let remap = match self.tcx.def_kind(def_id) { - // Associated consts have `Self: ~const Trait` bounds that should be satisfiable when - // `Self: Trait` is satisfied because it does not matter whether the impl is `const`. - // Therefore we have to remap the param env here to be non-const. - hir::def::DefKind::AssocConst => true, - hir::def::DefKind::AssocFn - if self.tcx.def_kind(self.tcx.parent(def_id)) == hir::def::DefKind::Trait => - { - // N.B.: All callsites to this function involve checking a path expression. - // - // When instantiating a trait method as a function item, it does not actually matter whether - // the trait is `const` or not, or whether `where T: ~const Tr` needs to be satisfied as - // `const`. If we were to introduce instantiating trait methods as `const fn`s, we would - // check that after this, either via a bound `where F: ~const FnOnce` or when coercing to a - // `const fn` pointer. - // - // FIXME(fee1-dead) FIXME(const_trait_impl): update this doc when trait methods can satisfy - // `~const FnOnce` or can be coerced to `const fn` pointer. - true - } - _ => false, - }; let bounds = self.instantiate_bounds(span, def_id, &substs); - for mut obligation in traits::predicates_for_generics( + for obligation in traits::predicates_for_generics( |idx, predicate_span| { traits::ObligationCause::new(span, self.body_id, code(idx, predicate_span)) }, param_env, bounds, ) { - if remap { - obligation = obligation.without_const(self.tcx); - } - self.register_predicate(obligation); + // N.B. We are remapping all predicates to non-const since we don't know if we just + // want them as function pointers or we are calling them from a const-context. The + // actual checking will occur in `rustc_const_eval::transform::check_consts`. + self.register_predicate(obligation.without_const(self.tcx)); } } diff --git a/tests/ui/const-generics/issue-93647.rs b/tests/ui/const-generics/issue-93647.rs index 806540e1775..a0083a0c629 100644 --- a/tests/ui/const-generics/issue-93647.rs +++ b/tests/ui/const-generics/issue-93647.rs @@ -1,6 +1,7 @@ struct X; fn main() {} diff --git a/tests/ui/const-generics/issue-93647.stderr b/tests/ui/const-generics/issue-93647.stderr index 18370eea571..20a6af5c549 100644 --- a/tests/ui/const-generics/issue-93647.stderr +++ b/tests/ui/const-generics/issue-93647.stderr @@ -1,3 +1,17 @@ +error[E0277]: the trait bound `[closure@$DIR/issue-93647.rs:2:6: 2:8]: Fn<()>` is not satisfied + --> $DIR/issue-93647.rs:2:5 + | +LL | (||1usize)() + | ^^^^^^^^^^^^ expected an `Fn<()>` closure, found `[closure@$DIR/issue-93647.rs:2:6: 2:8]` + | + = help: the trait `~const Fn<()>` is not implemented for closure `[closure@$DIR/issue-93647.rs:2:6: 2:8]` +note: the trait `Fn<()>` is implemented for `[closure@$DIR/issue-93647.rs:2:6: 2:8]`, but that implementation is not `const` + --> $DIR/issue-93647.rs:2:5 + | +LL | (||1usize)() + | ^^^^^^^^^^^^ + = note: wrap the `[closure@$DIR/issue-93647.rs:2:6: 2:8]` in a closure with no arguments: `|| { /* code */ }` + error[E0015]: cannot call non-const closure in constants --> $DIR/issue-93647.rs:2:5 | @@ -8,6 +22,7 @@ LL | (||1usize)() = note: calls in constants are limited to constant functions, tuple structs and tuple variants = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable -error: aborting due to previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0015`. +Some errors have detailed explanations: E0015, E0277. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/const-block-const-bound.stderr b/tests/ui/consts/const-block-const-bound.stderr index b9c4d8866bf..fef4914fad5 100644 --- a/tests/ui/consts/const-block-const-bound.stderr +++ b/tests/ui/consts/const-block-const-bound.stderr @@ -1,44 +1,30 @@ error[E0277]: can't drop `UnconstDrop` in const contexts - --> $DIR/const-block-const-bound.rs:20:11 + --> $DIR/const-block-const-bound.rs:20:9 | LL | f(UnconstDrop); - | - ^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `UnconstDrop` - | | - | required by a bound introduced by this call + | ^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `UnconstDrop` | = note: the trait bound `UnconstDrop: ~const Destruct` is not satisfied -note: required by a bound in `f` - --> $DIR/const-block-const-bound.rs:6:15 - | -LL | const fn f(x: T) {} - | ^^^^^^^^^^^^^^^ required by this bound in `f` help: consider borrowing here | -LL | f(&UnconstDrop); - | + -LL | f(&mut UnconstDrop); - | ++++ +LL | &f(UnconstDrop); + | + +LL | &mut f(UnconstDrop); + | ++++ error[E0277]: can't drop `NonDrop` in const contexts - --> $DIR/const-block-const-bound.rs:22:11 + --> $DIR/const-block-const-bound.rs:22:9 | LL | f(NonDrop); - | - ^^^^^^^ the trait `~const Destruct` is not implemented for `NonDrop` - | | - | required by a bound introduced by this call + | ^^^^^^^^^^ the trait `~const Destruct` is not implemented for `NonDrop` | = note: the trait bound `NonDrop: ~const Destruct` is not satisfied -note: required by a bound in `f` - --> $DIR/const-block-const-bound.rs:6:15 - | -LL | const fn f(x: T) {} - | ^^^^^^^^^^^^^^^ required by this bound in `f` help: consider borrowing here | -LL | f(&NonDrop); - | + -LL | f(&mut NonDrop); - | ++++ +LL | &f(NonDrop); + | + +LL | &mut f(NonDrop); + | ++++ error: aborting due to 2 previous errors diff --git a/tests/ui/consts/invalid-inline-const-in-match-arm.rs b/tests/ui/consts/invalid-inline-const-in-match-arm.rs index 4d2d8fb1303..17acb2d9d17 100644 --- a/tests/ui/consts/invalid-inline-const-in-match-arm.rs +++ b/tests/ui/consts/invalid-inline-const-in-match-arm.rs @@ -5,5 +5,6 @@ fn main() { match () { const { (|| {})() } => {} //~^ ERROR cannot call non-const closure in constants + //~| ERROR the trait bound } } diff --git a/tests/ui/consts/invalid-inline-const-in-match-arm.stderr b/tests/ui/consts/invalid-inline-const-in-match-arm.stderr index 257ecd7f3cf..ac174849f06 100644 --- a/tests/ui/consts/invalid-inline-const-in-match-arm.stderr +++ b/tests/ui/consts/invalid-inline-const-in-match-arm.stderr @@ -1,3 +1,17 @@ +error[E0277]: the trait bound `[closure@$DIR/invalid-inline-const-in-match-arm.rs:6:18: 6:20]: Fn<()>` is not satisfied + --> $DIR/invalid-inline-const-in-match-arm.rs:6:17 + | +LL | const { (|| {})() } => {} + | ^^^^^^^^^ expected an `Fn<()>` closure, found `[closure@$DIR/invalid-inline-const-in-match-arm.rs:6:18: 6:20]` + | + = help: the trait `~const Fn<()>` is not implemented for closure `[closure@$DIR/invalid-inline-const-in-match-arm.rs:6:18: 6:20]` +note: the trait `Fn<()>` is implemented for `[closure@$DIR/invalid-inline-const-in-match-arm.rs:6:18: 6:20]`, but that implementation is not `const` + --> $DIR/invalid-inline-const-in-match-arm.rs:6:17 + | +LL | const { (|| {})() } => {} + | ^^^^^^^^^ + = note: wrap the `[closure@$DIR/invalid-inline-const-in-match-arm.rs:6:18: 6:20]` in a closure with no arguments: `|| { /* code */ }` + error[E0015]: cannot call non-const closure in constants --> $DIR/invalid-inline-const-in-match-arm.rs:6:17 | @@ -8,6 +22,7 @@ LL | const { (|| {})() } => {} = note: calls in constants are limited to constant functions, tuple structs and tuple variants = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable -error: aborting due to previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0015`. +Some errors have detailed explanations: E0015, E0277. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/issue-28113.rs b/tests/ui/consts/issue-28113.rs index f8131c9f3b7..e45c009d69f 100644 --- a/tests/ui/consts/issue-28113.rs +++ b/tests/ui/consts/issue-28113.rs @@ -3,6 +3,7 @@ const X: u8 = || -> u8 { 5 }() //~^ ERROR cannot call non-const closure + //~| ERROR the trait bound ; fn main() {} diff --git a/tests/ui/consts/issue-28113.stderr b/tests/ui/consts/issue-28113.stderr index 1294cc99bf7..e177a3585c4 100644 --- a/tests/ui/consts/issue-28113.stderr +++ b/tests/ui/consts/issue-28113.stderr @@ -1,3 +1,17 @@ +error[E0277]: the trait bound `[closure@$DIR/issue-28113.rs:4:5: 4:13]: Fn<()>` is not satisfied + --> $DIR/issue-28113.rs:4:5 + | +LL | || -> u8 { 5 }() + | ^^^^^^^^^^^^^^^^ expected an `Fn<()>` closure, found `[closure@$DIR/issue-28113.rs:4:5: 4:13]` + | + = help: the trait `~const Fn<()>` is not implemented for closure `[closure@$DIR/issue-28113.rs:4:5: 4:13]` +note: the trait `Fn<()>` is implemented for `[closure@$DIR/issue-28113.rs:4:5: 4:13]`, but that implementation is not `const` + --> $DIR/issue-28113.rs:4:5 + | +LL | || -> u8 { 5 }() + | ^^^^^^^^^^^^^^^^ + = note: wrap the `[closure@$DIR/issue-28113.rs:4:5: 4:13]` in a closure with no arguments: `|| { /* code */ }` + error[E0015]: cannot call non-const closure in constants --> $DIR/issue-28113.rs:4:5 | @@ -8,6 +22,7 @@ LL | || -> u8 { 5 }() = note: calls in constants are limited to constant functions, tuple structs and tuple variants = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable -error: aborting due to previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0015`. +Some errors have detailed explanations: E0015, E0277. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/issue-56164.rs b/tests/ui/consts/issue-56164.rs index 22c257d0b08..00875c4b582 100644 --- a/tests/ui/consts/issue-56164.rs +++ b/tests/ui/consts/issue-56164.rs @@ -1,5 +1,6 @@ const fn foo() { (||{})() } //~^ ERROR cannot call non-const closure +//~| ERROR the trait bound const fn bad(input: fn()) { input() diff --git a/tests/ui/consts/issue-56164.stderr b/tests/ui/consts/issue-56164.stderr index 845b23d5d87..003f8474463 100644 --- a/tests/ui/consts/issue-56164.stderr +++ b/tests/ui/consts/issue-56164.stderr @@ -1,3 +1,17 @@ +error[E0277]: the trait bound `[closure@$DIR/issue-56164.rs:1:19: 1:21]: Fn<()>` is not satisfied + --> $DIR/issue-56164.rs:1:18 + | +LL | const fn foo() { (||{})() } + | ^^^^^^^^ expected an `Fn<()>` closure, found `[closure@$DIR/issue-56164.rs:1:19: 1:21]` + | + = help: the trait `~const Fn<()>` is not implemented for closure `[closure@$DIR/issue-56164.rs:1:19: 1:21]` +note: the trait `Fn<()>` is implemented for `[closure@$DIR/issue-56164.rs:1:19: 1:21]`, but that implementation is not `const` + --> $DIR/issue-56164.rs:1:18 + | +LL | const fn foo() { (||{})() } + | ^^^^^^^^ + = note: wrap the `[closure@$DIR/issue-56164.rs:1:19: 1:21]` in a closure with no arguments: `|| { /* code */ }` + error[E0015]: cannot call non-const closure in constant functions --> $DIR/issue-56164.rs:1:18 | @@ -9,7 +23,7 @@ LL | const fn foo() { (||{})() } = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable error: function pointer calls are not allowed in constant functions - --> $DIR/issue-56164.rs:5:5 + --> $DIR/issue-56164.rs:6:5 | LL | input() | ^^^^^^^ @@ -26,6 +40,7 @@ note: erroneous constant used LL | const fn foo() { (||{})() } | ^^^^^^ -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0015`. +Some errors have detailed explanations: E0015, E0277. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/consts/issue-68542-closure-in-array-len.rs b/tests/ui/consts/issue-68542-closure-in-array-len.rs index 37958e7919d..a88e0cc6017 100644 --- a/tests/ui/consts/issue-68542-closure-in-array-len.rs +++ b/tests/ui/consts/issue-68542-closure-in-array-len.rs @@ -4,6 +4,7 @@ struct Bug { a: [(); (|| { 0 })()] //~ ERROR cannot call non-const closure + //~^ ERROR the trait bound } fn main() {} diff --git a/tests/ui/consts/issue-68542-closure-in-array-len.stderr b/tests/ui/consts/issue-68542-closure-in-array-len.stderr index d23513ed7ff..ace62f09d05 100644 --- a/tests/ui/consts/issue-68542-closure-in-array-len.stderr +++ b/tests/ui/consts/issue-68542-closure-in-array-len.stderr @@ -1,3 +1,17 @@ +error[E0277]: the trait bound `[closure@$DIR/issue-68542-closure-in-array-len.rs:6:14: 6:16]: Fn<()>` is not satisfied + --> $DIR/issue-68542-closure-in-array-len.rs:6:13 + | +LL | a: [(); (|| { 0 })()] + | ^^^^^^^^^^^^ expected an `Fn<()>` closure, found `[closure@$DIR/issue-68542-closure-in-array-len.rs:6:14: 6:16]` + | + = help: the trait `~const Fn<()>` is not implemented for closure `[closure@$DIR/issue-68542-closure-in-array-len.rs:6:14: 6:16]` +note: the trait `Fn<()>` is implemented for `[closure@$DIR/issue-68542-closure-in-array-len.rs:6:14: 6:16]`, but that implementation is not `const` + --> $DIR/issue-68542-closure-in-array-len.rs:6:13 + | +LL | a: [(); (|| { 0 })()] + | ^^^^^^^^^^^^ + = note: wrap the `[closure@$DIR/issue-68542-closure-in-array-len.rs:6:14: 6:16]` in a closure with no arguments: `|| { /* code */ }` + error[E0015]: cannot call non-const closure in constants --> $DIR/issue-68542-closure-in-array-len.rs:6:13 | @@ -8,6 +22,7 @@ LL | a: [(); (|| { 0 })()] = note: calls in constants are limited to constant functions, tuple structs and tuple variants = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable -error: aborting due to previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0015`. +Some errors have detailed explanations: E0015, E0277. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/never_type/issue-52443.rs b/tests/ui/never_type/issue-52443.rs index 0498a8a1625..4669d7c1a35 100644 --- a/tests/ui/never_type/issue-52443.rs +++ b/tests/ui/never_type/issue-52443.rs @@ -11,4 +11,5 @@ fn main() { //~| ERROR cannot convert //~| ERROR mutable references //~| ERROR cannot call + //~| ERROR the trait bound } diff --git a/tests/ui/never_type/issue-52443.stderr b/tests/ui/never_type/issue-52443.stderr index 99dfce86903..1233bdc5d1f 100644 --- a/tests/ui/never_type/issue-52443.stderr +++ b/tests/ui/never_type/issue-52443.stderr @@ -58,6 +58,19 @@ LL | [(); { for _ in 0usize.. {}; 0}]; = note: see issue #57349 for more information = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable +error[E0277]: the trait bound `RangeFrom: Iterator` is not satisfied + --> $DIR/issue-52443.rs:9:21 + | +LL | [(); { for _ in 0usize.. {}; 0}]; + | ^^^^^^^^ `RangeFrom` is not an iterator + | + = help: the trait `~const Iterator` is not implemented for `RangeFrom` +note: the trait `Iterator` is implemented for `RangeFrom`, but that implementation is not `const` + --> $DIR/issue-52443.rs:9:21 + | +LL | [(); { for _ in 0usize.. {}; 0}]; + | ^^^^^^^^ + error[E0015]: cannot call non-const fn ` as Iterator>::next` in constants --> $DIR/issue-52443.rs:9:21 | @@ -67,7 +80,7 @@ LL | [(); { for _ in 0usize.. {}; 0}]; = note: calls in constants are limited to constant functions, tuple structs and tuple variants = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable -error: aborting due to 6 previous errors; 1 warning emitted +error: aborting due to 7 previous errors; 1 warning emitted -Some errors have detailed explanations: E0015, E0308, E0658. +Some errors have detailed explanations: E0015, E0277, E0308, E0658. For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr index 706f5234365..a28d6ce05a7 100644 --- a/tests/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/call-generic-method-nonconst.stderr @@ -1,21 +1,14 @@ error[E0277]: the trait bound `S: ~const Foo` is not satisfied - --> $DIR/call-generic-method-nonconst.rs:23:34 + --> $DIR/call-generic-method-nonconst.rs:23:22 | LL | pub const EQ: bool = equals_self(&S); - | ----------- ^^ the trait `~const Foo` is not implemented for `S` - | | - | required by a bound introduced by this call + | ^^^^^^^^^^^^^^^ the trait `~const Foo` is not implemented for `S` | note: the trait `Foo` is implemented for `S`, but that implementation is not `const` - --> $DIR/call-generic-method-nonconst.rs:23:34 + --> $DIR/call-generic-method-nonconst.rs:23:22 | LL | pub const EQ: bool = equals_self(&S); - | ^^ -note: required by a bound in `equals_self` - --> $DIR/call-generic-method-nonconst.rs:16:25 - | -LL | const fn equals_self(t: &T) -> bool { - | ^^^^^^^^^^ required by this bound in `equals_self` + | ^^^^^^^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr b/tests/ui/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr index 4470e287cc3..ffc24ec6e92 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr @@ -1,22 +1,15 @@ error[E0277]: the trait bound `(): ~const Tr` is not satisfied in `fn(()) -> i32 {<() as Tr>::a}` - --> $DIR/const-closure-trait-method-fail.rs:16:42 + --> $DIR/const-closure-trait-method-fail.rs:16:23 | LL | const _: () = assert!(need_const_closure(Tr::a) == 42); - | ------------------ ^^^^^ within `fn(()) -> i32 {<() as Tr>::a}`, the trait `~const Tr` is not implemented for `()` - | | - | required by a bound introduced by this call + | ^^^^^^^^^^^^^^^^^^^^^^^^^ within `fn(()) -> i32 {<() as Tr>::a}`, the trait `~const Tr` is not implemented for `()` | note: the trait `Tr` is implemented for `()`, but that implementation is not `const` - --> $DIR/const-closure-trait-method-fail.rs:16:42 + --> $DIR/const-closure-trait-method-fail.rs:16:23 | LL | const _: () = assert!(need_const_closure(Tr::a) == 42); - | ^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^ = note: required because it appears within the type `fn(()) -> i32 {<() as Tr>::a}` -note: required by a bound in `need_const_closure` - --> $DIR/const-closure-trait-method-fail.rs:12:32 - | -LL | const fn need_const_closure i32>(x: T) -> i32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `need_const_closure` error: aborting due to previous error diff --git a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.precise.stderr b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.precise.stderr new file mode 100644 index 00000000000..dd35501faec --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.precise.stderr @@ -0,0 +1,50 @@ +error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied + --> $DIR/const-drop-fail-2.rs:31:23 + | +LL | const _: () = check::>(ConstDropImplWithBounds(PhantomData)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop` + | +note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const` + --> $DIR/const-drop-fail-2.rs:31:23 + | +LL | const _: () = check::>(ConstDropImplWithBounds(PhantomData)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `ConstDropImplWithBounds` + --> $DIR/const-drop-fail-2.rs:21:35 + | +LL | struct ConstDropImplWithBounds(PhantomData); + | ^^^^^^^^ required by this bound in `ConstDropImplWithBounds` + +error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied + --> $DIR/const-drop-fail-2.rs:31:64 + | +LL | const _: () = check::>(ConstDropImplWithBounds(PhantomData)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop` + | +note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const` + --> $DIR/const-drop-fail-2.rs:31:64 + | +LL | const _: () = check::>(ConstDropImplWithBounds(PhantomData)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `ConstDropImplWithBounds` + --> $DIR/const-drop-fail-2.rs:21:35 + | +LL | struct ConstDropImplWithBounds(PhantomData); + | ^^^^^^^^ required by this bound in `ConstDropImplWithBounds` + +error[E0367]: `Drop` impl requires `T: ~const A` but the struct it is implemented for does not + --> $DIR/const-drop-fail-2.rs:37:9 + | +LL | impl const Drop for ConstDropImplWithNonConstBounds { + | ^^^^^^^^ + | +note: the implementor must specify the same requirement + --> $DIR/const-drop-fail-2.rs:35:1 + | +LL | struct ConstDropImplWithNonConstBounds(PhantomData); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0277, E0367. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.rs b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.rs new file mode 100644 index 00000000000..8d7212dfe70 --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.rs @@ -0,0 +1,44 @@ +// revisions: stock precise +#![feature(const_trait_impl)] +#![feature(const_mut_refs)] +#![cfg_attr(precise, feature(const_precise_live_drops))] + +use std::marker::{Destruct, PhantomData}; + +struct NonTrivialDrop; + +impl Drop for NonTrivialDrop { + fn drop(&mut self) { + println!("Non trivial drop"); + } +} + +#[const_trait] +trait A { fn a() { } } + +impl A for NonTrivialDrop {} + +struct ConstDropImplWithBounds(PhantomData); + +impl const Drop for ConstDropImplWithBounds { + fn drop(&mut self) { + T::a(); + } +} + +const fn check(_: T) {} + +const _: () = check::>(ConstDropImplWithBounds(PhantomData)); +//~^ ERROR the trait bound +//~| ERROR the trait bound + +struct ConstDropImplWithNonConstBounds(PhantomData); + +impl const Drop for ConstDropImplWithNonConstBounds { +//~^ ERROR `Drop` impl requires `T: ~const A` but the struct it is implemented for does not + fn drop(&mut self) { + T::a(); + } +} + +fn main() {} diff --git a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.stock.stderr b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.stock.stderr new file mode 100644 index 00000000000..dd35501faec --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.stock.stderr @@ -0,0 +1,50 @@ +error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied + --> $DIR/const-drop-fail-2.rs:31:23 + | +LL | const _: () = check::>(ConstDropImplWithBounds(PhantomData)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop` + | +note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const` + --> $DIR/const-drop-fail-2.rs:31:23 + | +LL | const _: () = check::>(ConstDropImplWithBounds(PhantomData)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `ConstDropImplWithBounds` + --> $DIR/const-drop-fail-2.rs:21:35 + | +LL | struct ConstDropImplWithBounds(PhantomData); + | ^^^^^^^^ required by this bound in `ConstDropImplWithBounds` + +error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied + --> $DIR/const-drop-fail-2.rs:31:64 + | +LL | const _: () = check::>(ConstDropImplWithBounds(PhantomData)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop` + | +note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const` + --> $DIR/const-drop-fail-2.rs:31:64 + | +LL | const _: () = check::>(ConstDropImplWithBounds(PhantomData)); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: required by a bound in `ConstDropImplWithBounds` + --> $DIR/const-drop-fail-2.rs:21:35 + | +LL | struct ConstDropImplWithBounds(PhantomData); + | ^^^^^^^^ required by this bound in `ConstDropImplWithBounds` + +error[E0367]: `Drop` impl requires `T: ~const A` but the struct it is implemented for does not + --> $DIR/const-drop-fail-2.rs:37:9 + | +LL | impl const Drop for ConstDropImplWithNonConstBounds { + | ^^^^^^^^ + | +note: the implementor must specify the same requirement + --> $DIR/const-drop-fail-2.rs:35:1 + | +LL | struct ConstDropImplWithNonConstBounds(PhantomData); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0277, E0367. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr index 796c0d388ea..40caada51d7 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.precise.stderr @@ -1,99 +1,58 @@ error[E0277]: can't drop `NonTrivialDrop` in const contexts - --> $DIR/const-drop-fail.rs:44:5 + --> $DIR/const-drop-fail.rs:26:23 | -LL | const _: () = check($exp); - | ----- required by a bound introduced by this call +LL | const _: () = check($exp); + | ^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `NonTrivialDrop` ... -LL | NonTrivialDrop, - | ^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `NonTrivialDrop` - | - = note: the trait bound `NonTrivialDrop: ~const Destruct` is not satisfied -note: required by a bound in `check` - --> $DIR/const-drop-fail.rs:35:19 - | -LL | const fn check(_: T) {} - | ^^^^^^^^^^^^^^^ required by this bound in `check` -help: consider borrowing here - | -LL | &NonTrivialDrop, - | + -LL | &mut NonTrivialDrop, - | ++++ - -error[E0277]: can't drop `NonTrivialDrop` in const contexts - --> $DIR/const-drop-fail.rs:46:5 - | -LL | const _: () = check($exp); - | ----- required by a bound introduced by this call -... -LL | ConstImplWithDropGlue(NonTrivialDrop), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Destruct` is not implemented for `NonTrivialDrop` +LL | / check_all! { +LL | | NonTrivialDrop, +LL | | ConstImplWithDropGlue(NonTrivialDrop), +LL | | } + | |_- in this macro invocation | note: the trait `Destruct` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail.rs:46:5 + --> $DIR/const-drop-fail.rs:26:23 | -LL | ConstImplWithDropGlue(NonTrivialDrop), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const _: () = check($exp); + | ^^^^^^^^^^^ +... +LL | / check_all! { +LL | | NonTrivialDrop, +LL | | ConstImplWithDropGlue(NonTrivialDrop), +LL | | } + | |_- in this macro invocation + = note: this error originates in the macro `check_all` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: can't drop `NonTrivialDrop` in const contexts + --> $DIR/const-drop-fail.rs:26:23 + | +LL | const _: () = check($exp); + | ^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Destruct` is not implemented for `NonTrivialDrop` +... +LL | / check_all! { +LL | | NonTrivialDrop, +LL | | ConstImplWithDropGlue(NonTrivialDrop), +LL | | } + | |_- in this macro invocation + | +note: the trait `Destruct` is implemented for `NonTrivialDrop`, but that implementation is not `const` + --> $DIR/const-drop-fail.rs:26:23 + | +LL | const _: () = check($exp); + | ^^^^^^^^^^^ +... +LL | / check_all! { +LL | | NonTrivialDrop, +LL | | ConstImplWithDropGlue(NonTrivialDrop), +LL | | } + | |_- in this macro invocation note: required because it appears within the type `ConstImplWithDropGlue` --> $DIR/const-drop-fail.rs:16:8 | LL | struct ConstImplWithDropGlue(NonTrivialDrop); | ^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `check` - --> $DIR/const-drop-fail.rs:35:19 - | -LL | const fn check(_: T) {} - | ^^^^^^^^^^^^^^^ required by this bound in `check` + = note: this error originates in the macro `check_all` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied - --> $DIR/const-drop-fail.rs:48:47 - | -LL | ConstDropImplWithBounds::(PhantomData), - | ----------------------------------------- ^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop` - | | - | required by a bound introduced by this call - | -note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail.rs:48:47 - | -LL | ConstDropImplWithBounds::(PhantomData), - | ^^^^^^^^^^^ -note: required by a bound in `ConstDropImplWithBounds` - --> $DIR/const-drop-fail.rs:27:35 - | -LL | struct ConstDropImplWithBounds(PhantomData); - | ^^^^^^^^ required by this bound in `ConstDropImplWithBounds` +error: aborting due to 2 previous errors -error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied - --> $DIR/const-drop-fail.rs:48:5 - | -LL | ConstDropImplWithBounds::(PhantomData), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop` - | -note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail.rs:48:5 - | -LL | ConstDropImplWithBounds::(PhantomData), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `ConstDropImplWithBounds` - --> $DIR/const-drop-fail.rs:27:35 - | -LL | struct ConstDropImplWithBounds(PhantomData); - | ^^^^^^^^ required by this bound in `ConstDropImplWithBounds` - -error[E0367]: `Drop` impl requires `T: ~const A` but the struct it is implemented for does not - --> $DIR/const-drop-fail.rs:55:9 - | -LL | impl const Drop for ConstDropImplWithNonConstBounds { - | ^^^^^^^^ - | -note: the implementor must specify the same requirement - --> $DIR/const-drop-fail.rs:53:1 - | -LL | struct ConstDropImplWithNonConstBounds(PhantomData); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 5 previous errors - -Some errors have detailed explanations: E0277, E0367. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.rs b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.rs index d36c7f81ced..c4bdb9ef5e5 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.rs +++ b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.rs @@ -19,44 +19,19 @@ impl const Drop for ConstImplWithDropGlue { fn drop(&mut self) {} } -#[const_trait] -trait A { fn a() { } } - -impl A for NonTrivialDrop {} - -struct ConstDropImplWithBounds(PhantomData); - -impl const Drop for ConstDropImplWithBounds { - fn drop(&mut self) { - T::a(); - } -} - const fn check(_: T) {} macro_rules! check_all { ($($exp:expr),*$(,)?) => {$( const _: () = check($exp); + //~^ ERROR can't drop + //~| ERROR can't drop )*}; } check_all! { NonTrivialDrop, - //~^ ERROR can't drop ConstImplWithDropGlue(NonTrivialDrop), - //~^ ERROR can't drop - ConstDropImplWithBounds::(PhantomData), - //~^ ERROR the trait bound - //~| ERROR the trait bound -} - -struct ConstDropImplWithNonConstBounds(PhantomData); - -impl const Drop for ConstDropImplWithNonConstBounds { -//~^ ERROR `Drop` impl requires `T: ~const A` but the struct it is implemented for does not - fn drop(&mut self) { - T::a(); - } } fn main() {} diff --git a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr index 796c0d388ea..40caada51d7 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail.stock.stderr @@ -1,99 +1,58 @@ error[E0277]: can't drop `NonTrivialDrop` in const contexts - --> $DIR/const-drop-fail.rs:44:5 + --> $DIR/const-drop-fail.rs:26:23 | -LL | const _: () = check($exp); - | ----- required by a bound introduced by this call +LL | const _: () = check($exp); + | ^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `NonTrivialDrop` ... -LL | NonTrivialDrop, - | ^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `NonTrivialDrop` - | - = note: the trait bound `NonTrivialDrop: ~const Destruct` is not satisfied -note: required by a bound in `check` - --> $DIR/const-drop-fail.rs:35:19 - | -LL | const fn check(_: T) {} - | ^^^^^^^^^^^^^^^ required by this bound in `check` -help: consider borrowing here - | -LL | &NonTrivialDrop, - | + -LL | &mut NonTrivialDrop, - | ++++ - -error[E0277]: can't drop `NonTrivialDrop` in const contexts - --> $DIR/const-drop-fail.rs:46:5 - | -LL | const _: () = check($exp); - | ----- required by a bound introduced by this call -... -LL | ConstImplWithDropGlue(NonTrivialDrop), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Destruct` is not implemented for `NonTrivialDrop` +LL | / check_all! { +LL | | NonTrivialDrop, +LL | | ConstImplWithDropGlue(NonTrivialDrop), +LL | | } + | |_- in this macro invocation | note: the trait `Destruct` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail.rs:46:5 + --> $DIR/const-drop-fail.rs:26:23 | -LL | ConstImplWithDropGlue(NonTrivialDrop), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | const _: () = check($exp); + | ^^^^^^^^^^^ +... +LL | / check_all! { +LL | | NonTrivialDrop, +LL | | ConstImplWithDropGlue(NonTrivialDrop), +LL | | } + | |_- in this macro invocation + = note: this error originates in the macro `check_all` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: can't drop `NonTrivialDrop` in const contexts + --> $DIR/const-drop-fail.rs:26:23 + | +LL | const _: () = check($exp); + | ^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Destruct` is not implemented for `NonTrivialDrop` +... +LL | / check_all! { +LL | | NonTrivialDrop, +LL | | ConstImplWithDropGlue(NonTrivialDrop), +LL | | } + | |_- in this macro invocation + | +note: the trait `Destruct` is implemented for `NonTrivialDrop`, but that implementation is not `const` + --> $DIR/const-drop-fail.rs:26:23 + | +LL | const _: () = check($exp); + | ^^^^^^^^^^^ +... +LL | / check_all! { +LL | | NonTrivialDrop, +LL | | ConstImplWithDropGlue(NonTrivialDrop), +LL | | } + | |_- in this macro invocation note: required because it appears within the type `ConstImplWithDropGlue` --> $DIR/const-drop-fail.rs:16:8 | LL | struct ConstImplWithDropGlue(NonTrivialDrop); | ^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `check` - --> $DIR/const-drop-fail.rs:35:19 - | -LL | const fn check(_: T) {} - | ^^^^^^^^^^^^^^^ required by this bound in `check` + = note: this error originates in the macro `check_all` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied - --> $DIR/const-drop-fail.rs:48:47 - | -LL | ConstDropImplWithBounds::(PhantomData), - | ----------------------------------------- ^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop` - | | - | required by a bound introduced by this call - | -note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail.rs:48:47 - | -LL | ConstDropImplWithBounds::(PhantomData), - | ^^^^^^^^^^^ -note: required by a bound in `ConstDropImplWithBounds` - --> $DIR/const-drop-fail.rs:27:35 - | -LL | struct ConstDropImplWithBounds(PhantomData); - | ^^^^^^^^ required by this bound in `ConstDropImplWithBounds` +error: aborting due to 2 previous errors -error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied - --> $DIR/const-drop-fail.rs:48:5 - | -LL | ConstDropImplWithBounds::(PhantomData), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop` - | -note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail.rs:48:5 - | -LL | ConstDropImplWithBounds::(PhantomData), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: required by a bound in `ConstDropImplWithBounds` - --> $DIR/const-drop-fail.rs:27:35 - | -LL | struct ConstDropImplWithBounds(PhantomData); - | ^^^^^^^^ required by this bound in `ConstDropImplWithBounds` - -error[E0367]: `Drop` impl requires `T: ~const A` but the struct it is implemented for does not - --> $DIR/const-drop-fail.rs:55:9 - | -LL | impl const Drop for ConstDropImplWithNonConstBounds { - | ^^^^^^^^ - | -note: the implementor must specify the same requirement - --> $DIR/const-drop-fail.rs:53:1 - | -LL | struct ConstDropImplWithNonConstBounds(PhantomData); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 5 previous errors - -Some errors have detailed explanations: E0277, E0367. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs index 92843a8a2da..ed6699f3724 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs +++ b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.rs @@ -9,5 +9,6 @@ impl Default for A { #[derive_const(Default)] pub struct S(A); //~^ cannot call non-const fn +//~| the trait bound fn main() {} diff --git a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr index 96e0c78b9c7..6b6c578bff8 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/const_derives/derive-const-non-const-type.stderr @@ -1,3 +1,24 @@ +error[E0277]: the trait bound `A: Default` is not satisfied + --> $DIR/derive-const-non-const-type.rs:10:14 + | +LL | #[derive_const(Default)] + | ------- in this derive macro expansion +LL | pub struct S(A); + | ^ the trait `~const Default` is not implemented for `A` + | +note: the trait `Default` is implemented for `A`, but that implementation is not `const` + --> $DIR/derive-const-non-const-type.rs:10:14 + | +LL | #[derive_const(Default)] + | ------- in this derive macro expansion +LL | pub struct S(A); + | ^ + = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider annotating `A` with `#[derive(Default)]` + | +LL | #[derive(Default)] + | + error[E0015]: cannot call non-const fn `::default` in constant functions --> $DIR/derive-const-non-const-type.rs:10:14 | @@ -10,6 +31,7 @@ LL | pub struct S(A); = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable = note: this error originates in the derive macro `Default` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0015`. +Some errors have detailed explanations: E0015, E0277. +For more information about an error, try `rustc --explain E0015`. diff --git a/tests/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr b/tests/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr index a244ab10cab..26644f72c4e 100644 --- a/tests/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/default-method-body-is-const-body-checking.stderr @@ -1,19 +1,14 @@ error[E0277]: the trait bound `(): ~const Tr` is not satisfied - --> $DIR/default-method-body-is-const-body-checking.rs:12:15 + --> $DIR/default-method-body-is-const-body-checking.rs:12:9 | LL | foo::<()>(); - | ^^ the trait `~const Tr` is not implemented for `()` + | ^^^^^^^^^^^ the trait `~const Tr` is not implemented for `()` | note: the trait `Tr` is implemented for `()`, but that implementation is not `const` - --> $DIR/default-method-body-is-const-body-checking.rs:12:15 + --> $DIR/default-method-body-is-const-body-checking.rs:12:9 | LL | foo::<()>(); - | ^^ -note: required by a bound in `foo` - --> $DIR/default-method-body-is-const-body-checking.rs:7:28 - | -LL | const fn foo() where T: ~const Tr {} - | ^^^^^^^^^ required by this bound in `foo` + | ^^^^^^^^^^^ error: aborting due to previous error diff --git a/tests/ui/rfc-2632-const-trait-impl/function-pointer-does-not-require-const.rs b/tests/ui/rfc-2632-const-trait-impl/function-pointer-does-not-require-const.rs new file mode 100644 index 00000000000..60790e29746 --- /dev/null +++ b/tests/ui/rfc-2632-const-trait-impl/function-pointer-does-not-require-const.rs @@ -0,0 +1,15 @@ +// check-pass +#![feature(const_trait_impl)] + +#[const_trait] +pub trait Test {} + +impl Test for () {} + +pub const fn test() {} + +pub const fn min_by_i32() -> fn() { + test::<()> +} + +fn main() {} From 054009d17eef7355571fe8796d14e17b77cae825 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Tue, 28 Mar 2023 08:40:37 +0000 Subject: [PATCH 211/346] fix long line --- .../const-drop-fail-2.precise.stderr | 20 +++++++++---------- .../const-drop-fail-2.rs | 8 +++++--- .../const-drop-fail-2.stock.stderr | 20 +++++++++---------- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.precise.stderr b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.precise.stderr index dd35501faec..bcdc80f82f8 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.precise.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.precise.stderr @@ -1,13 +1,13 @@ error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied --> $DIR/const-drop-fail-2.rs:31:23 | -LL | const _: () = check::>(ConstDropImplWithBounds(PhantomData)); +LL | const _: () = check::>( | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop` | note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const` --> $DIR/const-drop-fail-2.rs:31:23 | -LL | const _: () = check::>(ConstDropImplWithBounds(PhantomData)); +LL | const _: () = check::>( | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `ConstDropImplWithBounds` --> $DIR/const-drop-fail-2.rs:21:35 @@ -16,16 +16,16 @@ LL | struct ConstDropImplWithBounds(PhantomData); | ^^^^^^^^ required by this bound in `ConstDropImplWithBounds` error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied - --> $DIR/const-drop-fail-2.rs:31:64 + --> $DIR/const-drop-fail-2.rs:33:5 | -LL | const _: () = check::>(ConstDropImplWithBounds(PhantomData)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop` +LL | ConstDropImplWithBounds(PhantomData) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop` | note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail-2.rs:31:64 + --> $DIR/const-drop-fail-2.rs:33:5 | -LL | const _: () = check::>(ConstDropImplWithBounds(PhantomData)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ConstDropImplWithBounds(PhantomData) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `ConstDropImplWithBounds` --> $DIR/const-drop-fail-2.rs:21:35 | @@ -33,13 +33,13 @@ LL | struct ConstDropImplWithBounds(PhantomData); | ^^^^^^^^ required by this bound in `ConstDropImplWithBounds` error[E0367]: `Drop` impl requires `T: ~const A` but the struct it is implemented for does not - --> $DIR/const-drop-fail-2.rs:37:9 + --> $DIR/const-drop-fail-2.rs:39:9 | LL | impl const Drop for ConstDropImplWithNonConstBounds { | ^^^^^^^^ | note: the implementor must specify the same requirement - --> $DIR/const-drop-fail-2.rs:35:1 + --> $DIR/const-drop-fail-2.rs:37:1 | LL | struct ConstDropImplWithNonConstBounds(PhantomData); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.rs b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.rs index 8d7212dfe70..6a252c5d37b 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.rs +++ b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.rs @@ -28,9 +28,11 @@ impl const Drop for ConstDropImplWithBounds { const fn check(_: T) {} -const _: () = check::>(ConstDropImplWithBounds(PhantomData)); -//~^ ERROR the trait bound -//~| ERROR the trait bound +const _: () = check::>( + //~^ ERROR the trait bound + ConstDropImplWithBounds(PhantomData) + //~^ ERROR the trait bound +); struct ConstDropImplWithNonConstBounds(PhantomData); diff --git a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.stock.stderr b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.stock.stderr index dd35501faec..bcdc80f82f8 100644 --- a/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.stock.stderr +++ b/tests/ui/rfc-2632-const-trait-impl/const-drop-fail-2.stock.stderr @@ -1,13 +1,13 @@ error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied --> $DIR/const-drop-fail-2.rs:31:23 | -LL | const _: () = check::>(ConstDropImplWithBounds(PhantomData)); +LL | const _: () = check::>( | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop` | note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const` --> $DIR/const-drop-fail-2.rs:31:23 | -LL | const _: () = check::>(ConstDropImplWithBounds(PhantomData)); +LL | const _: () = check::>( | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `ConstDropImplWithBounds` --> $DIR/const-drop-fail-2.rs:21:35 @@ -16,16 +16,16 @@ LL | struct ConstDropImplWithBounds(PhantomData); | ^^^^^^^^ required by this bound in `ConstDropImplWithBounds` error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied - --> $DIR/const-drop-fail-2.rs:31:64 + --> $DIR/const-drop-fail-2.rs:33:5 | -LL | const _: () = check::>(ConstDropImplWithBounds(PhantomData)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop` +LL | ConstDropImplWithBounds(PhantomData) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop` | note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const` - --> $DIR/const-drop-fail-2.rs:31:64 + --> $DIR/const-drop-fail-2.rs:33:5 | -LL | const _: () = check::>(ConstDropImplWithBounds(PhantomData)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | ConstDropImplWithBounds(PhantomData) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: required by a bound in `ConstDropImplWithBounds` --> $DIR/const-drop-fail-2.rs:21:35 | @@ -33,13 +33,13 @@ LL | struct ConstDropImplWithBounds(PhantomData); | ^^^^^^^^ required by this bound in `ConstDropImplWithBounds` error[E0367]: `Drop` impl requires `T: ~const A` but the struct it is implemented for does not - --> $DIR/const-drop-fail-2.rs:37:9 + --> $DIR/const-drop-fail-2.rs:39:9 | LL | impl const Drop for ConstDropImplWithNonConstBounds { | ^^^^^^^^ | note: the implementor must specify the same requirement - --> $DIR/const-drop-fail-2.rs:35:1 + --> $DIR/const-drop-fail-2.rs:37:1 | LL | struct ConstDropImplWithNonConstBounds(PhantomData); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ From 49f63eb021e03b5bdd09645d5e0e68bbeae781ee Mon Sep 17 00:00:00 2001 From: Kai Luo Date: Tue, 28 Mar 2023 17:53:34 +0800 Subject: [PATCH 212/346] Check data segment range --- compiler/rustc_session/src/filesearch.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index 5d8002b493e..c6c910a3f4d 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -89,9 +89,8 @@ fn current_dll_path() -> Result { // * The address of the entry point of the function. // * The TOC base address for the function. // * The environment pointer. - // Deref `current_dll_path` directly so that we can get the address of `current_dll_path`'s - // entry point in text section. - let addr = *(current_dll_path as *const u64); + // The function descriptor is in the data section. + let addr = current_dll_path as u64; let mut buffer = vec![std::mem::zeroed::(); 64]; loop { if libc::loadquery( @@ -110,9 +109,9 @@ fn current_dll_path() -> Result { } let mut current = buffer.as_mut_ptr() as *mut libc::ld_info; loop { - let text_base = (*current).ldinfo_textorg as u64; - let text_end = text_base + (*current).ldinfo_textsize; - if (text_base..text_end).contains(&addr) { + let data_base = (*current).ldinfo_dataorg as u64; + let data_end = data_base + (*current).ldinfo_datasize; + if (data_base..data_end).contains(&addr) { let bytes = CStr::from_ptr(&(*current).ldinfo_filename[0]).to_bytes(); let os = OsStr::from_bytes(bytes); return Ok(PathBuf::from(os)); From b82608aa56b1e56dbebe5d5d94977d8d28f609bc Mon Sep 17 00:00:00 2001 From: pommicket Date: Tue, 28 Mar 2023 08:12:36 -0400 Subject: [PATCH 213/346] Create AnnotationColumn struct to fix hard tab column numbers in errors --- .../src/annotate_snippet_emitter_writer.rs | 5 +- compiler/rustc_errors/src/emitter.rs | 51 +++++++++------ compiler/rustc_errors/src/snippet.rs | 65 +++++++++++++++---- .../auxiliary/tab_column_numbers.rs | 6 ++ .../ui/diagnostic-width/tab-column-numbers.rs | 12 ++++ .../tab-column-numbers.stderr | 14 ++++ 6 files changed, 117 insertions(+), 36 deletions(-) create mode 100644 tests/ui/diagnostic-width/auxiliary/tab_column_numbers.rs create mode 100644 tests/ui/diagnostic-width/tab-column-numbers.rs create mode 100644 tests/ui/diagnostic-width/tab-column-numbers.stderr diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs index d8879bf70ed..9872b3bda1e 100644 --- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs +++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs @@ -202,7 +202,10 @@ impl AnnotateSnippetEmitterWriter { annotations: annotations .iter() .map(|annotation| SourceAnnotation { - range: (annotation.start_col, annotation.end_col), + range: ( + annotation.start_col.display, + annotation.end_col.display, + ), label: annotation.label.as_deref().unwrap_or_default(), annotation_type: annotation_type_for_level(*level), }) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 1b2e7b7e083..d6fd057c5a4 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -12,7 +12,9 @@ use Destination::*; use rustc_span::source_map::SourceMap; use rustc_span::{FileLines, SourceFile, Span}; -use crate::snippet::{Annotation, AnnotationType, Line, MultilineAnnotation, Style, StyledString}; +use crate::snippet::{ + Annotation, AnnotationColumn, AnnotationType, Line, MultilineAnnotation, Style, StyledString, +}; use crate::styled_buffer::StyledBuffer; use crate::translation::{to_fluent_args, Translate}; use crate::{ @@ -858,7 +860,7 @@ impl EmitterWriter { let mut short_start = true; for ann in &line.annotations { if let AnnotationType::MultilineStart(depth) = ann.annotation_type { - if source_string.chars().take(ann.start_col).all(|c| c.is_whitespace()) { + if source_string.chars().take(ann.start_col.display).all(|c| c.is_whitespace()) { let style = if ann.is_primary { Style::UnderlinePrimary } else { @@ -1093,15 +1095,15 @@ impl EmitterWriter { '_', line_offset + pos, width_offset + depth, - (code_offset + annotation.start_col).saturating_sub(left), + (code_offset + annotation.start_col.display).saturating_sub(left), style, ); } _ if self.teach => { buffer.set_style_range( line_offset, - (code_offset + annotation.start_col).saturating_sub(left), - (code_offset + annotation.end_col).saturating_sub(left), + (code_offset + annotation.start_col.display).saturating_sub(left), + (code_offset + annotation.end_col.display).saturating_sub(left), style, annotation.is_primary, ); @@ -1133,7 +1135,7 @@ impl EmitterWriter { for p in line_offset + 1..=line_offset + pos { buffer.putc( p, - (code_offset + annotation.start_col).saturating_sub(left), + (code_offset + annotation.start_col.display).saturating_sub(left), '|', style, ); @@ -1169,9 +1171,9 @@ impl EmitterWriter { let style = if annotation.is_primary { Style::LabelPrimary } else { Style::LabelSecondary }; let (pos, col) = if pos == 0 { - (pos + 1, (annotation.end_col + 1).saturating_sub(left)) + (pos + 1, (annotation.end_col.display + 1).saturating_sub(left)) } else { - (pos + 2, annotation.start_col.saturating_sub(left)) + (pos + 2, annotation.start_col.display.saturating_sub(left)) }; if let Some(ref label) = annotation.label { buffer.puts(line_offset + pos, code_offset + col, label, style); @@ -1208,7 +1210,7 @@ impl EmitterWriter { } else { ('-', Style::UnderlineSecondary) }; - for p in annotation.start_col..annotation.end_col { + for p in annotation.start_col.display..annotation.end_col.display { buffer.putc( line_offset + 1, (code_offset + p).saturating_sub(left), @@ -1459,7 +1461,7 @@ impl EmitterWriter { &annotated_file.file.name, line.line_index ), - annotations[0].start_col + 1, + annotations[0].start_col.file + 1, ), Style::LineAndColumn, ); @@ -1546,7 +1548,7 @@ impl EmitterWriter { buffer.prepend(buffer_msg_line_offset + 1, "::: ", Style::LineNumber); let loc = if let Some(first_line) = annotated_file.lines.first() { let col = if let Some(first_annotation) = first_line.annotations.first() { - format!(":{}", first_annotation.start_col + 1) + format!(":{}", first_annotation.start_col.file + 1) } else { String::new() }; @@ -1607,8 +1609,8 @@ impl EmitterWriter { let mut span_left_margin = usize::MAX; for line in &annotated_file.lines { for ann in &line.annotations { - span_left_margin = min(span_left_margin, ann.start_col); - span_left_margin = min(span_left_margin, ann.end_col); + span_left_margin = min(span_left_margin, ann.start_col.display); + span_left_margin = min(span_left_margin, ann.end_col.display); } } if span_left_margin == usize::MAX { @@ -1625,11 +1627,12 @@ impl EmitterWriter { annotated_file.file.get_line(line.line_index - 1).map_or(0, |s| s.len()), ); for ann in &line.annotations { - span_right_margin = max(span_right_margin, ann.start_col); - span_right_margin = max(span_right_margin, ann.end_col); + span_right_margin = max(span_right_margin, ann.start_col.display); + span_right_margin = max(span_right_margin, ann.end_col.display); // FIXME: account for labels not in the same line let label_right = ann.label.as_ref().map_or(0, |l| l.len() + 1); - label_right_margin = max(label_right_margin, ann.end_col + label_right); + label_right_margin = + max(label_right_margin, ann.end_col.display + label_right); } } @@ -2352,8 +2355,8 @@ impl FileWithAnnotatedLines { depth: 1, line_start: lo.line, line_end: hi.line, - start_col: lo.col_display, - end_col: hi.col_display, + start_col: AnnotationColumn::from_loc(&lo), + end_col: AnnotationColumn::from_loc(&hi), is_primary, label, overlaps_exactly: false, @@ -2361,8 +2364,8 @@ impl FileWithAnnotatedLines { multiline_annotations.push((lo.file, ml)); } else { let ann = Annotation { - start_col: lo.col_display, - end_col: hi.col_display, + start_col: AnnotationColumn::from_loc(&lo), + end_col: AnnotationColumn::from_loc(&hi), is_primary, label, annotation_type: AnnotationType::Singleline, @@ -2551,7 +2554,13 @@ fn num_overlap( (b_start..b_end + extra).contains(&a_start) || (a_start..a_end + extra).contains(&b_start) } fn overlaps(a1: &Annotation, a2: &Annotation, padding: usize) -> bool { - num_overlap(a1.start_col, a1.end_col + padding, a2.start_col, a2.end_col, false) + num_overlap( + a1.start_col.display, + a1.end_col.display + padding, + a2.start_col.display, + a2.end_col.display, + false, + ) } fn emit_to_destination( diff --git a/compiler/rustc_errors/src/snippet.rs b/compiler/rustc_errors/src/snippet.rs index e4cc44c41dd..98eb70b5fce 100644 --- a/compiler/rustc_errors/src/snippet.rs +++ b/compiler/rustc_errors/src/snippet.rs @@ -1,6 +1,6 @@ // Code for annotating snippets. -use crate::Level; +use crate::{Level, Loc}; #[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)] pub struct Line { @@ -8,13 +8,39 @@ pub struct Line { pub annotations: Vec, } +#[derive(Clone, Copy, Debug, PartialOrd, Ord, PartialEq, Eq, Default)] +pub struct AnnotationColumn { + /// the (0-indexed) column for *display* purposes, counted in characters, not utf-8 bytes + pub display: usize, + /// the (0-indexed) column in the file, counted in characters, not utf-8 bytes. + /// + /// this may be different from `self.display`, + /// e.g. if the file contains hard tabs, because we convert tabs to spaces for error messages. + /// + /// for example: + /// ```text + /// (hard tab)hello + /// ^ this is display column 4, but file column 1 + /// ``` + /// + /// we want to keep around the correct file offset so that column numbers in error messages + /// are correct. (motivated by ) + pub file: usize, +} + +impl AnnotationColumn { + pub fn from_loc(loc: &Loc) -> AnnotationColumn { + AnnotationColumn { display: loc.col_display, file: loc.col.0 } + } +} + #[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)] pub struct MultilineAnnotation { pub depth: usize, pub line_start: usize, pub line_end: usize, - pub start_col: usize, - pub end_col: usize, + pub start_col: AnnotationColumn, + pub end_col: AnnotationColumn, pub is_primary: bool, pub label: Option, pub overlaps_exactly: bool, @@ -36,7 +62,12 @@ impl MultilineAnnotation { pub fn as_start(&self) -> Annotation { Annotation { start_col: self.start_col, - end_col: self.start_col + 1, + end_col: AnnotationColumn { + // these might not correspond to the same place anymore, + // but that's okay for our purposes + display: self.start_col.display + 1, + file: self.start_col.file + 1, + }, is_primary: self.is_primary, label: None, annotation_type: AnnotationType::MultilineStart(self.depth), @@ -45,7 +76,12 @@ impl MultilineAnnotation { pub fn as_end(&self) -> Annotation { Annotation { - start_col: self.end_col.saturating_sub(1), + start_col: AnnotationColumn { + // these might not correspond to the same place anymore, + // but that's okay for our purposes + display: self.end_col.display.saturating_sub(1), + file: self.end_col.file.saturating_sub(1), + }, end_col: self.end_col, is_primary: self.is_primary, label: self.label.clone(), @@ -55,8 +91,8 @@ impl MultilineAnnotation { pub fn as_line(&self) -> Annotation { Annotation { - start_col: 0, - end_col: 0, + start_col: Default::default(), + end_col: Default::default(), is_primary: self.is_primary, label: None, annotation_type: AnnotationType::MultilineLine(self.depth), @@ -92,14 +128,14 @@ pub enum AnnotationType { #[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)] pub struct Annotation { - /// Start column, 0-based indexing -- counting *characters*, not - /// utf-8 bytes. Note that it is important that this field goes + /// Start column. + /// Note that it is important that this field goes /// first, so that when we sort, we sort orderings by start /// column. - pub start_col: usize, + pub start_col: AnnotationColumn, /// End column within the line (exclusive) - pub end_col: usize, + pub end_col: AnnotationColumn, /// Is this annotation derived from primary span pub is_primary: bool, @@ -118,12 +154,13 @@ impl Annotation { matches!(self.annotation_type, AnnotationType::MultilineLine(_)) } + /// Length of this annotation as displayed in the stderr output pub fn len(&self) -> usize { // Account for usize underflows - if self.end_col > self.start_col { - self.end_col - self.start_col + if self.end_col.display > self.start_col.display { + self.end_col.display - self.start_col.display } else { - self.start_col - self.end_col + self.start_col.display - self.end_col.display } } diff --git a/tests/ui/diagnostic-width/auxiliary/tab_column_numbers.rs b/tests/ui/diagnostic-width/auxiliary/tab_column_numbers.rs new file mode 100644 index 00000000000..93418b7651c --- /dev/null +++ b/tests/ui/diagnostic-width/auxiliary/tab_column_numbers.rs @@ -0,0 +1,6 @@ +// ignore-tidy-tab + +pub struct S; +impl S { + fn method(&self) {} +} diff --git a/tests/ui/diagnostic-width/tab-column-numbers.rs b/tests/ui/diagnostic-width/tab-column-numbers.rs new file mode 100644 index 00000000000..2abb0bcde95 --- /dev/null +++ b/tests/ui/diagnostic-width/tab-column-numbers.rs @@ -0,0 +1,12 @@ +// Test for #109537: ensure that column numbers are correctly generated when using hard tabs. +// aux-build:tab_column_numbers.rs + +// ignore-tidy-tab + +extern crate tab_column_numbers; + +fn main() { + let s = tab_column_numbers::S; + s.method(); + //~^ ERROR method `method` is private +} diff --git a/tests/ui/diagnostic-width/tab-column-numbers.stderr b/tests/ui/diagnostic-width/tab-column-numbers.stderr new file mode 100644 index 00000000000..ea4e1ff52a9 --- /dev/null +++ b/tests/ui/diagnostic-width/tab-column-numbers.stderr @@ -0,0 +1,14 @@ +error[E0624]: method `method` is private + --> $DIR/tab-column-numbers.rs:10:4 + | +LL | s.method(); + | ^^^^^^ private method + | + ::: $DIR/auxiliary/tab_column_numbers.rs:5:3 + | +LL | fn method(&self) {} + | ---------------- private method defined here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0624`. From a857ba25f9630032a34aba5dc45fd5f58351c7f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Tue, 28 Mar 2023 13:22:01 +0000 Subject: [PATCH 214/346] address review comments Move tests and limit the init mask's structures/fields visibility. --- compiler/rustc_middle/src/mir/interpret/allocation.rs | 2 -- .../src/mir/interpret/allocation/init_mask.rs | 11 +++++++---- .../mir/interpret/allocation/{ => init_mask}/tests.rs | 1 + 3 files changed, 8 insertions(+), 6 deletions(-) rename compiler/rustc_middle/src/mir/interpret/allocation/{ => init_mask}/tests.rs (99%) diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index 48375ed301d..2f2c7b15416 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -2,8 +2,6 @@ mod init_mask; mod provenance_map; -#[cfg(test)] -mod tests; use std::borrow::Cow; use std::fmt; diff --git a/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs b/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs index 312fecea5da..9a02bc0cc15 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation/init_mask.rs @@ -1,3 +1,6 @@ +#[cfg(test)] +mod tests; + use std::hash; use std::iter; use std::ops::Range; @@ -16,12 +19,12 @@ type Block = u64; /// value. #[derive(Clone, Debug, Eq, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)] pub struct InitMask { - pub(crate) blocks: InitMaskBlocks, + blocks: InitMaskBlocks, len: Size, } #[derive(Clone, Debug, Eq, PartialEq, TyEncodable, TyDecodable, Hash, HashStable)] -pub(crate) enum InitMaskBlocks { +enum InitMaskBlocks { Lazy { /// Whether the lazy init mask is fully initialized or uninitialized. state: bool, @@ -180,8 +183,8 @@ impl InitMask { // Note: for performance reasons when interning, some of the fields can be partially // hashed. (see the `Hash` impl below for more details), so the impl is not derived. #[derive(Clone, Debug, Eq, PartialEq, TyEncodable, TyDecodable, HashStable)] -pub(crate) struct InitMaskMaterialized { - pub(crate) blocks: Vec, +struct InitMaskMaterialized { + blocks: Vec, } // Const allocations are only hashed for interning. However, they can be large, making the hashing diff --git a/compiler/rustc_middle/src/mir/interpret/allocation/tests.rs b/compiler/rustc_middle/src/mir/interpret/allocation/init_mask/tests.rs similarity index 99% rename from compiler/rustc_middle/src/mir/interpret/allocation/tests.rs rename to compiler/rustc_middle/src/mir/interpret/allocation/init_mask/tests.rs index 171ed4d93bb..1a7934bc210 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation/tests.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation/init_mask/tests.rs @@ -1,4 +1,5 @@ use super::*; +use crate::mir::interpret::alloc_range; #[test] fn uninit_mask() { From 52b15b4bf9f3a24b44017fe4b1c114a6d91f1e88 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Thu, 23 Mar 2023 18:47:49 +0400 Subject: [PATCH 215/346] rustdoc: Unsupport importing `doc(primitive)` and `doc(keyword)` modules These are internal features used for a specific purpose, and modules without imports are enough for that purpose. --- src/librustdoc/clean/types.rs | 17 ----------------- tests/rustdoc/issue-15318-2.rs | 2 +- 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 9019a6c49ec..93c2b5e069c 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -232,14 +232,6 @@ impl ExternalCrate { hir::ItemKind::Mod(_) => { as_keyword(Res::Def(DefKind::Mod, id.owner_id.to_def_id())) } - hir::ItemKind::Use(path, hir::UseKind::Single) - if tcx.visibility(id.owner_id).is_public() => - { - path.res - .iter() - .find_map(|res| as_keyword(res.expect_non_local())) - .map(|(_, prim)| (id.owner_id.to_def_id(), prim)) - } _ => None, } }) @@ -302,15 +294,6 @@ impl ExternalCrate { hir::ItemKind::Mod(_) => { as_primitive(Res::Def(DefKind::Mod, id.owner_id.to_def_id())) } - hir::ItemKind::Use(path, hir::UseKind::Single) - if tcx.visibility(id.owner_id).is_public() => - { - path.res - .iter() - .find_map(|res| as_primitive(res.expect_non_local())) - // Pretend the primitive is local. - .map(|(_, prim)| (id.owner_id.to_def_id(), prim)) - } _ => None, } }) diff --git a/tests/rustdoc/issue-15318-2.rs b/tests/rustdoc/issue-15318-2.rs index f7f5052a36d..614f2c1c08e 100644 --- a/tests/rustdoc/issue-15318-2.rs +++ b/tests/rustdoc/issue-15318-2.rs @@ -6,7 +6,7 @@ extern crate issue_15318; pub use issue_15318::ptr; -// @has issue_15318_2/fn.bar.html \ +// @!has issue_15318_2/fn.bar.html \ // '//*[@href="primitive.pointer.html"]' \ // '*mut T' pub fn bar(ptr: *mut T) {} From be6a09f96bbe0c0c6ce909a84ea0164112edfced Mon Sep 17 00:00:00 2001 From: Daniil Belov <70999565+BelovDV@users.noreply.github.com> Date: Tue, 28 Mar 2023 12:13:42 +0300 Subject: [PATCH 216/346] [fix] don't panic on failure to acquire jobserver token --- compiler/rustc_codegen_ssa/src/back/write.rs | 4 ++-- tests/run-make/jobserver-error/Makefile | 8 ++++++++ tests/run-make/jobserver-error/jobserver.stderr | 4 ++++ 3 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 tests/run-make/jobserver-error/Makefile create mode 100644 tests/run-make/jobserver-error/jobserver.stderr diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 7ce72d21727..2dda4cd1694 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -1452,8 +1452,8 @@ fn start_executing_work( Err(e) => { let msg = &format!("failed to acquire jobserver token: {}", e); shared_emitter.fatal(msg); - // Exit the coordinator thread - panic!("{}", msg) + codegen_done = true; + codegen_aborted = true; } } } diff --git a/tests/run-make/jobserver-error/Makefile b/tests/run-make/jobserver-error/Makefile new file mode 100644 index 00000000000..3b9104fc354 --- /dev/null +++ b/tests/run-make/jobserver-error/Makefile @@ -0,0 +1,8 @@ +include ../../run-make-fulldeps/tools.mk + +# only-linux + +# Test compiler behavior in case: `jobserver-auth` points to correct pipe which is not jobserver. + +all: + bash -c 'echo "fn main() {}" | MAKEFLAGS="--jobserver-auth=3,3" $(RUSTC) - 3&1 | diff jobserver.stderr - diff --git a/tests/run-make/jobserver-error/jobserver.stderr b/tests/run-make/jobserver-error/jobserver.stderr new file mode 100644 index 00000000000..d18e15a2628 --- /dev/null +++ b/tests/run-make/jobserver-error/jobserver.stderr @@ -0,0 +1,4 @@ +error: failed to acquire jobserver token: early EOF on jobserver pipe + +error: aborting due to previous error + From e3968be331aaf7fa48f2365998ed4d076ddc82c8 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Thu, 10 Nov 2022 10:06:34 +0000 Subject: [PATCH 217/346] Add OpenHarmony targets - `aarch64-unknown-linux-ohos` - `armv7-unknown-linux-ohos` --- Cargo.lock | 8 +- compiler/rustc_codegen_llvm/src/back/write.rs | 3 + compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 1 + .../rustc_llvm/llvm-wrapper/PassWrapper.cpp | 7 +- .../src/spec/aarch64_unknown_linux_ohos.rs | 31 +++++ .../src/spec/armv7_unknown_linux_ohos.rs | 27 ++++ compiler/rustc_target/src/spec/mod.rs | 9 ++ library/std/Cargo.toml | 2 +- library/std/src/sys/unix/os.rs | 5 +- library/unwind/src/lib.rs | 16 +++ src/bootstrap/lib.rs | 2 + src/bootstrap/llvm.rs | 3 + src/doc/rustc/src/SUMMARY.md | 1 + src/doc/rustc/src/platform-support.md | 2 + .../rustc/src/platform-support/openharmony.md | 128 ++++++++++++++++++ 15 files changed, 238 insertions(+), 7 deletions(-) create mode 100644 compiler/rustc_target/src/spec/aarch64_unknown_linux_ohos.rs create mode 100644 compiler/rustc_target/src/spec/armv7_unknown_linux_ohos.rs create mode 100644 src/doc/rustc/src/platform-support/openharmony.md diff --git a/Cargo.lock b/Cargo.lock index 449f0c73588..014e6ee71c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -868,9 +868,9 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.87" +version = "0.1.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f867ce54c09855ccd135ad4a50c777182a0c7af5ff20a8f537617bd648b10d50" +checksum = "9fc9c2080d347a2c316518840ac9194644a9993dfa1e9778ef38979a339f5d8b" dependencies = [ "cc", "rustc-std-workspace-core", @@ -2879,9 +2879,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.139" +version = "0.2.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" dependencies = [ "rustc-std-workspace-core", ] diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index a4ae1b01e86..fb563f70ed0 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -214,6 +214,8 @@ pub fn target_machine_factory( let path_mapping = sess.source_map().path_mapping().clone(); + let force_emulated_tls = sess.target.force_emulated_tls; + Arc::new(move |config: TargetMachineFactoryConfig| { let split_dwarf_file = path_mapping.map_prefix(config.split_dwarf_file.unwrap_or_default()).0; @@ -239,6 +241,7 @@ pub fn target_machine_factory( relax_elf_relocations, use_init_array, split_dwarf_file.as_ptr(), + force_emulated_tls, ) }; diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index 9e5265188b5..0d63e634ad8 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2257,6 +2257,7 @@ extern "C" { RelaxELFRelocations: bool, UseInitArray: bool, SplitDwarfFile: *const c_char, + ForceEmulatedTls: bool, ) -> Option<&'static mut TargetMachine>; pub fn LLVMRustDisposeTargetMachine(T: &'static mut TargetMachine); pub fn LLVMRustAddLibraryInfo<'a>( diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index e604e44a715..329e7329b11 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -368,7 +368,8 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( bool EmitStackSizeSection, bool RelaxELFRelocations, bool UseInitArray, - const char *SplitDwarfFile) { + const char *SplitDwarfFile, + bool ForceEmulatedTls) { auto OptLevel = fromRust(RustOptLevel); auto RM = fromRust(RustReloc); @@ -400,6 +401,10 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine( } Options.RelaxELFRelocations = RelaxELFRelocations; Options.UseInitArray = UseInitArray; + if (ForceEmulatedTls) { + Options.ExplicitEmulatedTLS = true; + Options.EmulatedTLS = true; + } if (TrapUnreachable) { // Tell LLVM to codegen `unreachable` into an explicit trap instruction. diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_linux_ohos.rs b/compiler/rustc_target/src/spec/aarch64_unknown_linux_ohos.rs new file mode 100644 index 00000000000..0a5e654cf0d --- /dev/null +++ b/compiler/rustc_target/src/spec/aarch64_unknown_linux_ohos.rs @@ -0,0 +1,31 @@ +use crate::spec::{Target, TargetOptions}; + +use super::SanitizerSet; + +pub fn target() -> Target { + let mut base = super::linux_musl_base::opts(); + base.env = "ohos".into(); + base.crt_static_default = false; + base.max_atomic_width = Some(128); + + Target { + // LLVM 15 doesn't support OpenHarmony yet, use a linux target instead. + llvm_target: "aarch64-unknown-linux-musl".into(), + pointer_width: 64, + data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(), + arch: "aarch64".into(), + options: TargetOptions { + features: "+reserve-x18".into(), + mcount: "\u{1}_mcount".into(), + force_emulated_tls: true, + supported_sanitizers: SanitizerSet::ADDRESS + | SanitizerSet::CFI + | SanitizerSet::LEAK + | SanitizerSet::MEMORY + | SanitizerSet::MEMTAG + | SanitizerSet::THREAD + | SanitizerSet::HWADDRESS, + ..base + }, + } +} diff --git a/compiler/rustc_target/src/spec/armv7_unknown_linux_ohos.rs b/compiler/rustc_target/src/spec/armv7_unknown_linux_ohos.rs new file mode 100644 index 00000000000..a64f3a4f049 --- /dev/null +++ b/compiler/rustc_target/src/spec/armv7_unknown_linux_ohos.rs @@ -0,0 +1,27 @@ +use crate::spec::{Target, TargetOptions}; + +// This target is for OpenHarmony on ARMv7 Linux with thumb-mode, but no NEON or +// hardfloat. + +pub fn target() -> Target { + // Most of these settings are copied from the armv7_unknown_linux_musleabi + // target. + Target { + // LLVM 15 doesn't support OpenHarmony yet, use a linux target instead. + llvm_target: "armv7-unknown-linux-gnueabi".into(), + pointer_width: 32, + data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), + arch: "arm".into(), + + options: TargetOptions { + abi: "eabi".into(), + features: "+v7,+thumb2,+soft-float,-neon".into(), + max_atomic_width: Some(64), + env: "ohos".into(), + crt_static_default: false, + mcount: "\u{1}mcount".into(), + force_emulated_tls: true, + ..super::linux_musl_base::opts() + }, + } +} diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 2553b11d878..c40284cbf44 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1261,6 +1261,9 @@ supported_targets! { ("aarch64-unknown-nto-qnx710", aarch64_unknown_nto_qnx_710), ("x86_64-pc-nto-qnx710", x86_64_pc_nto_qnx710), + + ("aarch64-unknown-linux-ohos", aarch64_unknown_linux_ohos), + ("armv7-unknown-linux-ohos", armv7_unknown_linux_ohos), } /// Cow-Vec-Str: Cow<'static, [Cow<'static, str>]> @@ -1734,6 +1737,9 @@ pub struct TargetOptions { /// Whether the target supports XRay instrumentation. pub supports_xray: bool, + + /// Forces the use of emulated TLS (__emutls_get_address) + pub force_emulated_tls: bool, } /// Add arguments for the given flavor and also for its "twin" flavors @@ -1954,6 +1960,7 @@ impl Default for TargetOptions { entry_name: "main".into(), entry_abi: Conv::C, supports_xray: false, + force_emulated_tls: false, } } } @@ -2605,6 +2612,7 @@ impl Target { key!(entry_name); key!(entry_abi, Conv)?; key!(supports_xray, bool); + key!(force_emulated_tls, bool); if base.is_builtin { // This can cause unfortunate ICEs later down the line. @@ -2859,6 +2867,7 @@ impl ToJson for Target { target_option_val!(entry_name); target_option_val!(entry_abi); target_option_val!(supports_xray); + target_option_val!(force_emulated_tls); if let Some(abi) = self.default_adjusted_cabi { d.insert("default-adjusted-cabi".into(), Abi::name(abi).to_json()); diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 598a4bf9282..6345db24054 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -15,7 +15,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] } panic_unwind = { path = "../panic_unwind", optional = true } panic_abort = { path = "../panic_abort" } core = { path = "../core" } -libc = { version = "0.2.139", default-features = false, features = ['rustc-dep-of-std'] } +libc = { version = "0.2.140", default-features = false, features = ['rustc-dep-of-std'] } compiler_builtins = { version = "0.1.87" } profiler_builtins = { path = "../profiler_builtins", optional = true } unwind = { path = "../unwind" } diff --git a/library/std/src/sys/unix/os.rs b/library/std/src/sys/unix/os.rs index 21b035fb373..1c44058aff7 100644 --- a/library/std/src/sys/unix/os.rs +++ b/library/std/src/sys/unix/os.rs @@ -115,7 +115,10 @@ pub fn set_errno(e: i32) { /// Gets a detailed string description for the given error number. pub fn error_string(errno: i32) -> String { extern "C" { - #[cfg_attr(any(target_os = "linux", target_env = "newlib"), link_name = "__xpg_strerror_r")] + #[cfg_attr( + all(any(target_os = "linux", target_env = "newlib"), not(target_env = "ohos")), + link_name = "__xpg_strerror_r" + )] fn strerror_r(errnum: c_int, buf: *mut c_char, buflen: libc::size_t) -> c_int; } diff --git a/library/unwind/src/lib.rs b/library/unwind/src/lib.rs index edc10aa39af..b655bae9673 100644 --- a/library/unwind/src/lib.rs +++ b/library/unwind/src/lib.rs @@ -54,6 +54,22 @@ cfg_if::cfg_if! { } } +// This is the same as musl except that we default to using the system libunwind +// instead of libgcc. +#[cfg(target_env = "ohos")] +cfg_if::cfg_if! { + if #[cfg(all(feature = "llvm-libunwind", feature = "system-llvm-libunwind"))] { + compile_error!("`llvm-libunwind` and `system-llvm-libunwind` cannot be enabled at the same time"); + } else if #[cfg(feature = "llvm-libunwind")] { + #[link(name = "unwind", kind = "static", modifiers = "-bundle")] + extern "C" {} + } else { + #[link(name = "unwind", kind = "static", modifiers = "-bundle", cfg(target_feature = "crt-static"))] + #[link(name = "unwind", cfg(not(target_feature = "crt-static")))] + extern "C" {} + } +} + #[cfg(target_os = "android")] cfg_if::cfg_if! { if #[cfg(feature = "llvm-libunwind")] { diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 20b92b294fe..f981b5d5da8 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -149,6 +149,8 @@ const EXTRA_CHECK_CFGS: &[(Option, &'static str, Option<&[&'static str]>)] // Needed to avoid the need to copy windows.lib into the sysroot. (Some(Mode::Rustc), "windows_raw_dylib", None), (Some(Mode::ToolRustc), "windows_raw_dylib", None), + // #[cfg(bootstrap)] ohos + (Some(Mode::Std), "target_env", Some(&["ohos"])), ]; /// A structure representing a Rust compiler. diff --git a/src/bootstrap/llvm.rs b/src/bootstrap/llvm.rs index de06f8ca8c0..a22f0f04b2e 100644 --- a/src/bootstrap/llvm.rs +++ b/src/bootstrap/llvm.rs @@ -1008,6 +1008,9 @@ fn supported_sanitizers( "aarch64-unknown-linux-gnu" => { common_libs("linux", "aarch64", &["asan", "lsan", "msan", "tsan", "hwasan"]) } + "aarch64-unknown-linux-ohos" => { + common_libs("linux", "aarch64", &["asan", "lsan", "msan", "tsan", "hwasan"]) + } "x86_64-apple-darwin" => darwin_libs("osx", &["asan", "lsan", "tsan"]), "x86_64-unknown-fuchsia" => common_libs("fuchsia", "x86_64", &["asan"]), "x86_64-apple-ios" => darwin_libs("iossim", &["asan", "tsan"]), diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 752f1cc4aba..0452126cc37 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -26,6 +26,7 @@ - [armv7-unknown-linux-uclibceabi](platform-support/armv7-unknown-linux-uclibceabi.md) - [armv7-unknown-linux-uclibceabihf](platform-support/armv7-unknown-linux-uclibceabihf.md) - [\*-android and \*-androideabi](platform-support/android.md) + - [\*-linux-ohos](platform-support/openharmony.md) - [\*-unknown-fuchsia](platform-support/fuchsia.md) - [\*-kmc-solid_\*](platform-support/kmc-solid.md) - [m68k-unknown-linux-gnu](platform-support/m68k-unknown-linux-gnu.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 2d74a224096..5c18a38ddab 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -218,6 +218,7 @@ target | std | host | notes [`aarch64-kmc-solid_asp3`](platform-support/kmc-solid.md) | ✓ | | ARM64 SOLID with TOPPERS/ASP3 [`aarch64-nintendo-switch-freestanding`](platform-support/aarch64-nintendo-switch-freestanding.md) | * | | ARM64 Nintendo Switch, Horizon [`aarch64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ | +[`aarch64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | | ARM64 OpenHarmony | [`aarch64-unknown-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 7.1 RTOS | `aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD `aarch64-unknown-hermit` | ✓ | | ARM64 HermitCore @@ -240,6 +241,7 @@ target | std | host | notes [`armv6k-nintendo-3ds`](platform-support/armv6k-nintendo-3ds.md) | ? | | ARMv6K Nintendo 3DS, Horizon (Requires devkitARM toolchain) `armv7-apple-ios` | ✓ | | ARMv7 iOS, Cortex-a8 [`armv7-sony-vita-newlibeabihf`](platform-support/armv7-sony-vita-newlibeabihf.md) | ? | | ARM Cortex-A9 Sony PlayStation Vita (requires VITASDK toolchain) +[`armv7-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | | ARMv7 OpenHarmony | [`armv7-unknown-linux-uclibceabi`](platform-support/armv7-unknown-linux-uclibceabi.md) | ✓ | ✓ | ARMv7 Linux with uClibc, softfloat [`armv7-unknown-linux-uclibceabihf`](platform-support/armv7-unknown-linux-uclibceabihf.md) | ✓ | ? | ARMv7 Linux with uClibc, hardfloat `armv7-unknown-freebsd` | ✓ | ✓ | ARMv7 FreeBSD diff --git a/src/doc/rustc/src/platform-support/openharmony.md b/src/doc/rustc/src/platform-support/openharmony.md new file mode 100644 index 00000000000..aa4debfd45a --- /dev/null +++ b/src/doc/rustc/src/platform-support/openharmony.md @@ -0,0 +1,128 @@ +# `*-linux-ohos*` + +**Tier: 3** + +Targets for the [OpenHarmony](https://gitee.com/openharmony/docs/) operating +system. + +## Target maintainers + +- Amanieu d'Antras ([@Amanieu](https://github.com/Amanieu)) + +## Setup + +The OpenHarmony SDK doesn't currently support Rust compilation directly, so +some setup is required. + +First, you must obtain the OpenHarmony SDK from [this page](https://gitee.com/openharmony/docs/tree/master/en/release-notes). +Select the version of OpenHarmony you are developing for and download the "Public SDK package for the standard system". + +Create the following shell scripts that wrap Clang from the OpenHarmony SDK: + +`aarch64-unknown-linux-ohos-clang.sh` + +```sh +#!/bin/sh +exec /path/to/ohos-sdk/linux/native/llvm/bin/clang \ + -target aarch64-linux-ohos \ + --sysroot=/path/to/ohos-sdk/linux/native/sysroot \ + -D__MUSL__ \ + "$@" +``` + +`aarch64-unknown-linux-ohos-clang++.sh` + +```sh +#!/bin/sh +exec /path/to/ohos-sdk/linux/native/llvm/bin/clang++ \ + -target aarch64-linux-ohos \ + --sysroot=/path/to/ohos-sdk/linux/native/sysroot \ + -D__MUSL__ \ + "$@" +``` + +`armv7-unknown-linux-ohos-clang.sh` + +```sh +#!/bin/sh +exec /path/to/ohos-sdk/linux/native/llvm/bin/clang \ + -target arm-linux-ohos \ + --sysroot=/path/to/ohos-sdk/linux/native/sysroot \ + -D__MUSL__ \ + -march=armv7-a \ + -mfloat-abi=softfp \ + -mtune=generic-armv7-a \ + -mthumb \ + "$@" +``` + +`armv7-unknown-linux-ohos-clang++.sh` + +```sh +#!/bin/sh +exec /path/to/ohos-sdk/linux/native/llvm/bin/clang++ \ + -target arm-linux-ohos \ + --sysroot=/path/to/ohos-sdk/linux/native/sysroot \ + -D__MUSL__ \ + -march=armv7-a \ + -mfloat-abi=softfp \ + -mtune=generic-armv7-a \ + -mthumb \ + "$@" +``` + +Future versions of the OpenHarmony SDK will avoid the need for this process. + +## Building the target + +To build a rust toolchain, create a `config.toml` with the following contents: + +```toml +profile = "compiler" +changelog-seen = 2 + +[build] +sanitizers = true +profiler = true + +[target.aarch64-unknown-linux-ohos] +cc = "/path/to/aarch64-unknown-linux-ohos-clang.sh" +cxx = "/path/to/aarch64-unknown-linux-ohos-clang++.sh" +ar = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ar" +ranlib = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ranlib" +linker = "/path/to/aarch64-unknown-linux-ohos-clang.sh" + +[target.armv7-unknown-linux-ohos] +cc = "/path/to/armv7-unknown-linux-ohos-clang.sh" +cxx = "/path/to/armv7-unknown-linux-ohos-clang++.sh" +ar = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ar" +ranlib = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ranlib" +linker = "/path/to/armv7-unknown-linux-ohos-clang.sh" +``` + +## Building Rust programs + +Rust does not yet ship pre-compiled artifacts for this target. To compile for +this target, you will either need to build Rust with the target enabled (see +"Building the target" above), or build your own copy of `core` by using +`build-std` or similar. + +You will need to configure the linker to use in `~/.cargo/config`: +```toml +[target.aarch64-unknown-linux-ohos] +ar = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ar" +linker = "/path/to/aarch64-unknown-linux-ohos-clang.sh" + +[target.armv7-unknown-linux-ohos] +ar = "/path/to/ohos-sdk/linux/native/llvm/bin/llvm-ar" +linker = "/path/to/armv7-unknown-linux-ohos-clang.sh" +``` + +## Testing + +Running the Rust testsuite is possible, but currently difficult due to the way +the OpenHarmony emulator is set up (no networking). + +## Cross-compilation toolchains and C code + +You can use the shell scripts above to compile C code for the target. From c972a4269c862c3bc98fb649f17c57b4d429fe13 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Tue, 28 Mar 2023 17:29:21 +0100 Subject: [PATCH 218/346] Stabilize `binary_heap_retain` FCP finished in tracking issue: #71503 --- library/alloc/src/collections/binary_heap/mod.rs | 3 +-- library/alloc/tests/lib.rs | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs index d0a87e3fb9f..31946822689 100644 --- a/library/alloc/src/collections/binary_heap/mod.rs +++ b/library/alloc/src/collections/binary_heap/mod.rs @@ -837,7 +837,6 @@ impl BinaryHeap { /// Basic usage: /// /// ``` - /// #![feature(binary_heap_retain)] /// use std::collections::BinaryHeap; /// /// let mut heap = BinaryHeap::from([-10, -5, 1, 2, 4, 13]); @@ -846,7 +845,7 @@ impl BinaryHeap { /// /// assert_eq!(heap.into_sorted_vec(), [-10, 2, 4]) /// ``` - #[unstable(feature = "binary_heap_retain", issue = "71503")] + #[stable(feature = "binary_heap_retain", since = "CURRENT_RUSTC_VERSION")] pub fn retain(&mut self, mut f: F) where F: FnMut(&T) -> bool, diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs index 966cf575116..4f298e3f5cc 100644 --- a/library/alloc/tests/lib.rs +++ b/library/alloc/tests/lib.rs @@ -25,7 +25,6 @@ #![feature(binary_heap_into_iter_sorted)] #![feature(binary_heap_drain_sorted)] #![feature(slice_ptr_get)] -#![feature(binary_heap_retain)] #![feature(binary_heap_as_slice)] #![feature(inplace_iteration)] #![feature(iter_advance_by)] From be9fd75d32f9af0ebed5aad348891603f2e17ac2 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 22 Feb 2023 04:43:15 +0000 Subject: [PATCH 219/346] rustdoc + rustdoc-json support for non_lifetime_binders --- src/librustdoc/clean/mod.rs | 17 ++--------- src/librustdoc/clean/simplify.rs | 6 +--- src/librustdoc/clean/types.rs | 8 ++--- src/librustdoc/html/format.rs | 4 +-- src/librustdoc/json/conversions.rs | 34 +++++++++++++++++++--- tests/rustdoc-json/non_lifetime_binders.rs | 24 +++++++++++++++ tests/rustdoc/non_lifetime_binders.rs | 9 ++++++ 7 files changed, 73 insertions(+), 29 deletions(-) create mode 100644 tests/rustdoc-json/non_lifetime_binders.rs create mode 100644 tests/rustdoc/non_lifetime_binders.rs diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 5f5521caf68..2d247bd537b 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -31,7 +31,6 @@ use rustc_span::hygiene::{AstPass, MacroKind}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{self, ExpnKind}; -use std::assert_matches::assert_matches; use std::borrow::Cow; use std::collections::hash_map::Entry; use std::collections::BTreeMap; @@ -270,15 +269,7 @@ fn clean_where_predicate<'tcx>( let bound_params = wbp .bound_generic_params .iter() - .map(|param| { - // Higher-ranked params must be lifetimes. - // Higher-ranked lifetimes can't have bounds. - assert_matches!( - param, - hir::GenericParam { kind: hir::GenericParamKind::Lifetime { .. }, .. } - ); - Lifetime(param.name.ident().name) - }) + .map(|param| clean_generic_param(cx, None, param)) .collect(); WherePredicate::BoundPredicate { ty: clean_ty(wbp.bounded_ty, cx), @@ -410,7 +401,7 @@ fn clean_projection_predicate<'tcx>( .collect_referenced_late_bound_regions(&pred) .into_iter() .filter_map(|br| match br { - ty::BrNamed(_, name) if br.is_named() => Some(Lifetime(name)), + ty::BrNamed(_, name) if br.is_named() => Some(GenericParamDef::lifetime(name)), _ => None, }) .collect(); @@ -508,7 +499,6 @@ fn clean_generic_param_def<'tcx>( ty::GenericParamDefKind::Const { has_default } => ( def.name, GenericParamDefKind::Const { - did: def.def_id, ty: Box::new(clean_middle_ty( ty::Binder::dummy( cx.tcx @@ -578,7 +568,6 @@ fn clean_generic_param<'tcx>( hir::GenericParamKind::Const { ty, default } => ( param.name.ident().name, GenericParamDefKind::Const { - did: param.def_id.to_def_id(), ty: Box::new(clean_ty(ty, cx)), default: default .map(|ct| Box::new(ty::Const::from_anon_const(cx.tcx, ct.def_id).to_string())), @@ -831,7 +820,7 @@ fn clean_ty_generics<'tcx>( p.get_bound_params() .into_iter() .flatten() - .map(|param| GenericParamDef::lifetime(param.0)) + .cloned() .collect(), )); } diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index dbbc25739aa..3c72b0bf9f2 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -49,11 +49,7 @@ pub(crate) fn where_clauses(cx: &DocContext<'_>, clauses: Vec) -> ThinVec, bound_params: Vec }, + BoundPredicate { ty: Type, bounds: Vec, bound_params: Vec }, RegionPredicate { lifetime: Lifetime, bounds: Vec }, - EqPredicate { lhs: Box, rhs: Box, bound_params: Vec }, + EqPredicate { lhs: Box, rhs: Box, bound_params: Vec }, } impl WherePredicate { @@ -1250,7 +1250,7 @@ impl WherePredicate { } } - pub(crate) fn get_bound_params(&self) -> Option<&[Lifetime]> { + pub(crate) fn get_bound_params(&self) -> Option<&[GenericParamDef]> { match self { Self::BoundPredicate { bound_params, .. } | Self::EqPredicate { bound_params, .. } => { Some(bound_params) @@ -1264,7 +1264,7 @@ impl WherePredicate { pub(crate) enum GenericParamDefKind { Lifetime { outlives: Vec }, Type { did: DefId, bounds: Vec, default: Option>, synthetic: bool }, - Const { did: DefId, ty: Box, default: Option> }, + Const { ty: Box, default: Option> }, } impl GenericParamDefKind { diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index f2b9c0bcf3e..0895bb510d4 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -307,13 +307,13 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>( write!( f, "for<{:#}> {ty_cx:#}: {generic_bounds:#}", - comma_sep(bound_params.iter().map(|lt| lt.print()), true) + comma_sep(bound_params.iter().map(|lt| lt.print(cx)), true) ) } else { write!( f, "for<{}> {ty_cx}: {generic_bounds}", - comma_sep(bound_params.iter().map(|lt| lt.print()), true) + comma_sep(bound_params.iter().map(|lt| lt.print(cx)), true) ) } } diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 18c45fd6991..59d67f27b30 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -456,7 +456,7 @@ impl FromWithTcx for GenericParamDefKind { default: default.map(|x| (*x).into_tcx(tcx)), synthetic, }, - Const { did: _, ty, default } => GenericParamDefKind::Const { + Const { ty, default } => GenericParamDefKind::Const { type_: (*ty).into_tcx(tcx), default: default.map(|x| *x), }, @@ -473,9 +473,35 @@ impl FromWithTcx for WherePredicate { bounds: bounds.into_tcx(tcx), generic_params: bound_params .into_iter() - .map(|x| GenericParamDef { - name: x.0.to_string(), - kind: GenericParamDefKind::Lifetime { outlives: vec![] }, + .map(|x| { + let name = x.name.to_string(); + let kind = match x.kind { + clean::GenericParamDefKind::Lifetime { outlives } => { + GenericParamDefKind::Lifetime { + outlives: outlives.iter().map(|lt| lt.0.to_string()).collect(), + } + } + clean::GenericParamDefKind::Type { + did: _, + bounds, + default, + synthetic, + } => GenericParamDefKind::Type { + bounds: bounds + .into_iter() + .map(|bound| bound.into_tcx(tcx)) + .collect(), + default: default.map(|ty| (*ty).into_tcx(tcx)), + synthetic, + }, + clean::GenericParamDefKind::Const { ty, default } => { + GenericParamDefKind::Const { + type_: (*ty).into_tcx(tcx), + default: default.map(|d| *d), + } + } + }; + GenericParamDef { name, kind } }) .collect(), }, diff --git a/tests/rustdoc-json/non_lifetime_binders.rs b/tests/rustdoc-json/non_lifetime_binders.rs new file mode 100644 index 00000000000..ca5a008344a --- /dev/null +++ b/tests/rustdoc-json/non_lifetime_binders.rs @@ -0,0 +1,24 @@ +// ignore-tidy-linelength + +#![feature(non_lifetime_binders)] +#![allow(incomplete_features)] + +#![no_core] +#![feature(lang_items, no_core)] + +#[lang = "sized"] +pub trait Sized {} + +pub trait Trait {} + +#[lang = "phantom_data"] +struct PhantomData; + +pub struct Wrapper(PhantomData); + +// @count "$.index[*][?(@.name=='foo')].inner.generics.where_predicates[0].bound_predicate.generic_params[*]" 2 +// @is "$.index[*][?(@.name=='foo')].inner.generics.where_predicates[0].bound_predicate.generic_params[0].name" \"\'a\" +// @is "$.index[*][?(@.name=='foo')].inner.generics.where_predicates[0].bound_predicate.generic_params[0].kind" '{ "lifetime": { "outlives": [] } }' +// @is "$.index[*][?(@.name=='foo')].inner.generics.where_predicates[0].bound_predicate.generic_params[1].name" \"T\" +// @is "$.index[*][?(@.name=='foo')].inner.generics.where_predicates[0].bound_predicate.generic_params[1].kind" '{ "type": { "bounds": [], "default": null, "synthetic": false } }' +pub fn foo() where for<'a, T> &'a Wrapper: Trait {} diff --git a/tests/rustdoc/non_lifetime_binders.rs b/tests/rustdoc/non_lifetime_binders.rs new file mode 100644 index 00000000000..da9a4e6a84d --- /dev/null +++ b/tests/rustdoc/non_lifetime_binders.rs @@ -0,0 +1,9 @@ +#![feature(non_lifetime_binders)] +#![allow(incomplete_features)] + +pub trait Trait {} + +pub struct Wrapper(Box); + +// @has non_lifetime_binders/fn.foo.html '//pre' "fn foo()where for<'a, T> &'a Wrapper: Trait" +pub fn foo() where for<'a, T> &'a Wrapper: Trait {} From ef5f773bffdc2fb28bc833fa6132cbdade1dc549 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 27 Mar 2023 21:48:43 +0000 Subject: [PATCH 220/346] Check for overflow in assemble_candidates_after_normalizing_self_ty --- .../src/solve/assembly.rs | 50 ++++++++++++------- .../src/solve/search_graph/overflow.rs | 21 ++++++++ .../recursive-self-normalization-2.rs | 19 +++++++ .../recursive-self-normalization-2.stderr | 9 ++++ .../recursive-self-normalization.rs | 15 ++++++ .../recursive-self-normalization.stderr | 9 ++++ 6 files changed, 105 insertions(+), 18 deletions(-) create mode 100644 tests/ui/traits/new-solver/recursive-self-normalization-2.rs create mode 100644 tests/ui/traits/new-solver/recursive-self-normalization-2.stderr create mode 100644 tests/ui/traits/new-solver/recursive-self-normalization.rs create mode 100644 tests/ui/traits/new-solver/recursive-self-normalization.stderr diff --git a/compiler/rustc_trait_selection/src/solve/assembly.rs b/compiler/rustc_trait_selection/src/solve/assembly.rs index 4fb77d79518..0f7a0eb337b 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly.rs @@ -1,5 +1,6 @@ //! Code shared by trait and projection goals for candidate assembly. +use super::search_graph::OverflowHandler; #[cfg(doc)] use super::trait_goals::structural_traits::*; use super::{EvalCtxt, SolverMode}; @@ -279,25 +280,38 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { return }; - self.probe(|ecx| { - let normalized_ty = ecx.next_ty_infer(); - let normalizes_to_goal = goal.with( - tcx, - ty::Binder::dummy(ty::ProjectionPredicate { - projection_ty, - term: normalized_ty.into(), - }), - ); - ecx.add_goal(normalizes_to_goal); - if let Ok(_) = ecx.try_evaluate_added_goals() { - let normalized_ty = ecx.resolve_vars_if_possible(normalized_ty); - - // NOTE: Alternatively we could call `evaluate_goal` here and only have a `Normalized` candidate. - // This doesn't work as long as we use `CandidateSource` in winnowing. - let goal = goal.with(tcx, goal.predicate.with_self_ty(tcx, normalized_ty)); - candidates.extend(ecx.assemble_and_evaluate_candidates(goal)); - } + let normalized_self_candidates: Result<_, NoSolution> = self.probe(|ecx| { + ecx.with_incremented_depth( + |ecx| { + let result = ecx.evaluate_added_goals_and_make_canonical_response( + Certainty::Maybe(MaybeCause::Overflow), + )?; + Ok(vec![Candidate { source: CandidateSource::BuiltinImpl, result }]) + }, + |ecx| { + let normalized_ty = ecx.next_ty_infer(); + let normalizes_to_goal = goal.with( + tcx, + ty::Binder::dummy(ty::ProjectionPredicate { + projection_ty, + term: normalized_ty.into(), + }), + ); + ecx.add_goal(normalizes_to_goal); + let _ = ecx.try_evaluate_added_goals()?; + let normalized_ty = ecx.resolve_vars_if_possible(normalized_ty); + // NOTE: Alternatively we could call `evaluate_goal` here and only + // have a `Normalized` candidate. This doesn't work as long as we + // use `CandidateSource` in winnowing. + let goal = goal.with(tcx, goal.predicate.with_self_ty(tcx, normalized_ty)); + Ok(ecx.assemble_and_evaluate_candidates(goal)) + }, + ) }); + + if let Ok(normalized_self_candidates) = normalized_self_candidates { + candidates.extend(normalized_self_candidates); + } } fn assemble_impl_candidates>( diff --git a/compiler/rustc_trait_selection/src/solve/search_graph/overflow.rs b/compiler/rustc_trait_selection/src/solve/search_graph/overflow.rs index 7c9e63f529b..574f3e9a577 100644 --- a/compiler/rustc_trait_selection/src/solve/search_graph/overflow.rs +++ b/compiler/rustc_trait_selection/src/solve/search_graph/overflow.rs @@ -73,6 +73,27 @@ pub(in crate::solve) trait OverflowHandler<'tcx> { self.search_graph().overflow_data.deal_with_overflow(); on_overflow(self) } + + // Increment the `additional_depth` by one and evaluate `body`, or `on_overflow` + // if the depth is overflown. + fn with_incremented_depth( + &mut self, + on_overflow: impl FnOnce(&mut Self) -> T, + body: impl FnOnce(&mut Self) -> T, + ) -> T { + let depth = self.search_graph().stack.len(); + self.search_graph().overflow_data.additional_depth += 1; + + let result = if self.search_graph().overflow_data.has_overflow(depth) { + self.search_graph().overflow_data.deal_with_overflow(); + on_overflow(self) + } else { + body(self) + }; + + self.search_graph().overflow_data.additional_depth -= 1; + result + } } impl<'tcx> OverflowHandler<'tcx> for EvalCtxt<'_, 'tcx> { diff --git a/tests/ui/traits/new-solver/recursive-self-normalization-2.rs b/tests/ui/traits/new-solver/recursive-self-normalization-2.rs new file mode 100644 index 00000000000..7417d6018a1 --- /dev/null +++ b/tests/ui/traits/new-solver/recursive-self-normalization-2.rs @@ -0,0 +1,19 @@ +// compile-flags: -Ztrait-solver=next + +trait Foo1 { + type Assoc1; +} + +trait Foo2 { + type Assoc2; +} + +trait Bar {} +fn needs_bar() {} + +fn test::Assoc2> + Foo2::Assoc1>>() { + needs_bar::(); + //~^ ERROR type annotations needed +} + +fn main() {} diff --git a/tests/ui/traits/new-solver/recursive-self-normalization-2.stderr b/tests/ui/traits/new-solver/recursive-self-normalization-2.stderr new file mode 100644 index 00000000000..29cfa47a105 --- /dev/null +++ b/tests/ui/traits/new-solver/recursive-self-normalization-2.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed + --> $DIR/recursive-self-normalization-2.rs:15:5 + | +LL | needs_bar::(); + | ^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `S` declared on the function `needs_bar` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/tests/ui/traits/new-solver/recursive-self-normalization.rs b/tests/ui/traits/new-solver/recursive-self-normalization.rs new file mode 100644 index 00000000000..f3e3d71d813 --- /dev/null +++ b/tests/ui/traits/new-solver/recursive-self-normalization.rs @@ -0,0 +1,15 @@ +// compile-flags: -Ztrait-solver=next + +trait Foo { + type Assoc; +} + +trait Bar {} +fn needs_bar() {} + +fn test::Assoc>>() { + needs_bar::(); + //~^ ERROR type annotations needed +} + +fn main() {} diff --git a/tests/ui/traits/new-solver/recursive-self-normalization.stderr b/tests/ui/traits/new-solver/recursive-self-normalization.stderr new file mode 100644 index 00000000000..ba39981893d --- /dev/null +++ b/tests/ui/traits/new-solver/recursive-self-normalization.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed + --> $DIR/recursive-self-normalization.rs:11:5 + | +LL | needs_bar::(); + | ^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `S` declared on the function `needs_bar` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. From e34ad763639eda0e6174fc89ee31d808ec0d1536 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Tue, 28 Mar 2023 03:25:30 -0700 Subject: [PATCH 221/346] Remove ~const from alloc --- library/alloc/src/alloc.rs | 8 +------ library/alloc/src/borrow.rs | 5 ++-- library/alloc/src/boxed.rs | 44 +++++++++++++----------------------- library/alloc/tests/boxed.rs | 15 ------------ library/alloc/tests/lib.rs | 1 - 5 files changed, 19 insertions(+), 54 deletions(-) diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index 3a797bd5eca..6f2ba957bcd 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -14,8 +14,6 @@ use core::ptr::{self, NonNull}; #[doc(inline)] pub use core::alloc::*; -use core::marker::Destruct; - #[cfg(test)] mod tests; @@ -331,16 +329,12 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 { #[cfg_attr(not(test), lang = "box_free")] #[inline] -#[rustc_const_unstable(feature = "const_box", issue = "92521")] // This signature has to be the same as `Box`, otherwise an ICE will happen. // When an additional parameter to `Box` is added (like `A: Allocator`), this has to be added here as // well. // For example if `Box` is changed to `struct Box(Unique, A)`, // this function has to be changed to `fn box_free(Unique, A)` as well. -pub(crate) const unsafe fn box_free( - ptr: Unique, - alloc: A, -) { +pub(crate) unsafe fn box_free(ptr: Unique, alloc: A) { unsafe { let size = size_of_val(ptr.as_ref()); let align = min_align_of_val(ptr.as_ref()); diff --git a/library/alloc/src/borrow.rs b/library/alloc/src/borrow.rs index 83a1385599b..0c8c796ae9b 100644 --- a/library/alloc/src/borrow.rs +++ b/library/alloc/src/borrow.rs @@ -328,10 +328,9 @@ impl Cow<'_, B> { } #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_deref", issue = "88955")] -impl const Deref for Cow<'_, B> +impl Deref for Cow<'_, B> where - B::Owned: ~const Borrow, + B::Owned: Borrow, { type Target = B; diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index 241b11c3f5f..09041bb119b 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -159,7 +159,7 @@ use core::hash::{Hash, Hasher}; use core::iter::FromIterator; use core::iter::{FusedIterator, Iterator}; use core::marker::Tuple; -use core::marker::{Destruct, Unpin, Unsize}; +use core::marker::{Unpin, Unsize}; use core::mem; use core::ops::{ CoerceUnsized, Deref, DerefMut, DispatchFromDyn, Generator, GeneratorState, Receiver, @@ -376,12 +376,11 @@ impl Box { /// ``` #[cfg(not(no_global_oom_handling))] #[unstable(feature = "allocator_api", issue = "32838")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[must_use] #[inline] - pub const fn new_in(x: T, alloc: A) -> Self + pub fn new_in(x: T, alloc: A) -> Self where - A: ~const Allocator + ~const Destruct, + A: Allocator, { let mut boxed = Self::new_uninit_in(alloc); unsafe { @@ -406,12 +405,10 @@ impl Box { /// # Ok::<(), std::alloc::AllocError>(()) /// ``` #[unstable(feature = "allocator_api", issue = "32838")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] - pub const fn try_new_in(x: T, alloc: A) -> Result + pub fn try_new_in(x: T, alloc: A) -> Result where - T: ~const Destruct, - A: ~const Allocator + ~const Destruct, + A: Allocator, { let mut boxed = Self::try_new_uninit_in(alloc)?; unsafe { @@ -441,13 +438,12 @@ impl Box { /// assert_eq!(*five, 5) /// ``` #[unstable(feature = "allocator_api", issue = "32838")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[cfg(not(no_global_oom_handling))] #[must_use] // #[unstable(feature = "new_uninit", issue = "63291")] - pub const fn new_uninit_in(alloc: A) -> Box, A> + pub fn new_uninit_in(alloc: A) -> Box, A> where - A: ~const Allocator + ~const Destruct, + A: Allocator, { let layout = Layout::new::>(); // NOTE: Prefer match over unwrap_or_else since closure sometimes not inlineable. @@ -482,10 +478,9 @@ impl Box { /// ``` #[unstable(feature = "allocator_api", issue = "32838")] // #[unstable(feature = "new_uninit", issue = "63291")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] - pub const fn try_new_uninit_in(alloc: A) -> Result, A>, AllocError> + pub fn try_new_uninit_in(alloc: A) -> Result, A>, AllocError> where - A: ~const Allocator + ~const Destruct, + A: Allocator, { let layout = Layout::new::>(); let ptr = alloc.allocate(layout)?.cast(); @@ -513,13 +508,12 @@ impl Box { /// /// [zeroed]: mem::MaybeUninit::zeroed #[unstable(feature = "allocator_api", issue = "32838")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[cfg(not(no_global_oom_handling))] // #[unstable(feature = "new_uninit", issue = "63291")] #[must_use] - pub const fn new_zeroed_in(alloc: A) -> Box, A> + pub fn new_zeroed_in(alloc: A) -> Box, A> where - A: ~const Allocator + ~const Destruct, + A: Allocator, { let layout = Layout::new::>(); // NOTE: Prefer match over unwrap_or_else since closure sometimes not inlineable. @@ -554,10 +548,9 @@ impl Box { /// [zeroed]: mem::MaybeUninit::zeroed #[unstable(feature = "allocator_api", issue = "32838")] // #[unstable(feature = "new_uninit", issue = "63291")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] - pub const fn try_new_zeroed_in(alloc: A) -> Result, A>, AllocError> + pub fn try_new_zeroed_in(alloc: A) -> Result, A>, AllocError> where - A: ~const Allocator + ~const Destruct, + A: Allocator, { let layout = Layout::new::>(); let ptr = alloc.allocate_zeroed(layout)?.cast(); @@ -573,12 +566,11 @@ impl Box { /// construct a (pinned) `Box` in a different way than with [`Box::new_in`]. #[cfg(not(no_global_oom_handling))] #[unstable(feature = "allocator_api", issue = "32838")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[must_use] #[inline(always)] - pub const fn pin_in(x: T, alloc: A) -> Pin + pub fn pin_in(x: T, alloc: A) -> Pin where - A: 'static + ~const Allocator + ~const Destruct, + A: 'static + Allocator, { Self::into_pin(Self::new_in(x, alloc)) } @@ -605,12 +597,8 @@ impl Box { /// assert_eq!(Box::into_inner(c), 5); /// ``` #[unstable(feature = "box_into_inner", issue = "80437")] - #[rustc_const_unstable(feature = "const_box", issue = "92521")] #[inline] - pub const fn into_inner(boxed: Self) -> T - where - Self: ~const Destruct, - { + pub fn into_inner(boxed: Self) -> T { *boxed } } diff --git a/library/alloc/tests/boxed.rs b/library/alloc/tests/boxed.rs index af49826ff30..68ebd8e35ee 100644 --- a/library/alloc/tests/boxed.rs +++ b/library/alloc/tests/boxed.rs @@ -179,18 +179,3 @@ unsafe impl const Allocator for ConstAllocator { self } } - -#[test] -fn const_box() { - const VALUE: u32 = { - let mut boxed = Box::new_in(1u32, ConstAllocator); - assert!(*boxed == 1); - - *boxed = 42; - assert!(*boxed == 42); - - *Box::leak(boxed) - }; - - assert!(VALUE == 42); -} diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs index 966cf575116..c27ca642e9b 100644 --- a/library/alloc/tests/lib.rs +++ b/library/alloc/tests/lib.rs @@ -3,7 +3,6 @@ #![feature(assert_matches)] #![feature(btree_drain_filter)] #![feature(cow_is_borrowed)] -#![feature(const_box)] #![feature(const_convert)] #![feature(const_cow_is_borrowed)] #![feature(const_heap)] From 84487b212daa3916b52ab1469afba161760e3081 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 19 Mar 2023 10:00:27 +0000 Subject: [PATCH 222/346] Reformat codegen_fn_attrs. --- .../rustc_codegen_ssa/src/codegen_attrs.rs | 104 ++++++------------ 1 file changed, 33 insertions(+), 71 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 57856b4ddb1..dac7d2e89b1 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -89,44 +89,24 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { }; match name { - sym::cold => { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD; - } - sym::rustc_allocator => { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR; - } + sym::cold => codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD, + sym::rustc_allocator => codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR, sym::ffi_returns_twice => { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_RETURNS_TWICE; - } - sym::ffi_pure => { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_PURE; - } - sym::ffi_const => { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_CONST; - } - sym::rustc_nounwind => { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND; - } - sym::rustc_reallocator => { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::REALLOCATOR; - } - sym::rustc_deallocator => { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::DEALLOCATOR; + codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_RETURNS_TWICE } + sym::ffi_pure => codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_PURE, + sym::ffi_const => codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_CONST, + sym::rustc_nounwind => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND, + sym::rustc_reallocator => codegen_fn_attrs.flags |= CodegenFnAttrFlags::REALLOCATOR, + sym::rustc_deallocator => codegen_fn_attrs.flags |= CodegenFnAttrFlags::DEALLOCATOR, sym::rustc_allocator_zeroed => { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR_ZEROED; - } - sym::naked => { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED; - } - sym::no_mangle => { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE; - } - sym::no_coverage => { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_COVERAGE; + codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR_ZEROED } + sym::naked => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED, + sym::no_mangle => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE, + sym::no_coverage => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_COVERAGE, sym::rustc_std_internal_symbol => { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL; + codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL } sym::used => { let inner = attr.meta_item_list(); @@ -207,11 +187,9 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { struct_span_err!(tcx.sess, attr.span, E0775, "`#[cmse_nonsecure_entry]` is only valid for targets with the TrustZone-M extension") .emit(); } - codegen_fn_attrs.flags |= CodegenFnAttrFlags::CMSE_NONSECURE_ENTRY; - } - sym::thread_local => { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL; + codegen_fn_attrs.flags |= CodegenFnAttrFlags::CMSE_NONSECURE_ENTRY } + sym::thread_local => codegen_fn_attrs.flags |= CodegenFnAttrFlags::THREAD_LOCAL, sym::track_caller => { if !tcx.is_closure(did.to_def_id()) && let Some(fn_sig) = fn_sig() @@ -229,7 +207,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { ) .emit(); } - codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER; + codegen_fn_attrs.flags |= CodegenFnAttrFlags::TRACK_CALLER } sym::export_name => { if let Some(s) = attr.value_str() { @@ -306,20 +284,14 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { sym::link_section => { if let Some(val) = attr.value_str() { if val.as_str().bytes().any(|b| b == 0) { - let msg = format!( - "illegal null byte in link_section \ - value: `{}`", - &val - ); + let msg = format!("illegal null byte in link_section value: `{}`", &val); tcx.sess.span_err(attr.span, &msg); } else { codegen_fn_attrs.link_section = Some(val); } } } - sym::link_name => { - codegen_fn_attrs.link_name = attr.value_str(); - } + sym::link_name => codegen_fn_attrs.link_name = attr.value_str(), sym::link_ordinal => { link_ordinal_span = Some(attr.span); if let ordinal @ Some(_) = check_link_ordinal(tcx, attr) { @@ -330,37 +302,27 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { no_sanitize_span = Some(attr.span); if let Some(list) = attr.meta_item_list() { for item in list.iter() { - match item.ident().map(|ident| ident.name) { - Some(sym::address) => { + match item.name_or_empty() { + sym::address => { codegen_fn_attrs.no_sanitize |= - SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS; + SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS } - Some(sym::cfi) => { - codegen_fn_attrs.no_sanitize |= SanitizerSet::CFI; + sym::cfi => codegen_fn_attrs.no_sanitize |= SanitizerSet::CFI, + sym::kcfi => codegen_fn_attrs.no_sanitize |= SanitizerSet::KCFI, + sym::memory => codegen_fn_attrs.no_sanitize |= SanitizerSet::MEMORY, + sym::memtag => codegen_fn_attrs.no_sanitize |= SanitizerSet::MEMTAG, + sym::shadow_call_stack => { + codegen_fn_attrs.no_sanitize |= SanitizerSet::SHADOWCALLSTACK } - Some(sym::kcfi) => { - codegen_fn_attrs.no_sanitize |= SanitizerSet::KCFI; - } - Some(sym::memory) => { - codegen_fn_attrs.no_sanitize |= SanitizerSet::MEMORY; - } - Some(sym::memtag) => { - codegen_fn_attrs.no_sanitize |= SanitizerSet::MEMTAG; - } - Some(sym::shadow_call_stack) => { - codegen_fn_attrs.no_sanitize |= SanitizerSet::SHADOWCALLSTACK; - } - Some(sym::thread) => { - codegen_fn_attrs.no_sanitize |= SanitizerSet::THREAD; - } - Some(sym::hwaddress) => { - codegen_fn_attrs.no_sanitize |= SanitizerSet::HWADDRESS; + sym::thread => codegen_fn_attrs.no_sanitize |= SanitizerSet::THREAD, + sym::hwaddress => { + codegen_fn_attrs.no_sanitize |= SanitizerSet::HWADDRESS } _ => { tcx.sess - .struct_span_err(item.span(), "invalid argument for `no_sanitize`") - .note("expected one of: `address`, `cfi`, `hwaddress`, `kcfi`, `memory`, `memtag`, `shadow-call-stack`, or `thread`") - .emit(); + .struct_span_err(item.span(), "invalid argument for `no_sanitize`") + .note("expected one of: `address`, `cfi`, `hwaddress`, `kcfi`, `memory`, `memtag`, `shadow-call-stack`, or `thread`") + .emit(); } } } From 3102722ef4aa61b02f78f98403ceef588ed791ca Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 19 Mar 2023 10:04:44 +0000 Subject: [PATCH 223/346] Skip no_mangle if the item has no name. --- compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 17 ++++++++++++++++- tests/ui/attributes/no-mangle-closure.rs | 11 +++++++++++ tests/ui/attributes/no-mangle-closure.stderr | 8 ++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 tests/ui/attributes/no-mangle-closure.rs create mode 100644 tests/ui/attributes/no-mangle-closure.stderr diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index dac7d2e89b1..8542bab689d 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -103,7 +103,22 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs { codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR_ZEROED } sym::naked => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED, - sym::no_mangle => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE, + sym::no_mangle => { + if tcx.opt_item_name(did.to_def_id()).is_some() { + codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE + } else { + tcx.sess + .struct_span_err( + attr.span, + format!( + "`#[no_mangle]` cannot be used on {} {} as it has no name", + tcx.def_descr_article(did.to_def_id()), + tcx.def_descr(did.to_def_id()), + ), + ) + .emit(); + } + } sym::no_coverage => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_COVERAGE, sym::rustc_std_internal_symbol => { codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL diff --git a/tests/ui/attributes/no-mangle-closure.rs b/tests/ui/attributes/no-mangle-closure.rs new file mode 100644 index 00000000000..c76baa27f38 --- /dev/null +++ b/tests/ui/attributes/no-mangle-closure.rs @@ -0,0 +1,11 @@ +// Check that we do not ICE when `no_mangle` is applied to something that has no name. + +#![crate_type = "lib"] +#![feature(stmt_expr_attributes)] + +pub struct S([usize; 8]); + +pub fn outer_function(x: S, y: S) -> usize { + (#[no_mangle] || y.0[0])() + //~^ ERROR `#[no_mangle]` cannot be used on a closure as it has no name +} diff --git a/tests/ui/attributes/no-mangle-closure.stderr b/tests/ui/attributes/no-mangle-closure.stderr new file mode 100644 index 00000000000..949eb70510e --- /dev/null +++ b/tests/ui/attributes/no-mangle-closure.stderr @@ -0,0 +1,8 @@ +error: `#[no_mangle]` cannot be used on a closure as it has no name + --> $DIR/no-mangle-closure.rs:9:6 + | +LL | (#[no_mangle] || y.0[0])() + | ^^^^^^^^^^^^ + +error: aborting due to previous error + From 4695ddf510b8cc8727497be4702ed1859bee2cca Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 28 Mar 2023 20:26:41 +0400 Subject: [PATCH 224/346] privacy: Support `#![rustc_effective_visibility]` on the crate root --- compiler/rustc_privacy/src/lib.rs | 1 + tests/ui/privacy/effective_visibilities.rs | 1 + .../ui/privacy/effective_visibilities.stderr | 60 +++++++++++-------- 3 files changed, 38 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 3be0160d561..51a0a3e9a19 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -2149,6 +2149,7 @@ fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities { let mut check_visitor = TestReachabilityVisitor { tcx, effective_visibilities: &visitor.effective_visibilities }; + check_visitor.effective_visibility_diagnostic(CRATE_DEF_ID); tcx.hir().visit_all_item_likes_in_crate(&mut check_visitor); tcx.arena.alloc(visitor.effective_visibilities) diff --git a/tests/ui/privacy/effective_visibilities.rs b/tests/ui/privacy/effective_visibilities.rs index ff20e20d332..3e9eef46230 100644 --- a/tests/ui/privacy/effective_visibilities.rs +++ b/tests/ui/privacy/effective_visibilities.rs @@ -1,3 +1,4 @@ +#![rustc_effective_visibility] //~ ERROR Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub #![feature(rustc_attrs)] #[rustc_effective_visibility] diff --git a/tests/ui/privacy/effective_visibilities.stderr b/tests/ui/privacy/effective_visibilities.stderr index 046b6095f4e..2618fc427e9 100644 --- a/tests/ui/privacy/effective_visibilities.stderr +++ b/tests/ui/privacy/effective_visibilities.stderr @@ -1,140 +1,152 @@ +error: Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub + --> $DIR/effective_visibilities.rs:1:1 + | +LL | / #![rustc_effective_visibility] +LL | | #![feature(rustc_attrs)] +LL | | +LL | | #[rustc_effective_visibility] +... | +LL | | +LL | | fn main() {} + | |____________^ + error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate) - --> $DIR/effective_visibilities.rs:4:1 + --> $DIR/effective_visibilities.rs:5:1 | LL | mod outer { | ^^^^^^^^^ error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub - --> $DIR/effective_visibilities.rs:6:5 + --> $DIR/effective_visibilities.rs:7:5 | LL | pub mod inner1 { | ^^^^^^^^^^^^^^ error: not in the table - --> $DIR/effective_visibilities.rs:9:9 + --> $DIR/effective_visibilities.rs:10:9 | LL | extern "C" {} | ^^^^^^^^^^^^^ error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub - --> $DIR/effective_visibilities.rs:12:9 + --> $DIR/effective_visibilities.rs:13:9 | LL | pub trait PubTrait { | ^^^^^^^^^^^^^^^^^^ error: Direct: pub(self), Reexported: pub(self), Reachable: pub(self), ReachableThroughImplTrait: pub(self) - --> $DIR/effective_visibilities.rs:20:9 + --> $DIR/effective_visibilities.rs:21:9 | LL | struct PrivStruct; | ^^^^^^^^^^^^^^^^^ error: Direct: pub(self), Reexported: pub(self), Reachable: pub(self), ReachableThroughImplTrait: pub(self) - --> $DIR/effective_visibilities.rs:20:9 + --> $DIR/effective_visibilities.rs:21:9 | LL | struct PrivStruct; | ^^^^^^^^^^^^^^^^^ error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub - --> $DIR/effective_visibilities.rs:24:9 + --> $DIR/effective_visibilities.rs:25:9 | LL | pub union PubUnion { | ^^^^^^^^^^^^^^^^^^ error: Direct: pub(self), Reexported: pub(self), Reachable: pub(self), ReachableThroughImplTrait: pub(self) - --> $DIR/effective_visibilities.rs:26:13 + --> $DIR/effective_visibilities.rs:27:13 | LL | a: u8, | ^^^^^ error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub - --> $DIR/effective_visibilities.rs:28:13 + --> $DIR/effective_visibilities.rs:29:13 | LL | pub b: u8, | ^^^^^^^^^ error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub - --> $DIR/effective_visibilities.rs:32:9 + --> $DIR/effective_visibilities.rs:33:9 | LL | pub enum Enum { | ^^^^^^^^^^^^^ error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub - --> $DIR/effective_visibilities.rs:34:13 + --> $DIR/effective_visibilities.rs:35:13 | LL | A( | ^ error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub - --> $DIR/effective_visibilities.rs:34:13 + --> $DIR/effective_visibilities.rs:35:13 | LL | A( | ^ error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub - --> $DIR/effective_visibilities.rs:37:17 + --> $DIR/effective_visibilities.rs:38:17 | LL | PubUnion, | ^^^^^^^^ error: not in the table - --> $DIR/effective_visibilities.rs:43:5 + --> $DIR/effective_visibilities.rs:44:5 | LL | macro_rules! none_macro { | ^^^^^^^^^^^^^^^^^^^^^^^ error: Direct: pub(self), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub - --> $DIR/effective_visibilities.rs:49:5 + --> $DIR/effective_visibilities.rs:50:5 | LL | macro_rules! public_macro { | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub, ReachableThroughImplTrait: pub - --> $DIR/effective_visibilities.rs:54:5 + --> $DIR/effective_visibilities.rs:55:5 | LL | pub struct ReachableStruct { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub, ReachableThroughImplTrait: pub - --> $DIR/effective_visibilities.rs:56:9 + --> $DIR/effective_visibilities.rs:57:9 | LL | pub a: u8, | ^^^^^^^^^ error: Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub - --> $DIR/effective_visibilities.rs:61:9 + --> $DIR/effective_visibilities.rs:62:9 | LL | pub use outer::inner1; | ^^^^^^^^^^^^^ error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub - --> $DIR/effective_visibilities.rs:67:5 + --> $DIR/effective_visibilities.rs:68:5 | LL | pub type HalfPublicImport = u8; | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate) - --> $DIR/effective_visibilities.rs:70:5 + --> $DIR/effective_visibilities.rs:71:5 | LL | pub(crate) const HalfPublicImport: u8 = 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub - --> $DIR/effective_visibilities.rs:74:9 + --> $DIR/effective_visibilities.rs:75:9 | LL | pub use half_public_import::HalfPublicImport; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub - --> $DIR/effective_visibilities.rs:14:13 + --> $DIR/effective_visibilities.rs:15:13 | LL | const A: i32; | ^^^^^^^^^^^^ error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub - --> $DIR/effective_visibilities.rs:16:13 + --> $DIR/effective_visibilities.rs:17:13 | LL | type B; | ^^^^^^ -error: aborting due to 23 previous errors +error: aborting due to 24 previous errors From ede21e8932224f4a51d024c5d6b37189a701f2e4 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 28 Mar 2023 22:12:45 +0400 Subject: [PATCH 225/346] effvis: Merge two similar code paths --- .../src/effective_visibilities.rs | 55 ++++++++----------- 1 file changed, 22 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs index a1ae9b8a521..15df577e841 100644 --- a/compiler/rustc_resolve/src/effective_visibilities.rs +++ b/compiler/rustc_resolve/src/effective_visibilities.rs @@ -125,43 +125,32 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> { for (_, name_resolution) in resolutions.borrow().iter() { if let Some(mut binding) = name_resolution.borrow().binding() { - if !binding.is_ambiguity() { - // Set the given effective visibility level to `Level::Direct` and - // sets the rest of the `use` chain to `Level::Reexported` until - // we hit the actual exported item. - let mut parent_id = ParentId::Def(module_id); - while let NameBindingKind::Import { binding: nested_binding, .. } = binding.kind - { - let binding_id = ImportId::new_unchecked(binding); - self.update_import(binding_id, parent_id); + // Set the given effective visibility level to `Level::Direct` and + // sets the rest of the `use` chain to `Level::Reexported` until + // we hit the actual exported item. + // + // If the binding is ambiguous, put the root ambiguity binding and all reexports + // leading to it into the table. They are used by the `ambiguous_glob_reexports` + // lint. For all bindings added to the table this way `is_ambiguity` returns true. + let mut parent_id = ParentId::Def(module_id); + while let NameBindingKind::Import { binding: nested_binding, .. } = binding.kind { + let binding_id = ImportId::new_unchecked(binding); + self.update_import(binding_id, parent_id); - parent_id = ParentId::Import(binding_id); - binding = nested_binding; + if binding.ambiguity.is_some() { + // Stop at the root ambiguity, further bindings in the chain should not + // be reexported because the root ambiguity blocks any access to them. + // (Those further bindings are most likely not ambiguities themselves.) + break; } - if let Some(def_id) = binding.res().opt_def_id().and_then(|id| id.as_local()) { - self.update_def(def_id, binding.vis.expect_local(), parent_id); - } - } else { - // Put the root ambiguity binding and all reexports leading to it into the - // table. They are used by the `ambiguous_glob_reexports` lint. For all - // bindings added to the table here `is_ambiguity` returns true. - let mut parent_id = ParentId::Def(module_id); - while let NameBindingKind::Import { binding: nested_binding, .. } = binding.kind - { - let binding_id = ImportId::new_unchecked(binding); - self.update_import(binding_id, parent_id); + parent_id = ParentId::Import(binding_id); + binding = nested_binding; + } - if binding.ambiguity.is_some() { - // Stop at the root ambiguity, further bindings in the chain should not - // be reexported because the root ambiguity blocks any access to them. - // (Those further bindings are most likely not ambiguities themselves.) - break; - } - - parent_id = ParentId::Import(binding_id); - binding = nested_binding; - } + if binding.ambiguity.is_none() + && let Some(def_id) = binding.res().opt_def_id().and_then(|id| id.as_local()) { + self.update_def(def_id, binding.vis.expect_local(), parent_id); } } } From b3bfeaf765463ae634fb0658d1eb14d47a63200b Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Tue, 28 Mar 2023 22:18:02 +0400 Subject: [PATCH 226/346] effvis: Stop considering crate root its own parent It helped to reuse `update_def` for the crate root, but it created confusion and caused some mistakes when I implemented #109500 --- compiler/rustc_middle/src/middle/privacy.rs | 6 +++++- .../rustc_resolve/src/effective_visibilities.rs | 13 ++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_middle/src/middle/privacy.rs b/compiler/rustc_middle/src/middle/privacy.rs index 171cf1c1ab1..967fed687b6 100644 --- a/compiler/rustc_middle/src/middle/privacy.rs +++ b/compiler/rustc_middle/src/middle/privacy.rs @@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_macros::HashStable; use rustc_query_system::ich::StableHashingContext; -use rustc_span::def_id::LocalDefId; +use rustc_span::def_id::{LocalDefId, CRATE_DEF_ID}; use std::hash::Hash; /// Represents the levels of effective visibility an item can have. @@ -107,6 +107,10 @@ impl EffectiveVisibilities { }) } + pub fn update_root(&mut self) { + self.map.insert(CRATE_DEF_ID, EffectiveVisibility::from_vis(Visibility::Public)); + } + // FIXME: Share code with `fn update`. pub fn update_eff_vis( &mut self, diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs index 15df577e841..3673f603d16 100644 --- a/compiler/rustc_resolve/src/effective_visibilities.rs +++ b/compiler/rustc_resolve/src/effective_visibilities.rs @@ -61,7 +61,7 @@ impl Resolver<'_, '_> { // For mod items `nearest_normal_mod` returns its argument, but we actually need its parent. let normal_mod_id = self.nearest_normal_mod(def_id); if normal_mod_id == def_id { - self.tcx.opt_local_parent(def_id).map_or(Visibility::Public, Visibility::Restricted) + Visibility::Restricted(self.tcx.local_parent(def_id)) } else { Visibility::Restricted(normal_mod_id) } @@ -80,12 +80,11 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> { r, def_effective_visibilities: Default::default(), import_effective_visibilities: Default::default(), - current_private_vis: Visibility::Public, + current_private_vis: Visibility::Restricted(CRATE_DEF_ID), changed: false, }; - visitor.update(CRATE_DEF_ID, CRATE_DEF_ID); - visitor.current_private_vis = Visibility::Restricted(CRATE_DEF_ID); + visitor.def_effective_visibilities.update_root(); visitor.set_bindings_effective_visibilities(CRATE_DEF_ID); while visitor.changed { @@ -202,7 +201,7 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> { ); } - fn update(&mut self, def_id: LocalDefId, parent_id: LocalDefId) { + fn update_field(&mut self, def_id: LocalDefId, parent_id: LocalDefId) { self.update_def(def_id, self.r.visibilities[&def_id], ParentId::Def(parent_id)); } } @@ -234,14 +233,14 @@ impl<'r, 'ast, 'tcx> Visitor<'ast> for EffectiveVisibilitiesVisitor<'ast, 'r, 't for variant in variants { let variant_def_id = self.r.local_def_id(variant.id); for field in variant.data.fields() { - self.update(self.r.local_def_id(field.id), variant_def_id); + self.update_field(self.r.local_def_id(field.id), variant_def_id); } } } ast::ItemKind::Struct(ref def, _) | ast::ItemKind::Union(ref def, _) => { for field in def.fields() { - self.update(self.r.local_def_id(field.id), def_id); + self.update_field(self.r.local_def_id(field.id), def_id); } } From 27a3b10ed25b5e10491b39aba626ecd8d7f828f2 Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 28 Mar 2023 21:45:35 +0200 Subject: [PATCH 227/346] check for intercrate mode when accessing the cache --- .../src/solve/search_graph/mod.rs | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs b/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs index 9773a3eacd6..d7ad730b4a3 100644 --- a/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs @@ -47,6 +47,22 @@ impl<'tcx> SearchGraph<'tcx> { self.mode } + /// We do not use the global cache during coherence. + /// + /// The trait solver behavior is different for coherence + /// so we would have to add the solver mode to the cache key. + /// This is probably not worth it as trait solving during + /// coherence tends to already be incredibly fast. + /// + /// We could add another global cache for coherence instead, + /// but that's effort so let's only do it if necessary. + pub(super) fn should_use_global_cache(&self) -> bool { + match self.mode { + SolverMode::Normal => true, + SolverMode::Coherence => false, + } + } + pub(super) fn is_empty(&self) -> bool { self.stack.is_empty() && self.provisional_cache.is_empty() } @@ -191,8 +207,10 @@ impl<'tcx> SearchGraph<'tcx> { canonical_goal: CanonicalGoal<'tcx>, mut loop_body: impl FnMut(&mut Self) -> QueryResult<'tcx>, ) -> QueryResult<'tcx> { - if let Some(result) = tcx.new_solver_evaluation_cache.get(&canonical_goal, tcx) { - return result; + if self.should_use_global_cache() { + if let Some(result) = tcx.new_solver_evaluation_cache.get(&canonical_goal, tcx) { + return result; + } } match self.try_push_stack(tcx, canonical_goal) { @@ -252,9 +270,8 @@ impl<'tcx> SearchGraph<'tcx> { // dependencies, our non-root goal may no longer appear as child of the root goal. // // See https://github.com/rust-lang/rust/pull/108071 for some additional context. - let should_cache_globally = matches!(self.solver_mode(), SolverMode::Normal) - && (!self.overflow_data.did_overflow() || self.stack.is_empty()); - if should_cache_globally { + let can_cache = !self.overflow_data.did_overflow() || self.stack.is_empty(); + if self.should_use_global_cache() && can_cache { tcx.new_solver_evaluation_cache.insert( current_goal.goal, dep_node, From 47225e8700d8e10848b4f8df8e551fc7e438240f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 7 Mar 2023 15:42:50 +1100 Subject: [PATCH 228/346] Introduce `DeepRejectCtxt::substs_refs_may_unify`. It factors out a repeated code pattern. --- compiler/rustc_middle/src/ty/fast_reject.rs | 15 +++++++++++---- .../src/solve/project_goals.rs | 5 +---- .../src/solve/trait_goals.rs | 9 ++++----- .../rustc_trait_selection/src/traits/coherence.rs | 5 +++-- .../src/traits/select/mod.rs | 6 ++++-- 5 files changed, 23 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs index 669d50a7fda..6fe91b0cfa0 100644 --- a/compiler/rustc_middle/src/ty/fast_reject.rs +++ b/compiler/rustc_middle/src/ty/fast_reject.rs @@ -1,6 +1,6 @@ use crate::mir::Mutability; use crate::ty::subst::GenericArgKind; -use crate::ty::{self, Ty, TyCtxt, TypeVisitableExt}; +use crate::ty::{self, SubstsRef, Ty, TyCtxt, TypeVisitableExt}; use rustc_hir::def_id::DefId; use std::fmt::Debug; use std::hash::Hash; @@ -188,6 +188,15 @@ pub struct DeepRejectCtxt { } impl DeepRejectCtxt { + pub fn substs_refs_may_unify<'tcx>( + self, + obligation_substs: SubstsRef<'tcx>, + impl_substs: SubstsRef<'tcx>, + ) -> bool { + iter::zip(obligation_substs, impl_substs) + .all(|(obl, imp)| self.generic_args_may_unify(obl, imp)) + } + pub fn generic_args_may_unify<'tcx>( self, obligation_arg: ty::GenericArg<'tcx>, @@ -258,9 +267,7 @@ impl DeepRejectCtxt { }, ty::Adt(obl_def, obl_substs) => match k { &ty::Adt(impl_def, impl_substs) => { - obl_def == impl_def - && iter::zip(obl_substs, impl_substs) - .all(|(obl, imp)| self.generic_args_may_unify(obl, imp)) + obl_def == impl_def && self.substs_refs_may_unify(obl_substs, impl_substs) } _ => false, }, diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index 2b104703aab..91b56fe3522 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -17,7 +17,6 @@ use rustc_middle::ty::ProjectionPredicate; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{ToPredicate, TypeVisitableExt}; use rustc_span::{sym, DUMMY_SP}; -use std::iter; impl<'tcx> EvalCtxt<'_, 'tcx> { #[instrument(level = "debug", skip(self), ret)] @@ -144,9 +143,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { let goal_trait_ref = goal.predicate.projection_ty.trait_ref(tcx); let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap(); let drcx = DeepRejectCtxt { treat_obligation_params: TreatParams::ForLookup }; - if iter::zip(goal_trait_ref.substs, impl_trait_ref.skip_binder().substs) - .any(|(goal, imp)| !drcx.generic_args_may_unify(goal, imp)) - { + if !drcx.substs_refs_may_unify(goal_trait_ref.substs, impl_trait_ref.skip_binder().substs) { return Err(NoSolution); } diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index 718c82c8f1f..f522a8f7e65 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -1,7 +1,5 @@ //! Dealing with trait goals, i.e. `T: Trait<'a, U>`. -use std::iter; - use super::{assembly, EvalCtxt, SolverMode}; use rustc_hir::def_id::DefId; use rustc_hir::LangItem; @@ -41,9 +39,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap(); let drcx = DeepRejectCtxt { treat_obligation_params: TreatParams::ForLookup }; - if iter::zip(goal.predicate.trait_ref.substs, impl_trait_ref.skip_binder().substs) - .any(|(goal, imp)| !drcx.generic_args_may_unify(goal, imp)) - { + if !drcx.substs_refs_may_unify( + goal.predicate.trait_ref.substs, + impl_trait_ref.skip_binder().substs, + ) { return Err(NoSolution); } diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 4e5e756dc4a..d360158fdf8 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -79,8 +79,9 @@ pub fn overlapping_impls( let impl1_ref = tcx.impl_trait_ref(impl1_def_id); let impl2_ref = tcx.impl_trait_ref(impl2_def_id); let may_overlap = match (impl1_ref, impl2_ref) { - (Some(a), Some(b)) => iter::zip(a.skip_binder().substs, b.skip_binder().substs) - .all(|(arg1, arg2)| drcx.generic_args_may_unify(arg1, arg2)), + (Some(a), Some(b)) => { + drcx.substs_refs_may_unify(a.skip_binder().substs, b.skip_binder().substs) + } (None, None) => { let self_ty1 = tcx.type_of(impl1_def_id).skip_binder(); let self_ty2 = tcx.type_of(impl2_def_id).skip_binder(); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 98c3e7c13ac..827c107c8b1 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2542,8 +2542,10 @@ impl<'tcx> SelectionContext<'_, 'tcx> { // substitution if we find that any of the input types, when // simplified, do not match. let drcx = DeepRejectCtxt { treat_obligation_params: TreatParams::ForLookup }; - iter::zip(obligation.predicate.skip_binder().trait_ref.substs, impl_trait_ref.substs) - .any(|(obl, imp)| !drcx.generic_args_may_unify(obl, imp)) + !drcx.substs_refs_may_unify( + obligation.predicate.skip_binder().trait_ref.substs, + impl_trait_ref.substs, + ) } /// Normalize `where_clause_trait_ref` and try to match it against From 9fa69473fd34d9d8974ebe722e21fd6feae6c986 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 7 Mar 2023 16:02:01 +1100 Subject: [PATCH 229/346] Inline and remove `generic_args_may_unify`. It has a single callsite. --- compiler/rustc_middle/src/ty/fast_reject.rs | 31 ++++++++------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs index 6fe91b0cfa0..0a6e94248e6 100644 --- a/compiler/rustc_middle/src/ty/fast_reject.rs +++ b/compiler/rustc_middle/src/ty/fast_reject.rs @@ -193,26 +193,19 @@ impl DeepRejectCtxt { obligation_substs: SubstsRef<'tcx>, impl_substs: SubstsRef<'tcx>, ) -> bool { - iter::zip(obligation_substs, impl_substs) - .all(|(obl, imp)| self.generic_args_may_unify(obl, imp)) - } - - pub fn generic_args_may_unify<'tcx>( - self, - obligation_arg: ty::GenericArg<'tcx>, - impl_arg: ty::GenericArg<'tcx>, - ) -> bool { - match (obligation_arg.unpack(), impl_arg.unpack()) { - // We don't fast reject based on regions for now. - (GenericArgKind::Lifetime(_), GenericArgKind::Lifetime(_)) => true, - (GenericArgKind::Type(obl), GenericArgKind::Type(imp)) => { - self.types_may_unify(obl, imp) + iter::zip(obligation_substs, impl_substs).all(|(obl, imp)| { + match (obl.unpack(), imp.unpack()) { + // We don't fast reject based on regions for now. + (GenericArgKind::Lifetime(_), GenericArgKind::Lifetime(_)) => true, + (GenericArgKind::Type(obl), GenericArgKind::Type(imp)) => { + self.types_may_unify(obl, imp) + } + (GenericArgKind::Const(obl), GenericArgKind::Const(imp)) => { + self.consts_may_unify(obl, imp) + } + _ => bug!("kind mismatch: {obl} {imp}"), } - (GenericArgKind::Const(obl), GenericArgKind::Const(imp)) => { - self.consts_may_unify(obl, imp) - } - _ => bug!("kind mismatch: {obligation_arg} {impl_arg}"), - } + }) } pub fn types_may_unify<'tcx>(self, obligation_ty: Ty<'tcx>, impl_ty: Ty<'tcx>) -> bool { From 03923661afd565efbd9d000c1bc2eaa98206e2c8 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 9 Mar 2023 11:00:05 +1100 Subject: [PATCH 230/346] Inline and remove `SelectionContext::fast_reject_trait_refs`. Because it has a single call site, and it lets us move a small amount of the work outside the loop. --- .../src/traits/select/candidate_assembly.rs | 6 ++++-- .../src/traits/select/mod.rs | 16 ---------------- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 234d773d64d..47a351590b1 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -11,7 +11,7 @@ use hir::LangItem; use rustc_hir as hir; use rustc_infer::traits::ObligationCause; use rustc_infer::traits::{Obligation, SelectionError, TraitObligation}; -use rustc_middle::ty::fast_reject::TreatProjections; +use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams, TreatProjections}; use rustc_middle::ty::{self, Ty, TypeVisitableExt}; use crate::traits; @@ -344,6 +344,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { return; } + let drcx = DeepRejectCtxt { treat_obligation_params: TreatParams::ForLookup }; + let obligation_substs = obligation.predicate.skip_binder().trait_ref.substs; self.tcx().for_each_relevant_impl( obligation.predicate.def_id(), obligation.predicate.skip_binder().trait_ref.self_ty(), @@ -352,7 +354,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // consider a "quick reject". This avoids creating more types // and so forth that we need to. let impl_trait_ref = self.tcx().impl_trait_ref(impl_def_id).unwrap(); - if self.fast_reject_trait_refs(obligation, &impl_trait_ref.0) { + if !drcx.substs_refs_may_unify(obligation_substs, impl_trait_ref.0.substs) { return; } if self.reject_fn_ptr_impls( diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 827c107c8b1..3ed3dd2d20d 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -45,7 +45,6 @@ use rustc_infer::traits::TraitEngineExt; use rustc_middle::dep_graph::{DepKind, DepNodeIndex}; use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::ty::abstract_const::NotConstEvaluatable; -use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; use rustc_middle::ty::fold::BottomUpFolder; use rustc_middle::ty::relate::TypeRelation; use rustc_middle::ty::SubstsRef; @@ -2533,21 +2532,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> { Ok(Normalized { value: impl_substs, obligations: nested_obligations }) } - fn fast_reject_trait_refs( - &mut self, - obligation: &TraitObligation<'tcx>, - impl_trait_ref: &ty::TraitRef<'tcx>, - ) -> bool { - // We can avoid creating type variables and doing the full - // substitution if we find that any of the input types, when - // simplified, do not match. - let drcx = DeepRejectCtxt { treat_obligation_params: TreatParams::ForLookup }; - !drcx.substs_refs_may_unify( - obligation.predicate.skip_binder().trait_ref.substs, - impl_trait_ref.substs, - ) - } - /// Normalize `where_clause_trait_ref` and try to match it against /// `obligation`. If successful, return any predicates that /// result from the normalization. From eb7f64582dcd7c4136dee7521ba9347d889fbb58 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 28 Mar 2023 17:52:56 -0300 Subject: [PATCH 231/346] Specialization involving RPITITs is broken so ignore the diagnostic differences for them --- ...o-specializable-projection.current.stderr} | 4 +-- ...ct-to-specializable-projection.next.stderr | 34 +++++++++++++++++++ ...ont-project-to-specializable-projection.rs | 2 ++ 3 files changed, 38 insertions(+), 2 deletions(-) rename tests/ui/async-await/in-trait/{dont-project-to-specializable-projection.stderr => dont-project-to-specializable-projection.current.stderr} (85%) create mode 100644 tests/ui/async-await/in-trait/dont-project-to-specializable-projection.next.stderr diff --git a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.current.stderr similarity index 85% rename from tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr rename to tests/ui/async-await/in-trait/dont-project-to-specializable-projection.current.stderr index f71fd9980a2..1e67cdca248 100644 --- a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.stderr +++ b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.current.stderr @@ -1,5 +1,5 @@ warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes - --> $DIR/dont-project-to-specializable-projection.rs:4:12 + --> $DIR/dont-project-to-specializable-projection.rs:6:12 | LL | #![feature(async_fn_in_trait)] | ^^^^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | #![feature(async_fn_in_trait)] = note: `#[warn(incomplete_features)]` on by default error: async associated function in trait cannot be specialized - --> $DIR/dont-project-to-specializable-projection.rs:14:5 + --> $DIR/dont-project-to-specializable-projection.rs:16:5 | LL | default async fn foo(_: T) -> &'static str { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.next.stderr b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.next.stderr new file mode 100644 index 00000000000..fa89c6b77e0 --- /dev/null +++ b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.next.stderr @@ -0,0 +1,34 @@ +warning: the feature `async_fn_in_trait` is incomplete and may not be safe to use and/or cause compiler crashes + --> $DIR/dont-project-to-specializable-projection.rs:6:12 + | +LL | #![feature(async_fn_in_trait)] + | ^^^^^^^^^^^^^^^^^ + | + = note: see issue #91611 for more information + = note: `#[warn(incomplete_features)]` on by default + +error[E0053]: method `foo` has an incompatible type for trait + --> $DIR/dont-project-to-specializable-projection.rs:16:35 + | +LL | default async fn foo(_: T) -> &'static str { + | ^^^^^^^^^^^^ expected associated type, found future + | +note: type in trait + --> $DIR/dont-project-to-specializable-projection.rs:12:27 + | +LL | async fn foo(_: T) -> &'static str; + | ^^^^^^^^^^^^ + = note: expected signature `fn(_) -> impl Future` + found signature `fn(_) -> impl Future` + +error: async associated function in trait cannot be specialized + --> $DIR/dont-project-to-specializable-projection.rs:16:5 + | +LL | default async fn foo(_: T) -> &'static str { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: specialization behaves in inconsistent and surprising ways with `#![feature(async_fn_in_trait)]`, and for now is disallowed + +error: aborting due to 2 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0053`. diff --git a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs index afd3db5e052..7183eaccc93 100644 --- a/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs +++ b/tests/ui/async-await/in-trait/dont-project-to-specializable-projection.rs @@ -1,5 +1,7 @@ // edition: 2021 // known-bug: #108309 +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(async_fn_in_trait)] #![feature(min_specialization)] From f20af8d43d9193a2f865ae0361e80158bce0a0a2 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 25 Mar 2023 14:32:31 -0700 Subject: [PATCH 232/346] Simplify transmutes in MIR InstCombine Thanks to the combination of #108246 and #108442 it could already remove identity transmutes. With this PR, it can also simplify them to `IntToInt` casts, `Discriminant` reads, or `Field` projections. --- .../rustc_mir_transform/src/instcombine.rs | 54 +++++- ...transmutes.adt_transmutes.InstCombine.diff | 158 ++++++++++++++++++ ...mutes.identity_transmutes.InstCombine.diff | 43 +++++ ...smutes.integer_transmutes.InstCombine.diff | 24 +++ tests/mir-opt/combine_transmutes.rs | 65 +++++++ 5 files changed, 340 insertions(+), 4 deletions(-) create mode 100644 tests/mir-opt/combine_transmutes.adt_transmutes.InstCombine.diff create mode 100644 tests/mir-opt/combine_transmutes.identity_transmutes.InstCombine.diff create mode 100644 tests/mir-opt/combine_transmutes.integer_transmutes.InstCombine.diff create mode 100644 tests/mir-opt/combine_transmutes.rs diff --git a/compiler/rustc_mir_transform/src/instcombine.rs b/compiler/rustc_mir_transform/src/instcombine.rs index c926390aa2b..c9750e899a5 100644 --- a/compiler/rustc_mir_transform/src/instcombine.rs +++ b/compiler/rustc_mir_transform/src/instcombine.rs @@ -3,10 +3,12 @@ use crate::MirPass; use rustc_hir::Mutability; use rustc_middle::mir::{ - BinOp, Body, Constant, ConstantKind, LocalDecls, Operand, Place, ProjectionElem, Rvalue, - SourceInfo, Statement, StatementKind, SwitchTargets, Terminator, TerminatorKind, UnOp, + BinOp, Body, CastKind, Constant, ConstantKind, Field, LocalDecls, Operand, Place, + ProjectionElem, Rvalue, SourceInfo, Statement, StatementKind, SwitchTargets, Terminator, + TerminatorKind, UnOp, }; use rustc_middle::ty::layout::ValidityRequirement; +use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, ParamEnv, SubstsRef, Ty, TyCtxt}; use rustc_span::symbol::Symbol; @@ -145,9 +147,53 @@ impl<'tcx> InstCombineContext<'tcx, '_> { } fn combine_cast(&self, _source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) { - if let Rvalue::Cast(_kind, operand, ty) = rvalue { - if operand.ty(self.local_decls, self.tcx) == *ty { + if let Rvalue::Cast(kind, operand, cast_ty) = rvalue { + let operand_ty = operand.ty(self.local_decls, self.tcx); + if operand_ty == *cast_ty { *rvalue = Rvalue::Use(operand.clone()); + } else if *kind == CastKind::Transmute { + // Transmuting an integer to another integer is just a signedness cast + if let (ty::Int(int), ty::Uint(uint)) | (ty::Uint(uint), ty::Int(int)) = (operand_ty.kind(), cast_ty.kind()) + && int.bit_width() == uint.bit_width() + { + // The width check isn't strictly necessary, as different widths + // are UB and thus we'd be allowed to turn it into a cast anyway. + // But let's keep the UB around for codegen to exploit later. + // (If `CastKind::Transmute` ever becomes *not* UB for mismatched sizes, + // then the width check is necessary for big-endian correctness.) + *kind = CastKind::IntToInt; + return; + } + + // Transmuting a fieldless enum to its repr is a discriminant read + if let ty::Adt(adt_def, ..) = operand_ty.kind() + && adt_def.is_enum() + && adt_def.is_payloadfree() + && let Some(place) = operand.place() + && let Some(repr_int) = adt_def.repr().int + && repr_int.to_ty(self.tcx) == *cast_ty + { + *rvalue = Rvalue::Discriminant(place); + return; + } + + // Transmuting a transparent struct/union to a field's type is a projection + if let ty::Adt(adt_def, substs) = operand_ty.kind() + && adt_def.repr().transparent() + && (adt_def.is_struct() || adt_def.is_union()) + && let Some(place) = operand.place() + { + let variant = adt_def.non_enum_variant(); + for (i, field) in variant.fields.iter().enumerate() { + let field_ty = field.ty(self.tcx, substs); + if field_ty == *cast_ty { + let place = place.project_deeper(&[ProjectionElem::Field(Field::from_usize(i), *cast_ty)], self.tcx); + let operand = if operand.is_move() { Operand::Move(place) } else { Operand::Copy(place) }; + *rvalue = Rvalue::Use(operand); + return; + } + } + } } } } diff --git a/tests/mir-opt/combine_transmutes.adt_transmutes.InstCombine.diff b/tests/mir-opt/combine_transmutes.adt_transmutes.InstCombine.diff new file mode 100644 index 00000000000..c44a14075ef --- /dev/null +++ b/tests/mir-opt/combine_transmutes.adt_transmutes.InstCombine.diff @@ -0,0 +1,158 @@ +- // MIR for `adt_transmutes` before InstCombine ++ // MIR for `adt_transmutes` after InstCombine + + fn adt_transmutes() -> () { + let mut _0: (); // return place in scope 0 at $DIR/combine_transmutes.rs:+0:32: +0:32 + let _1: u8; // in scope 0 at $DIR/combine_transmutes.rs:+1:9: +1:11 + let mut _2: EnumNoRepr; // in scope 0 at $DIR/combine_transmutes.rs:+1:28: +1:41 + let mut _4: EnumNoRepr; // in scope 0 at $DIR/combine_transmutes.rs:+2:28: +2:41 + let mut _6: EnumReprIsize; // in scope 0 at $DIR/combine_transmutes.rs:+3:31: +3:47 + let mut _8: EnumReprIsize; // in scope 0 at $DIR/combine_transmutes.rs:+4:31: +4:47 + let mut _10: std::cmp::Ordering; // in scope 0 at $DIR/combine_transmutes.rs:+5:28: +5:52 + let mut _12: std::cmp::Ordering; // in scope 0 at $DIR/combine_transmutes.rs:+6:28: +6:52 + let mut _14: std::option::Option; // in scope 0 at $DIR/combine_transmutes.rs:+7:28: +7:58 + let mut _16: std::num::Wrapping; // in scope 0 at $DIR/combine_transmutes.rs:+8:29: +8:54 + let mut _18: std::num::Wrapping; // in scope 0 at $DIR/combine_transmutes.rs:+9:29: +9:54 + let mut _20: Union32; // in scope 0 at $DIR/combine_transmutes.rs:+10:29: +10:47 + let mut _22: Union32; // in scope 0 at $DIR/combine_transmutes.rs:+11:29: +11:47 + let mut _24: std::mem::MaybeUninit; // in scope 0 at $DIR/combine_transmutes.rs:+12:46: +12:77 + scope 1 { + debug _a => _1; // in scope 1 at $DIR/combine_transmutes.rs:+1:9: +1:11 + let _3: i8; // in scope 1 at $DIR/combine_transmutes.rs:+2:9: +2:11 + scope 2 { + debug _a => _3; // in scope 2 at $DIR/combine_transmutes.rs:+2:9: +2:11 + let _5: usize; // in scope 2 at $DIR/combine_transmutes.rs:+3:9: +3:11 + scope 3 { + debug _a => _5; // in scope 3 at $DIR/combine_transmutes.rs:+3:9: +3:11 + let _7: isize; // in scope 3 at $DIR/combine_transmutes.rs:+4:9: +4:11 + scope 4 { + debug _a => _7; // in scope 4 at $DIR/combine_transmutes.rs:+4:9: +4:11 + let _9: u8; // in scope 4 at $DIR/combine_transmutes.rs:+5:9: +5:11 + scope 5 { + debug _a => _9; // in scope 5 at $DIR/combine_transmutes.rs:+5:9: +5:11 + let _11: i8; // in scope 5 at $DIR/combine_transmutes.rs:+6:9: +6:11 + scope 6 { + debug _a => _11; // in scope 6 at $DIR/combine_transmutes.rs:+6:9: +6:11 + let _13: u8; // in scope 6 at $DIR/combine_transmutes.rs:+7:9: +7:11 + scope 7 { + debug _a => _13; // in scope 7 at $DIR/combine_transmutes.rs:+7:9: +7:11 + let _15: i16; // in scope 7 at $DIR/combine_transmutes.rs:+8:9: +8:11 + scope 8 { + debug _a => _15; // in scope 8 at $DIR/combine_transmutes.rs:+8:9: +8:11 + let _17: u16; // in scope 8 at $DIR/combine_transmutes.rs:+9:9: +9:11 + scope 9 { + debug _a => _17; // in scope 9 at $DIR/combine_transmutes.rs:+9:9: +9:11 + let _19: u32; // in scope 9 at $DIR/combine_transmutes.rs:+10:9: +10:11 + scope 10 { + debug _a => _19; // in scope 10 at $DIR/combine_transmutes.rs:+10:9: +10:11 + let _21: i32; // in scope 10 at $DIR/combine_transmutes.rs:+11:9: +11:11 + scope 11 { + debug _a => _21; // in scope 11 at $DIR/combine_transmutes.rs:+11:9: +11:11 + let _23: std::mem::ManuallyDrop; // in scope 11 at $DIR/combine_transmutes.rs:+12:9: +12:11 + scope 12 { + debug _a => _23; // in scope 12 at $DIR/combine_transmutes.rs:+12:9: +12:11 + } + } + } + } + } + } + } + } + } + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/combine_transmutes.rs:+1:9: +1:11 + StorageLive(_2); // scope 0 at $DIR/combine_transmutes.rs:+1:28: +1:41 + _2 = EnumNoRepr::A; // scope 0 at $DIR/combine_transmutes.rs:+1:28: +1:41 + _1 = move _2 as u8 (Transmute); // scope 0 at $DIR/combine_transmutes.rs:+1:18: +1:42 + StorageDead(_2); // scope 0 at $DIR/combine_transmutes.rs:+1:41: +1:42 + StorageLive(_3); // scope 1 at $DIR/combine_transmutes.rs:+2:9: +2:11 + StorageLive(_4); // scope 1 at $DIR/combine_transmutes.rs:+2:28: +2:41 + _4 = EnumNoRepr::B; // scope 1 at $DIR/combine_transmutes.rs:+2:28: +2:41 + _3 = move _4 as i8 (Transmute); // scope 1 at $DIR/combine_transmutes.rs:+2:18: +2:42 + StorageDead(_4); // scope 1 at $DIR/combine_transmutes.rs:+2:41: +2:42 + StorageLive(_5); // scope 2 at $DIR/combine_transmutes.rs:+3:9: +3:11 + StorageLive(_6); // scope 2 at $DIR/combine_transmutes.rs:+3:31: +3:47 + _6 = EnumReprIsize::A; // scope 2 at $DIR/combine_transmutes.rs:+3:31: +3:47 + _5 = move _6 as usize (Transmute); // scope 2 at $DIR/combine_transmutes.rs:+3:21: +3:48 + StorageDead(_6); // scope 2 at $DIR/combine_transmutes.rs:+3:47: +3:48 + StorageLive(_7); // scope 3 at $DIR/combine_transmutes.rs:+4:9: +4:11 + StorageLive(_8); // scope 3 at $DIR/combine_transmutes.rs:+4:31: +4:47 + _8 = EnumReprIsize::B; // scope 3 at $DIR/combine_transmutes.rs:+4:31: +4:47 +- _7 = move _8 as isize (Transmute); // scope 3 at $DIR/combine_transmutes.rs:+4:21: +4:48 ++ _7 = discriminant(_8); // scope 3 at $DIR/combine_transmutes.rs:+4:21: +4:48 + StorageDead(_8); // scope 3 at $DIR/combine_transmutes.rs:+4:47: +4:48 + StorageLive(_9); // scope 4 at $DIR/combine_transmutes.rs:+5:9: +5:11 + StorageLive(_10); // scope 4 at $DIR/combine_transmutes.rs:+5:28: +5:52 + _10 = Less; // scope 4 at $DIR/combine_transmutes.rs:+5:28: +5:52 + _9 = move _10 as u8 (Transmute); // scope 4 at $DIR/combine_transmutes.rs:+5:18: +5:53 + StorageDead(_10); // scope 4 at $DIR/combine_transmutes.rs:+5:52: +5:53 + StorageLive(_11); // scope 5 at $DIR/combine_transmutes.rs:+6:9: +6:11 + StorageLive(_12); // scope 5 at $DIR/combine_transmutes.rs:+6:28: +6:52 + _12 = Less; // scope 5 at $DIR/combine_transmutes.rs:+6:28: +6:52 +- _11 = move _12 as i8 (Transmute); // scope 5 at $DIR/combine_transmutes.rs:+6:18: +6:53 ++ _11 = discriminant(_12); // scope 5 at $DIR/combine_transmutes.rs:+6:18: +6:53 + StorageDead(_12); // scope 5 at $DIR/combine_transmutes.rs:+6:52: +6:53 + StorageLive(_13); // scope 6 at $DIR/combine_transmutes.rs:+7:9: +7:11 + StorageLive(_14); // scope 6 at $DIR/combine_transmutes.rs:+7:28: +7:58 + _14 = Option::::Some(const _); // scope 6 at $DIR/combine_transmutes.rs:+7:28: +7:58 + // mir::Constant + // + span: $DIR/combine_transmutes.rs:41:33: 41:57 + // + literal: Const { ty: NonZeroU8, val: Unevaluated(NonZeroU8::MAX, [], None) } + _13 = move _14 as u8 (Transmute); // scope 6 at $DIR/combine_transmutes.rs:+7:18: +7:59 + StorageDead(_14); // scope 6 at $DIR/combine_transmutes.rs:+7:58: +7:59 + StorageLive(_15); // scope 7 at $DIR/combine_transmutes.rs:+8:9: +8:11 + StorageLive(_16); // scope 7 at $DIR/combine_transmutes.rs:+8:29: +8:54 + _16 = Wrapping::(const 0_i16); // scope 7 at $DIR/combine_transmutes.rs:+8:29: +8:54 +- _15 = move _16 as i16 (Transmute); // scope 7 at $DIR/combine_transmutes.rs:+8:19: +8:55 ++ _15 = move (_16.0: i16); // scope 7 at $DIR/combine_transmutes.rs:+8:19: +8:55 + StorageDead(_16); // scope 7 at $DIR/combine_transmutes.rs:+8:54: +8:55 + StorageLive(_17); // scope 8 at $DIR/combine_transmutes.rs:+9:9: +9:11 + StorageLive(_18); // scope 8 at $DIR/combine_transmutes.rs:+9:29: +9:54 + _18 = Wrapping::(const 0_i16); // scope 8 at $DIR/combine_transmutes.rs:+9:29: +9:54 + _17 = move _18 as u16 (Transmute); // scope 8 at $DIR/combine_transmutes.rs:+9:19: +9:55 + StorageDead(_18); // scope 8 at $DIR/combine_transmutes.rs:+9:54: +9:55 + StorageLive(_19); // scope 9 at $DIR/combine_transmutes.rs:+10:9: +10:11 + StorageLive(_20); // scope 9 at $DIR/combine_transmutes.rs:+10:29: +10:47 + _20 = Union32 { u32: const 0_i32 }; // scope 9 at $DIR/combine_transmutes.rs:+10:29: +10:47 + _19 = move _20 as u32 (Transmute); // scope 9 at $DIR/combine_transmutes.rs:+10:19: +10:48 + StorageDead(_20); // scope 9 at $DIR/combine_transmutes.rs:+10:47: +10:48 + StorageLive(_21); // scope 10 at $DIR/combine_transmutes.rs:+11:9: +11:11 + StorageLive(_22); // scope 10 at $DIR/combine_transmutes.rs:+11:29: +11:47 + _22 = Union32 { u32: const 0_u32 }; // scope 10 at $DIR/combine_transmutes.rs:+11:29: +11:47 + _21 = move _22 as i32 (Transmute); // scope 10 at $DIR/combine_transmutes.rs:+11:19: +11:48 + StorageDead(_22); // scope 10 at $DIR/combine_transmutes.rs:+11:47: +11:48 + StorageLive(_23); // scope 11 at $DIR/combine_transmutes.rs:+12:9: +12:11 + StorageLive(_24); // scope 11 at $DIR/combine_transmutes.rs:+12:46: +12:77 + _24 = MaybeUninit::::uninit() -> bb1; // scope 11 at $DIR/combine_transmutes.rs:+12:46: +12:77 + // mir::Constant + // + span: $DIR/combine_transmutes.rs:46:46: 46:75 + // + user_ty: UserType(23) + // + literal: Const { ty: fn() -> MaybeUninit {MaybeUninit::::uninit}, val: Value() } + } + + bb1: { +- _23 = move _24 as std::mem::ManuallyDrop (Transmute); // scope 11 at $DIR/combine_transmutes.rs:+12:36: +12:78 ++ _23 = move (_24.1: std::mem::ManuallyDrop); // scope 11 at $DIR/combine_transmutes.rs:+12:36: +12:78 + StorageDead(_24); // scope 11 at $DIR/combine_transmutes.rs:+12:77: +12:78 + _0 = const (); // scope 0 at $DIR/combine_transmutes.rs:+0:32: +13:2 + StorageDead(_23); // scope 11 at $DIR/combine_transmutes.rs:+13:1: +13:2 + StorageDead(_21); // scope 10 at $DIR/combine_transmutes.rs:+13:1: +13:2 + StorageDead(_19); // scope 9 at $DIR/combine_transmutes.rs:+13:1: +13:2 + StorageDead(_17); // scope 8 at $DIR/combine_transmutes.rs:+13:1: +13:2 + StorageDead(_15); // scope 7 at $DIR/combine_transmutes.rs:+13:1: +13:2 + StorageDead(_13); // scope 6 at $DIR/combine_transmutes.rs:+13:1: +13:2 + StorageDead(_11); // scope 5 at $DIR/combine_transmutes.rs:+13:1: +13:2 + StorageDead(_9); // scope 4 at $DIR/combine_transmutes.rs:+13:1: +13:2 + StorageDead(_7); // scope 3 at $DIR/combine_transmutes.rs:+13:1: +13:2 + StorageDead(_5); // scope 2 at $DIR/combine_transmutes.rs:+13:1: +13:2 + StorageDead(_3); // scope 1 at $DIR/combine_transmutes.rs:+13:1: +13:2 + StorageDead(_1); // scope 0 at $DIR/combine_transmutes.rs:+13:1: +13:2 + return; // scope 0 at $DIR/combine_transmutes.rs:+13:2: +13:2 + } + } + diff --git a/tests/mir-opt/combine_transmutes.identity_transmutes.InstCombine.diff b/tests/mir-opt/combine_transmutes.identity_transmutes.InstCombine.diff new file mode 100644 index 00000000000..c83c9f5acf4 --- /dev/null +++ b/tests/mir-opt/combine_transmutes.identity_transmutes.InstCombine.diff @@ -0,0 +1,43 @@ +- // MIR for `identity_transmutes` before InstCombine ++ // MIR for `identity_transmutes` after InstCombine + + fn identity_transmutes() -> () { + let mut _0: (); // return place in scope 0 at $DIR/combine_transmutes.rs:+0:37: +0:37 + let _1: i32; // in scope 0 at $DIR/combine_transmutes.rs:+2:9: +2:11 + let mut _3: std::vec::Vec; // in scope 0 at $DIR/combine_transmutes.rs:+3:46: +3:56 + scope 1 { + debug _a => _1; // in scope 1 at $DIR/combine_transmutes.rs:+2:9: +2:11 + let _2: std::vec::Vec; // in scope 1 at $DIR/combine_transmutes.rs:+3:9: +3:11 + scope 2 { + debug _a => _2; // in scope 2 at $DIR/combine_transmutes.rs:+3:9: +3:11 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/combine_transmutes.rs:+2:9: +2:11 +- _1 = const 1_i32 as i32 (Transmute); // scope 0 at $DIR/combine_transmutes.rs:+2:14: +2:38 ++ _1 = const 1_i32; // scope 0 at $DIR/combine_transmutes.rs:+2:14: +2:38 + StorageLive(_2); // scope 1 at $DIR/combine_transmutes.rs:+3:9: +3:11 + StorageLive(_3); // scope 1 at $DIR/combine_transmutes.rs:+3:46: +3:56 + _3 = Vec::::new() -> bb1; // scope 1 at $DIR/combine_transmutes.rs:+3:46: +3:56 + // mir::Constant + // + span: $DIR/combine_transmutes.rs:15:46: 15:54 + // + user_ty: UserType(0) + // + literal: Const { ty: fn() -> Vec {Vec::::new}, val: Value() } + } + + bb1: { +- _2 = move _3 as std::vec::Vec (Transmute); // scope 1 at $DIR/combine_transmutes.rs:+3:14: +3:57 ++ _2 = move _3; // scope 1 at $DIR/combine_transmutes.rs:+3:14: +3:57 + StorageDead(_3); // scope 1 at $DIR/combine_transmutes.rs:+3:56: +3:57 + _0 = const (); // scope 0 at $DIR/combine_transmutes.rs:+0:37: +4:2 + drop(_2) -> bb2; // scope 1 at $DIR/combine_transmutes.rs:+4:1: +4:2 + } + + bb2: { + StorageDead(_2); // scope 1 at $DIR/combine_transmutes.rs:+4:1: +4:2 + StorageDead(_1); // scope 0 at $DIR/combine_transmutes.rs:+4:1: +4:2 + return; // scope 0 at $DIR/combine_transmutes.rs:+4:2: +4:2 + } + } + diff --git a/tests/mir-opt/combine_transmutes.integer_transmutes.InstCombine.diff b/tests/mir-opt/combine_transmutes.integer_transmutes.InstCombine.diff new file mode 100644 index 00000000000..8de7c34e6b2 --- /dev/null +++ b/tests/mir-opt/combine_transmutes.integer_transmutes.InstCombine.diff @@ -0,0 +1,24 @@ +- // MIR for `integer_transmutes` before InstCombine ++ // MIR for `integer_transmutes` after InstCombine + + fn integer_transmutes() -> () { + let mut _0: (); // return place in scope 0 at $DIR/combine_transmutes.rs:+0:36: +0:36 + let mut _1: u32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _2: i64; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _3: i64; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _4: u32; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + let mut _5: usize; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + + bb0: { +- _1 = const 1_i32 as u32 (Transmute); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL ++ _1 = const 1_i32 as u32 (IntToInt); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + _2 = const 1_i32 as i64 (Transmute); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL +- _3 = const 1_u64 as i64 (Transmute); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL ++ _3 = const 1_u64 as i64 (IntToInt); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + _4 = const 1_u64 as u32 (Transmute); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL +- _5 = const 1_isize as usize (Transmute); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL ++ _5 = const 1_isize as usize (IntToInt); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL + return; // scope 0 at $DIR/combine_transmutes.rs:+8:13: +8:21 + } + } + diff --git a/tests/mir-opt/combine_transmutes.rs b/tests/mir-opt/combine_transmutes.rs new file mode 100644 index 00000000000..de9b9c35c03 --- /dev/null +++ b/tests/mir-opt/combine_transmutes.rs @@ -0,0 +1,65 @@ +// unit-test: InstCombine +// compile-flags: -C panic=abort + +#![crate_type = "lib"] +#![feature(core_intrinsics)] +#![feature(custom_mir)] + +use std::intrinsics::mir::*; +use std::mem::{MaybeUninit, ManuallyDrop, transmute}; + +// EMIT_MIR combine_transmutes.identity_transmutes.InstCombine.diff +pub unsafe fn identity_transmutes() { + // These are nops and should be removed + let _a = transmute::(1); + let _a = transmute::, Vec>(Vec::new()); +} + +#[custom_mir(dialect = "runtime", phase = "initial")] +// EMIT_MIR combine_transmutes.integer_transmutes.InstCombine.diff +pub unsafe fn integer_transmutes() { + mir! { + { + let A = CastTransmute::(1); // Can be a cast + let B = CastTransmute::(1); // UB + let C = CastTransmute::(1); // Can be a cast + let D = CastTransmute::(1); // UB + let E = CastTransmute::(1); // Can be a cast + Return() + } + } +} + +// EMIT_MIR combine_transmutes.adt_transmutes.InstCombine.diff +pub unsafe fn adt_transmutes() { + let _a: u8 = transmute(EnumNoRepr::A); + let _a: i8 = transmute(EnumNoRepr::B); + let _a: usize = transmute(EnumReprIsize::A); + let _a: isize = transmute(EnumReprIsize::B); + let _a: u8 = transmute(std::cmp::Ordering::Less); + let _a: i8 = transmute(std::cmp::Ordering::Less); + let _a: u8 = transmute(Some(std::num::NonZeroU8::MAX)); + let _a: i16 = transmute(std::num::Wrapping(0_i16)); + let _a: u16 = transmute(std::num::Wrapping(0_i16)); + let _a: u32 = transmute(Union32 { i32: 0 }); + let _a: i32 = transmute(Union32 { u32: 0 }); + let _a: ManuallyDrop = transmute(MaybeUninit::::uninit()); +} + +#[inline(always)] +#[custom_mir(dialect = "runtime", phase = "initial")] +const unsafe fn mir_transmute(x: T) -> U { + mir!{ + { + RET = CastTransmute(x); + Return() + } + } +} + +pub enum EnumNoRepr { A, B, C } + +#[repr(isize)] +pub enum EnumReprIsize { A, B, C } + +pub union Union32 { u32: u32, i32: i32 } From 9f17ede4acd28df8c0468984d53b965bfbaea8dc Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Tue, 28 Mar 2023 21:37:15 -0400 Subject: [PATCH 233/346] Raise an aborting signal without UB --- tests/ui/process/signal-exit-status.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/ui/process/signal-exit-status.rs b/tests/ui/process/signal-exit-status.rs index 9519ed7b4c7..0f05f916cb9 100644 --- a/tests/ui/process/signal-exit-status.rs +++ b/tests/ui/process/signal-exit-status.rs @@ -4,14 +4,16 @@ // ignore-windows // ignore-fuchsia code returned as ZX_TASK_RETCODE_EXCEPTION_KILL, FIXME (#58590) +#![feature(core_intrinsics)] + use std::env; use std::process::Command; pub fn main() { let args: Vec = env::args().collect(); if args.len() >= 2 && args[1] == "signal" { - // Raise a segfault. - unsafe { *(1 as *mut isize) = 0; } + // Raise an aborting signal without UB + core::intrinsics::abort(); } else { let status = Command::new(&args[0]).arg("signal").status().unwrap(); assert!(status.code().is_none()); From dde26b31b6b625496e8dc0933e231c27f35b8933 Mon Sep 17 00:00:00 2001 From: Mu42 Date: Wed, 29 Mar 2023 09:56:28 +0800 Subject: [PATCH 234/346] add run-rustfix --- tests/ui/lint/issue-109529.fixed | 6 ++++++ tests/ui/lint/issue-109529.rs | 2 ++ tests/ui/lint/issue-109529.stderr | 4 ++-- 3 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 tests/ui/lint/issue-109529.fixed diff --git a/tests/ui/lint/issue-109529.fixed b/tests/ui/lint/issue-109529.fixed new file mode 100644 index 00000000000..5ad489073ee --- /dev/null +++ b/tests/ui/lint/issue-109529.fixed @@ -0,0 +1,6 @@ +// run-rustfix + +fn main() { + for _ in 0..=255 as u8 {} //~ ERROR range endpoint is out of range + for _ in 0..=(255 as u8) {} //~ ERROR range endpoint is out of range +} diff --git a/tests/ui/lint/issue-109529.rs b/tests/ui/lint/issue-109529.rs index c9b4da4b26e..383d7bc4cf3 100644 --- a/tests/ui/lint/issue-109529.rs +++ b/tests/ui/lint/issue-109529.rs @@ -1,3 +1,5 @@ +// run-rustfix + fn main() { for _ in 0..256 as u8 {} //~ ERROR range endpoint is out of range for _ in 0..(256 as u8) {} //~ ERROR range endpoint is out of range diff --git a/tests/ui/lint/issue-109529.stderr b/tests/ui/lint/issue-109529.stderr index 15b259ad55e..9e857d1b0ab 100644 --- a/tests/ui/lint/issue-109529.stderr +++ b/tests/ui/lint/issue-109529.stderr @@ -1,5 +1,5 @@ error: range endpoint is out of range for `u8` - --> $DIR/issue-109529.rs:2:14 + --> $DIR/issue-109529.rs:4:14 | LL | for _ in 0..256 as u8 {} | ------^^^^^^ @@ -9,7 +9,7 @@ LL | for _ in 0..256 as u8 {} = note: `#[deny(overflowing_literals)]` on by default error: range endpoint is out of range for `u8` - --> $DIR/issue-109529.rs:3:14 + --> $DIR/issue-109529.rs:5:14 | LL | for _ in 0..(256 as u8) {} | ^^^^^^^^^^^^^^ From c5da0619d102493ce39bc36554e14191e964c1b4 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Tue, 28 Mar 2023 20:21:23 -0700 Subject: [PATCH 235/346] Fix mismatched punctuation in Debug impl of AttrId --- compiler/rustc_ast/src/ast.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index ab8b7f632e8..cc0fc7b8358 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2570,7 +2570,7 @@ pub enum AttrStyle { rustc_index::newtype_index! { #[custom_encodable] - #[debug_format = "AttrId({})]"] + #[debug_format = "AttrId({})"] pub struct AttrId {} } From 51c93553d4344472f2e291b3a4f110f884062a37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Fri, 3 Feb 2023 08:05:59 +0100 Subject: [PATCH 236/346] Test that TLS access works outside of the dylib it's defined in --- tests/ui/thread-local/auxiliary/tls-export.rs | 16 ++++++++++++++++ tests/ui/thread-local/auxiliary/tls-rlib.rs | 14 ++++++++++++++ tests/ui/thread-local/tls-dylib-access.rs | 19 +++++++++++++++++++ 3 files changed, 49 insertions(+) create mode 100644 tests/ui/thread-local/auxiliary/tls-export.rs create mode 100644 tests/ui/thread-local/auxiliary/tls-rlib.rs create mode 100644 tests/ui/thread-local/tls-dylib-access.rs diff --git a/tests/ui/thread-local/auxiliary/tls-export.rs b/tests/ui/thread-local/auxiliary/tls-export.rs new file mode 100644 index 00000000000..aab48f871c9 --- /dev/null +++ b/tests/ui/thread-local/auxiliary/tls-export.rs @@ -0,0 +1,16 @@ +#![crate_type = "dylib"] +#![feature(thread_local)] +#![feature(cfg_target_thread_local)] +#![cfg(target_thread_local)] + +extern crate tls_rlib; + +pub use tls_rlib::*; + +#[thread_local] +pub static FOO: bool = true; + +#[inline(never)] +pub fn foo_addr() -> usize { + &FOO as *const bool as usize +} diff --git a/tests/ui/thread-local/auxiliary/tls-rlib.rs b/tests/ui/thread-local/auxiliary/tls-rlib.rs new file mode 100644 index 00000000000..0fbcf387b5f --- /dev/null +++ b/tests/ui/thread-local/auxiliary/tls-rlib.rs @@ -0,0 +1,14 @@ +// no-prefer-dynamic + +#![crate_type = "rlib"] +#![feature(thread_local)] +#![feature(cfg_target_thread_local)] +#![cfg(target_thread_local)] + +#[thread_local] +pub static BAR: bool = true; + +#[inline(never)] +pub fn bar_addr() -> usize { + &BAR as *const bool as usize +} diff --git a/tests/ui/thread-local/tls-dylib-access.rs b/tests/ui/thread-local/tls-dylib-access.rs new file mode 100644 index 00000000000..12c46113cea --- /dev/null +++ b/tests/ui/thread-local/tls-dylib-access.rs @@ -0,0 +1,19 @@ +// aux-build: tls-rlib.rs +// aux-build: tls-export.rs +// run-pass + +#![feature(cfg_target_thread_local)] + +#[cfg(target_thread_local)] +extern crate tls_export; + +fn main() { + #[cfg(target_thread_local)] + { + // Check that we get the real address of the `FOO` TLS in the dylib + assert_eq!(&tls_export::FOO as *const bool as usize, tls_export::foo_addr()); + + // Check that we get the real address of the `BAR` TLS in the rlib linked into the dylib + assert_eq!(&tls_export::BAR as *const bool as usize, tls_export::bar_addr()); + } +} From 5bbaeadc013cae79e440fb5d3da2175c83cb36e4 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Tue, 28 Mar 2023 12:32:57 -0700 Subject: [PATCH 237/346] =?UTF-8?q?Move=20`mir::Field`=20=E2=86=92=20`abi:?= =?UTF-8?q?:FieldIdx`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The first PR for https://github.com/rust-lang/compiler-team/issues/606 This is just the move-and-rename, because it's plenty big-and-bitrotty already. Future PRs will start using `FieldIdx` more broadly, and concomitantly removing `FieldIdx::new`s. --- compiler/rustc_abi/src/lib.rs | 26 +++++++++++++ .../rustc_borrowck/src/diagnostics/mod.rs | 10 ++--- .../src/diagnostics/mutability_errors.rs | 3 +- compiler/rustc_borrowck/src/lib.rs | 7 ++-- compiler/rustc_borrowck/src/path_utils.rs | 5 ++- compiler/rustc_borrowck/src/type_check/mod.rs | 4 +- .../rustc_codegen_cranelift/src/abi/mod.rs | 4 +- compiler/rustc_codegen_cranelift/src/base.rs | 2 +- .../src/discriminant.rs | 6 +-- .../src/intrinsics/llvm_x86.rs | 4 +- .../src/intrinsics/simd.rs | 2 +- compiler/rustc_codegen_cranelift/src/lib.rs | 2 +- .../rustc_codegen_cranelift/src/unsize.rs | 4 +- .../src/value_and_place.rs | 6 +-- .../rustc_codegen_cranelift/src/vtable.rs | 6 +-- .../src/debuginfo/metadata/enums/mod.rs | 8 ++-- .../rustc_codegen_ssa/src/mir/debuginfo.rs | 8 ++-- compiler/rustc_middle/src/mir/mod.rs | 37 +++++++------------ compiler/rustc_middle/src/mir/query.rs | 12 +++--- compiler/rustc_middle/src/mir/syntax.rs | 14 +++++-- compiler/rustc_middle/src/mir/tcx.rs | 8 ++-- compiler/rustc_middle/src/query/keys.rs | 3 +- compiler/rustc_middle/src/thir.rs | 10 ++--- compiler/rustc_middle/src/ty/context.rs | 8 ++-- .../rustc_middle/src/ty/structural_impls.rs | 4 +- .../src/build/custom/parse/instruction.rs | 4 +- .../src/build/expr/as_place.rs | 4 +- .../src/build/expr/as_rvalue.rs | 5 ++- .../rustc_mir_build/src/build/expr/into.rs | 3 +- compiler/rustc_mir_build/src/build/mod.rs | 3 +- compiler/rustc_mir_build/src/thir/cx/expr.rs | 12 +++--- .../src/thir/pattern/const_to_pat.rs | 5 ++- .../src/thir/pattern/deconstruct_pat.rs | 12 +++--- .../rustc_mir_build/src/thir/pattern/mod.rs | 9 +++-- .../rustc_mir_dataflow/src/elaborate_drops.rs | 18 ++++----- .../rustc_mir_dataflow/src/value_analysis.rs | 6 +-- .../src/dataflow_const_prop.rs | 5 +-- .../src/elaborate_box_derefs.rs | 7 ++-- .../src/elaborate_drops.rs | 4 +- compiler/rustc_mir_transform/src/generator.rs | 13 ++++--- compiler/rustc_mir_transform/src/inline.rs | 4 +- .../rustc_mir_transform/src/instcombine.rs | 8 ++-- .../src/lower_intrinsics.rs | 4 +- .../src/remove_uninit_drops.rs | 7 ++-- compiler/rustc_mir_transform/src/shim.rs | 8 ++-- compiler/rustc_mir_transform/src/sroa.rs | 5 ++- 46 files changed, 192 insertions(+), 157 deletions(-) diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 6740001c38b..428191bc8b9 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1057,6 +1057,32 @@ impl Scalar { } } +rustc_index::newtype_index! { + /// The *source-order* index of a field in a variant. + /// + /// This is how most code after type checking refers to fields, rather than + /// using names (as names have hygiene complications and more complex lookup). + /// + /// Particularly for `repr(Rust)` types, this may not be the same as *layout* order. + /// (It is for `repr(C)` `struct`s, however.) + /// + /// For example, in the following types, + /// ```rust + /// # enum Never {} + /// # #[repr(u16)] + /// enum Demo1 { + /// Variant0 { a: Never, b: i32 } = 100, + /// Variant1 { c: u8, d: u64 } = 10, + /// } + /// struct Demo2 { e: u8, f: u16, g: u8 } + /// ``` + /// `b` is `FieldIdx(1)` in `VariantIdx(0)`, + /// `d` is `FieldIdx(1)` in `VariantIdx(1)`, and + /// `f` is `FieldIdx(1)` in `VariantIdx(0)`. + #[derive(HashStable_Generic)] + pub struct FieldIdx {} +} + /// Describes how the fields of a type are located in memory. #[derive(PartialEq, Eq, Hash, Clone, Debug)] #[cfg_attr(feature = "nightly", derive(HashStable_Generic))] diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 9f543b71c5f..5827fa81cff 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -9,15 +9,15 @@ use rustc_hir::GeneratorKind; use rustc_infer::infer::{LateBoundRegionConversionTime, TyCtxtInferExt}; use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::{ - AggregateKind, Constant, FakeReadCause, Field, Local, LocalInfo, LocalKind, Location, Operand, - Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, + AggregateKind, Constant, FakeReadCause, Local, LocalInfo, LocalKind, Location, Operand, Place, + PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, }; use rustc_middle::ty::print::Print; use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; use rustc_mir_dataflow::move_paths::{InitLocation, LookupResult}; use rustc_span::def_id::LocalDefId; use rustc_span::{symbol::sym, Span, Symbol, DUMMY_SP}; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::{FieldIdx, VariantIdx}; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; use rustc_trait_selection::traits::{ type_known_to_meet_bound_modulo_regions, Obligation, ObligationCause, @@ -302,7 +302,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn describe_field( &self, place: PlaceRef<'tcx>, - field: Field, + field: FieldIdx, including_tuple_field: IncludingTupleField, ) -> Option { let place_ty = match place { @@ -331,7 +331,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn describe_field_from_ty( &self, ty: Ty<'_>, - field: Field, + field: FieldIdx, variant_index: Option, including_tuple_field: IncludingTupleField, ) -> Option { diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index a8c216407f9..9d904009650 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -12,6 +12,7 @@ use rustc_middle::{ use rustc_span::source_map::DesugaringKind; use rustc_span::symbol::{kw, Symbol}; use rustc_span::{sym, BytePos, Span}; +use rustc_target::abi::FieldIdx; use crate::diagnostics::BorrowedContentSource; use crate::MirBorrowckCtxt; @@ -1275,7 +1276,7 @@ fn is_closure_or_generator(ty: Ty<'_>) -> bool { fn get_mut_span_in_struct_field<'tcx>( tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, - field: mir::Field, + field: FieldIdx, ) -> Option { // Expect our local to be a reference to a struct of some kind. if let ty::Ref(_, ty, _) = ty.kind() diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index b7ce3afce7b..2f64ccee686 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -33,12 +33,13 @@ use rustc_middle::mir::{ Place, PlaceElem, PlaceRef, VarDebugInfoContents, }; use rustc_middle::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind}; -use rustc_middle::mir::{Field, ProjectionElem, Promoted, Rvalue, Statement, StatementKind}; use rustc_middle::mir::{InlineAsmOperand, Terminator, TerminatorKind}; +use rustc_middle::mir::{ProjectionElem, Promoted, Rvalue, Statement, StatementKind}; use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, CapturedPlace, ParamEnv, RegionVid, TyCtxt}; use rustc_session::lint::builtin::UNUSED_MUT; use rustc_span::{Span, Symbol}; +use rustc_target::abi::FieldIdx; use either::Either; use smallvec::SmallVec; @@ -597,7 +598,7 @@ struct MirBorrowckCtxt<'cx, 'tcx> { used_mut: FxIndexSet, /// 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]>, + used_mut_upvars: SmallVec<[FieldIdx; 8]>, /// 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. regioncx: Rc>, @@ -2277,7 +2278,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// then returns the index of the field being projected. Note that this closure will always /// be `self` in the current MIR, because that is the only time we directly access the fields /// of a closure type. - fn is_upvar_field_projection(&self, place_ref: PlaceRef<'tcx>) -> Option { + fn is_upvar_field_projection(&self, place_ref: PlaceRef<'tcx>) -> Option { path_utils::is_upvar_field_projection(self.infcx.tcx, &self.upvars, place_ref, self.body()) } diff --git a/compiler/rustc_borrowck/src/path_utils.rs b/compiler/rustc_borrowck/src/path_utils.rs index f8a99a2699e..ea9f8683ca7 100644 --- a/compiler/rustc_borrowck/src/path_utils.rs +++ b/compiler/rustc_borrowck/src/path_utils.rs @@ -7,8 +7,9 @@ use crate::BorrowIndex; use crate::Upvar; use rustc_data_structures::graph::dominators::Dominators; use rustc_middle::mir::BorrowKind; -use rustc_middle::mir::{BasicBlock, Body, Field, Location, Place, PlaceRef, ProjectionElem}; +use rustc_middle::mir::{BasicBlock, Body, Location, Place, PlaceRef, ProjectionElem}; use rustc_middle::ty::TyCtxt; +use rustc_target::abi::FieldIdx; /// Returns `true` if the borrow represented by `kind` is /// allowed to be split into separate Reservation and @@ -148,7 +149,7 @@ pub(crate) fn is_upvar_field_projection<'tcx>( upvars: &[Upvar<'tcx>], place_ref: PlaceRef<'tcx>, body: &Body<'tcx>, -) -> Option { +) -> Option { let mut place_ref = place_ref; let mut by_ref = false; diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 4b27d240985..04da6d6beff 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -36,7 +36,7 @@ use rustc_middle::ty::{ }; use rustc_span::def_id::CRATE_DEF_ID; use rustc_span::{Span, DUMMY_SP}; -use rustc_target::abi::FIRST_VARIANT; +use rustc_target::abi::{FieldIdx, FIRST_VARIANT}; use rustc_trait_selection::traits::query::type_op::custom::scrape_region_constraints; use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp; use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput}; @@ -786,7 +786,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { &mut self, parent: &dyn fmt::Debug, base_ty: PlaceTy<'tcx>, - field: Field, + field: FieldIdx, location: Location, ) -> Result, FieldAccessError> { let tcx = self.tcx(); diff --git a/compiler/rustc_codegen_cranelift/src/abi/mod.rs b/compiler/rustc_codegen_cranelift/src/abi/mod.rs index 3bc64c44524..91c085d3d69 100644 --- a/compiler/rustc_codegen_cranelift/src/abi/mod.rs +++ b/compiler/rustc_codegen_cranelift/src/abi/mod.rs @@ -327,7 +327,7 @@ pub(crate) fn codegen_fn_prelude<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, start_ ArgKind::Spread(params) => { for (i, param) in params.into_iter().enumerate() { if let Some(param) = param { - place.place_field(fx, mir::Field::new(i)).write_cvalue(fx, param); + place.place_field(fx, FieldIdx::new(i)).write_cvalue(fx, param); } } } @@ -460,7 +460,7 @@ pub(crate) fn codegen_terminator_call<'tcx>( args.push(self_arg); for i in 0..tupled_arguments.len() { args.push(CallArgument { - value: pack_arg.value.value_field(fx, mir::Field::new(i)), + value: pack_arg.value.value_field(fx, FieldIdx::new(i)), is_owned: pack_arg.is_owned, }); } diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 1825fb8cb22..615ef58ff58 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -797,7 +797,7 @@ fn codegen_stmt<'tcx>( let index = fx.bcx.ins().iconst(fx.pointer_type, field_index as i64); variant_dest.place_index(fx, index) } else { - variant_dest.place_field(fx, mir::Field::new(field_index)) + variant_dest.place_field(fx, FieldIdx::new(field_index)) }; to.write_cvalue(fx, operand); } diff --git a/compiler/rustc_codegen_cranelift/src/discriminant.rs b/compiler/rustc_codegen_cranelift/src/discriminant.rs index 3cbf313adf0..f740945a03c 100644 --- a/compiler/rustc_codegen_cranelift/src/discriminant.rs +++ b/compiler/rustc_codegen_cranelift/src/discriminant.rs @@ -26,7 +26,7 @@ pub(crate) fn codegen_set_discriminant<'tcx>( tag_encoding: TagEncoding::Direct, variants: _, } => { - let ptr = place.place_field(fx, mir::Field::new(tag_field)); + let ptr = place.place_field(fx, FieldIdx::new(tag_field)); let to = layout.ty.discriminant_for_variant(fx.tcx, variant_index).unwrap().val; let to = if ptr.layout().abi.is_signed() { ty::ScalarInt::try_from_int( @@ -47,7 +47,7 @@ pub(crate) fn codegen_set_discriminant<'tcx>( variants: _, } => { if variant_index != untagged_variant { - let niche = place.place_field(fx, mir::Field::new(tag_field)); + let niche = place.place_field(fx, FieldIdx::new(tag_field)); let niche_type = fx.clif_type(niche.layout().ty).unwrap(); let niche_value = variant_index.as_u32() - niche_variants.start().as_u32(); let niche_value = (niche_value as u128).wrapping_add(niche_start); @@ -107,7 +107,7 @@ pub(crate) fn codegen_get_discriminant<'tcx>( let cast_to = fx.clif_type(dest_layout.ty).unwrap(); // Read the tag/niche-encoded discriminant from memory. - let tag = value.value_field(fx, mir::Field::new(tag_field)); + let tag = value.value_field(fx, FieldIdx::new(tag_field)); let tag = tag.load_scalar(fx); // Decode the discriminant (specifically if it's niche-encoded). diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs index e5c4b244a1a..0f32d1a25ff 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs @@ -179,8 +179,8 @@ fn llvm_add_sub<'tcx>( // c + carry -> c + first intermediate carry or borrow respectively let int0 = crate::num::codegen_checked_int_binop(fx, bin_op, a, b); - let c = int0.value_field(fx, mir::Field::new(0)); - let cb0 = int0.value_field(fx, mir::Field::new(1)).load_scalar(fx); + let c = int0.value_field(fx, FieldIdx::new(0)); + let cb0 = int0.value_field(fx, FieldIdx::new(1)).load_scalar(fx); // c + carry -> c + second intermediate carry or borrow respectively let cb_in_as_u64 = fx.bcx.ins().uextend(types::I64, cb_in); diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs index 034b4e8072c..6f54a8d49c8 100644 --- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs +++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs @@ -253,7 +253,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>( } ret.write_cvalue(fx, base); - let ret_lane = ret.place_field(fx, mir::Field::new(idx.try_into().unwrap())); + let ret_lane = ret.place_field(fx, FieldIdx::new(idx.try_into().unwrap())); ret_lane.write_cvalue(fx, val); } diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs index 1bd03403f24..8cc7f6c34b0 100644 --- a/compiler/rustc_codegen_cranelift/src/lib.rs +++ b/compiler/rustc_codegen_cranelift/src/lib.rs @@ -86,7 +86,7 @@ mod prelude { self, FloatTy, Instance, InstanceDef, IntTy, ParamEnv, Ty, TyCtxt, TypeAndMut, TypeFoldable, TypeVisitableExt, UintTy, }; - pub(crate) use rustc_target::abi::{Abi, Scalar, Size, VariantIdx, FIRST_VARIANT}; + pub(crate) use rustc_target::abi::{Abi, FieldIdx, Scalar, Size, VariantIdx, FIRST_VARIANT}; pub(crate) use rustc_data_structures::fx::FxHashMap; diff --git a/compiler/rustc_codegen_cranelift/src/unsize.rs b/compiler/rustc_codegen_cranelift/src/unsize.rs index 93eefd92342..ff0e12410e7 100644 --- a/compiler/rustc_codegen_cranelift/src/unsize.rs +++ b/compiler/rustc_codegen_cranelift/src/unsize.rs @@ -147,8 +147,8 @@ pub(crate) fn coerce_unsized_into<'tcx>( assert_eq!(def_a, def_b); for i in 0..def_a.variant(FIRST_VARIANT).fields.len() { - let src_f = src.value_field(fx, mir::Field::new(i)); - let dst_f = dst.place_field(fx, mir::Field::new(i)); + let src_f = src.value_field(fx, FieldIdx::new(i)); + let dst_f = dst.place_field(fx, FieldIdx::new(i)); if dst_f.layout().is_zst() { continue; diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs index 58e0a498292..ffe3ccb0eca 100644 --- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs +++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs @@ -10,7 +10,7 @@ fn codegen_field<'tcx>( base: Pointer, extra: Option, layout: TyAndLayout<'tcx>, - field: mir::Field, + field: FieldIdx, ) -> (Pointer, TyAndLayout<'tcx>) { let field_offset = layout.fields.offset(field.index()); let field_layout = layout.field(&*fx, field.index()); @@ -210,7 +210,7 @@ impl<'tcx> CValue<'tcx> { pub(crate) fn value_field( self, fx: &mut FunctionCx<'_, '_, 'tcx>, - field: mir::Field, + field: FieldIdx, ) -> CValue<'tcx> { let layout = self.1; match self.0 { @@ -687,7 +687,7 @@ impl<'tcx> CPlace<'tcx> { pub(crate) fn place_field( self, fx: &mut FunctionCx<'_, '_, 'tcx>, - field: mir::Field, + field: FieldIdx, ) -> CPlace<'tcx> { let layout = self.layout(); diff --git a/compiler/rustc_codegen_cranelift/src/vtable.rs b/compiler/rustc_codegen_cranelift/src/vtable.rs index 94806e0d798..b309695c190 100644 --- a/compiler/rustc_codegen_cranelift/src/vtable.rs +++ b/compiler/rustc_codegen_cranelift/src/vtable.rs @@ -50,7 +50,7 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>( if let Abi::Scalar(_) = arg.layout().abi { 'descend_newtypes: while !arg.layout().ty.is_unsafe_ptr() && !arg.layout().ty.is_ref() { for i in 0..arg.layout().fields.count() { - let field = arg.value_field(fx, mir::Field::new(i)); + let field = arg.value_field(fx, FieldIdx::new(i)); if !field.layout().is_zst() { // we found the one non-zero-sized field that is allowed // now find *its* non-zero-sized field, or stop if it's a @@ -68,9 +68,9 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>( if ty.is_dyn_star() { let inner_layout = fx.layout_of(arg.layout().ty.builtin_deref(true).unwrap().ty); let dyn_star = CPlace::for_ptr(Pointer::new(arg.load_scalar(fx)), inner_layout); - let ptr = dyn_star.place_field(fx, mir::Field::new(0)).to_ptr(); + let ptr = dyn_star.place_field(fx, FieldIdx::new(0)).to_ptr(); let vtable = - dyn_star.place_field(fx, mir::Field::new(1)).to_cvalue(fx).load_scalar(fx); + dyn_star.place_field(fx, FieldIdx::new(1)).to_cvalue(fx).load_scalar(fx); break 'block (ptr, vtable); } } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs index 54e850f2599..3e4765fba57 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs @@ -6,7 +6,7 @@ use rustc_hir::def::CtorKind; use rustc_index::vec::IndexVec; use rustc_middle::{ bug, - mir::{Field, GeneratorLayout, GeneratorSavedLocal}, + mir::{GeneratorLayout, GeneratorSavedLocal}, ty::{ self, layout::{IntegerExt, LayoutOf, PrimitiveExt, TyAndLayout}, @@ -14,7 +14,9 @@ use rustc_middle::{ }, }; use rustc_span::Symbol; -use rustc_target::abi::{HasDataLayout, Integer, Primitive, TagEncoding, VariantIdx, Variants}; +use rustc_target::abi::{ + FieldIdx, HasDataLayout, Integer, Primitive, TagEncoding, VariantIdx, Variants, +}; use std::borrow::Cow; use crate::{ @@ -353,7 +355,7 @@ pub fn build_generator_variant_struct_type_di_node<'ll, 'tcx>( let state_specific_fields: SmallVec<_> = (0..variant_layout.fields.count()) .map(|field_index| { let generator_saved_local = generator_layout.variant_fields[variant_index] - [Field::from_usize(field_index)]; + [FieldIdx::from_usize(field_index)]; let field_name_maybe = state_specific_upvar_names[generator_saved_local]; let field_name = field_name_maybe .as_ref() diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs index d15774696a5..ff25d1e3823 100644 --- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs @@ -8,7 +8,7 @@ use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf}; use rustc_session::config::DebugInfo; use rustc_span::symbol::{kw, Symbol}; use rustc_span::{BytePos, Span}; -use rustc_target::abi::{Abi, Size, VariantIdx}; +use rustc_target::abi::{Abi, FieldIdx, Size, VariantIdx}; use super::operand::{OperandRef, OperandValue}; use super::place::PlaceRef; @@ -79,7 +79,7 @@ impl<'tcx, S: Copy, L: Copy> DebugScope { trait DebugInfoOffsetLocation<'tcx, Bx> { fn deref(&self, bx: &mut Bx) -> Self; fn layout(&self) -> TyAndLayout<'tcx>; - fn project_field(&self, bx: &mut Bx, field: mir::Field) -> Self; + fn project_field(&self, bx: &mut Bx, field: FieldIdx) -> Self; fn downcast(&self, bx: &mut Bx, variant: VariantIdx) -> Self; } @@ -94,7 +94,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> DebugInfoOffsetLocation<'tcx, Bx> self.layout } - fn project_field(&self, bx: &mut Bx, field: mir::Field) -> Self { + fn project_field(&self, bx: &mut Bx, field: FieldIdx) -> Self { PlaceRef::project_field(*self, bx, field.index()) } @@ -116,7 +116,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> DebugInfoOffsetLocation<'tcx, Bx> *self } - fn project_field(&self, bx: &mut Bx, field: mir::Field) -> Self { + fn project_field(&self, bx: &mut Bx, field: FieldIdx) -> Self { self.field(bx.cx(), field.index()) } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 9c575f6eb9f..37356b53c02 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -21,7 +21,7 @@ use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID}; use rustc_hir::{self, GeneratorKind, ImplicitSelfKind}; use rustc_hir::{self as hir, HirId}; use rustc_session::Session; -use rustc_target::abi::{Size, VariantIdx}; +use rustc_target::abi::{FieldIdx, Size, VariantIdx}; use polonius_engine::Atom; pub use rustc_ast::Mutability; @@ -1512,7 +1512,7 @@ impl ProjectionElem { } /// Returns `true` if this is a `Field` projection with the given index. - pub fn is_field_to(&self, f: Field) -> bool { + pub fn is_field_to(&self, f: FieldIdx) -> bool { matches!(*self, Self::Field(x, _) if x == f) } } @@ -1521,22 +1521,6 @@ impl ProjectionElem { /// need neither the `V` parameter for `Index` nor the `T` for `Field`. pub type ProjectionKind = ProjectionElem<(), ()>; -rustc_index::newtype_index! { - /// A [newtype'd][wrapper] index type in the MIR [control-flow graph][CFG] - /// - /// A field (e.g., `f` in `_1.f`) is one variant of [`ProjectionElem`]. Conceptually, - /// rustc can identify that a field projection refers to either two different regions of memory - /// or the same one between the base and the 'projection element'. - /// Read more about projections in the [rustc-dev-guide][mir-datatypes] - /// - /// [wrapper]: https://rustc-dev-guide.rust-lang.org/appendix/glossary.html#newtype - /// [CFG]: https://rustc-dev-guide.rust-lang.org/appendix/background.html#cfg - /// [mir-datatypes]: https://rustc-dev-guide.rust-lang.org/mir/index.html#mir-data-types - #[derive(HashStable)] - #[debug_format = "field[{}]"] - pub struct Field {} -} - #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct PlaceRef<'tcx> { pub local: Local, @@ -2685,12 +2669,17 @@ impl<'tcx> UserTypeProjections { self.map_projections(|pat_ty_proj| pat_ty_proj.deref()) } - pub fn leaf(self, field: Field) -> Self { + pub fn leaf(self, field: FieldIdx) -> Self { self.map_projections(|pat_ty_proj| pat_ty_proj.leaf(field)) } - pub fn variant(self, adt_def: AdtDef<'tcx>, variant_index: VariantIdx, field: Field) -> Self { - self.map_projections(|pat_ty_proj| pat_ty_proj.variant(adt_def, variant_index, field)) + pub fn variant( + self, + adt_def: AdtDef<'tcx>, + variant_index: VariantIdx, + field_index: FieldIdx, + ) -> Self { + self.map_projections(|pat_ty_proj| pat_ty_proj.variant(adt_def, variant_index, field_index)) } } @@ -2733,7 +2722,7 @@ impl UserTypeProjection { self } - pub(crate) fn leaf(mut self, field: Field) -> Self { + pub(crate) fn leaf(mut self, field: FieldIdx) -> Self { self.projs.push(ProjectionElem::Field(field, ())); self } @@ -2742,13 +2731,13 @@ impl UserTypeProjection { mut self, adt_def: AdtDef<'_>, variant_index: VariantIdx, - field: Field, + field_index: FieldIdx, ) -> Self { self.projs.push(ProjectionElem::Downcast( Some(adt_def.variant(variant_index).name), variant_index, )); - self.projs.push(ProjectionElem::Field(field, ())); + self.projs.push(ProjectionElem::Field(field_index, ())); self } } diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index 786c2e9cd94..68561cf6dd7 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -10,12 +10,12 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_index::bit_set::BitMatrix; use rustc_index::vec::{Idx, IndexVec}; use rustc_span::Span; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::{FieldIdx, VariantIdx}; use smallvec::SmallVec; use std::cell::Cell; use std::fmt::{self, Debug}; -use super::{Field, SourceInfo}; +use super::SourceInfo; #[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)] pub enum UnsafetyViolationKind { @@ -152,7 +152,7 @@ pub struct GeneratorLayout<'tcx> { /// Which of the above fields are in each variant. Note that one field may /// be stored in multiple variants. - pub variant_fields: IndexVec>, + pub variant_fields: IndexVec>, /// The source that led to each variant being created (usually, a yield or /// await). @@ -229,7 +229,7 @@ pub struct BorrowCheckResult<'tcx> { /// unerased regions. pub concrete_opaque_types: FxIndexMap>, pub closure_requirements: Option>, - pub used_mut_upvars: SmallVec<[Field; 8]>, + pub used_mut_upvars: SmallVec<[FieldIdx; 8]>, pub tainted_by_errors: Option, } @@ -353,7 +353,7 @@ pub enum ConstraintCategory<'tcx> { /// like `Foo { field: my_val }`) Usage, OpaqueType, - ClosureUpvar(Field), + ClosureUpvar(FieldIdx), /// A constraint from a user-written predicate /// with the provided span, written on the item @@ -375,7 +375,7 @@ pub enum ConstraintCategory<'tcx> { #[derive(TyEncodable, TyDecodable, HashStable, TypeVisitable, TypeFoldable)] pub enum ReturnConstraint { Normal, - ClosureUpvar(Field), + ClosureUpvar(FieldIdx), } /// The subject of a `ClosureOutlivesRequirement` -- that is, the thing diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index bbd913d071d..8fb693055fa 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -3,7 +3,7 @@ //! This is in a dedicated file so that changes to this file can be reviewed more carefully. //! The intention is that this file only contains datatype declarations, no code. -use super::{BasicBlock, Constant, Field, Local, SwitchTargets, UserTypeProjection}; +use super::{BasicBlock, Constant, Local, SwitchTargets, UserTypeProjection}; use crate::mir::coverage::{CodeRegion, CoverageKind}; use crate::traits::Reveal; @@ -16,7 +16,7 @@ use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_hir::def_id::DefId; use rustc_hir::{self as hir}; use rustc_hir::{self, GeneratorKind}; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::{FieldIdx, VariantIdx}; use rustc_ast::Mutability; use rustc_span::def_id::LocalDefId; @@ -888,7 +888,15 @@ pub struct Place<'tcx> { #[derive(TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] pub enum ProjectionElem { Deref, - Field(Field, T), + + /// A field (e.g., `f` in `_1.f`) is one variant of [`ProjectionElem`]. Conceptually, + /// rustc can identify that a field projection refers to either two different regions of memory + /// or the same one between the base and the 'projection element'. + /// Read more about projections in the [rustc-dev-guide][mir-datatypes] + /// + /// [mir-datatypes]: https://rustc-dev-guide.rust-lang.org/mir/index.html#mir-data-types + Field(FieldIdx, T), + /// Index into a slice/array. /// /// Note that this does not also dereference, and so it does not exactly correspond to slice diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index 0aa2c500f51..6e23c82a37b 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -6,7 +6,7 @@ use crate::mir::*; use crate::ty::{self, Ty, TyCtxt}; use rustc_hir as hir; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::{FieldIdx, VariantIdx}; #[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable)] pub struct PlaceTy<'tcx> { @@ -33,7 +33,7 @@ impl<'tcx> PlaceTy<'tcx> { /// /// Note that the resulting type has not been normalized. #[instrument(level = "debug", skip(tcx), ret)] - pub fn field_ty(self, tcx: TyCtxt<'tcx>, f: Field) -> Ty<'tcx> { + pub fn field_ty(self, tcx: TyCtxt<'tcx>, f: FieldIdx) -> Ty<'tcx> { match self.ty.kind() { ty::Adt(adt_def, substs) => { let variant_def = match self.variant_index { @@ -61,14 +61,14 @@ impl<'tcx> PlaceTy<'tcx> { /// `place_ty.projection_ty_core(tcx, elem, |...| { ... })` /// projects `place_ty` onto `elem`, returning the appropriate /// `Ty` or downcast variant corresponding to that projection. - /// The `handle_field` callback must map a `Field` to its `Ty`, + /// The `handle_field` callback must map a `FieldIdx` to its `Ty`, /// (which should be trivial when `T` = `Ty`). pub fn projection_ty_core( self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, elem: &ProjectionElem, - mut handle_field: impl FnMut(&Self, Field, T) -> Ty<'tcx>, + mut handle_field: impl FnMut(&Self, FieldIdx, T) -> Ty<'tcx>, mut handle_opaque_cast: impl FnMut(&Self, T) -> Ty<'tcx>, ) -> PlaceTy<'tcx> where diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs index ca65fbc2fd4..4a096a2c0e8 100644 --- a/compiler/rustc_middle/src/query/keys.rs +++ b/compiler/rustc_middle/src/query/keys.rs @@ -12,6 +12,7 @@ use rustc_hir::hir_id::{HirId, OwnerId}; use rustc_query_system::query::{DefaultCacheSelector, SingleCacheSelector, VecCacheSelector}; use rustc_span::symbol::{Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; +use rustc_target::abi::FieldIdx; /// Placeholder for `CrateNum`'s "local" counterpart #[derive(Copy, Clone, Debug)] @@ -332,7 +333,7 @@ impl<'tcx> Key for (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) { } } -impl<'tcx> Key for (ty::Const<'tcx>, mir::Field) { +impl<'tcx> Key for (ty::Const<'tcx>, FieldIdx) { type CacheSelector = DefaultCacheSelector; fn default_span(&self, _: TyCtxt<'_>) -> Span { diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 3b11fab8cdf..29e3055a4b8 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -17,14 +17,14 @@ use rustc_index::newtype_index; use rustc_index::vec::IndexVec; use rustc_middle::middle::region; use rustc_middle::mir::interpret::AllocId; -use rustc_middle::mir::{self, BinOp, BorrowKind, FakeReadCause, Field, Mutability, UnOp}; +use rustc_middle::mir::{self, BinOp, BorrowKind, FakeReadCause, Mutability, UnOp}; use rustc_middle::ty::adjustment::PointerCast; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::{self, AdtDef, FnSig, Ty, UpvarSubsts}; use rustc_middle::ty::{CanonicalUserType, CanonicalUserTypeAnnotation}; use rustc_span::def_id::LocalDefId; use rustc_span::{sym, Span, Symbol, DUMMY_SP}; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::{FieldIdx, VariantIdx}; use rustc_target::asm::InlineAsmRegOrRegClass; use std::fmt; use std::ops::Index; @@ -366,7 +366,7 @@ pub enum ExprKind<'tcx> { /// Variant containing the field. variant_index: VariantIdx, /// This can be a named (`.foo`) or unnamed (`.0`) field. - name: Field, + name: FieldIdx, }, /// A *non-overloaded* indexing operation. Index { @@ -491,7 +491,7 @@ pub enum ExprKind<'tcx> { /// This is used in struct constructors. #[derive(Clone, Debug, HashStable)] pub struct FieldExpr { - pub name: Field, + pub name: FieldIdx, pub expr: ExprId, } @@ -570,7 +570,7 @@ pub enum BindingMode { #[derive(Clone, Debug, HashStable)] pub struct FieldPat<'tcx> { - pub field: Field, + pub field: FieldIdx, pub pattern: Box>, } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index a1c1acc4a25..8d0aa622244 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -12,9 +12,7 @@ use crate::middle::codegen_fn_attrs::CodegenFnAttrs; use crate::middle::resolve_bound_vars; use crate::middle::stability; use crate::mir::interpret::{self, Allocation, ConstAllocation}; -use crate::mir::{ - Body, BorrowCheckResult, Field, Local, Place, PlaceElem, ProjectionKind, Promoted, -}; +use crate::mir::{Body, BorrowCheckResult, Local, Place, PlaceElem, ProjectionKind, Promoted}; use crate::query::LocalCrate; use crate::thir::Thir; use crate::traits; @@ -65,7 +63,7 @@ use rustc_span::def_id::{DefPathHash, StableCrateId}; use rustc_span::source_map::SourceMap; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{Span, DUMMY_SP}; -use rustc_target::abi::{Layout, LayoutS, TargetDataLayout, VariantIdx}; +use rustc_target::abi::{FieldIdx, Layout, LayoutS, TargetDataLayout, VariantIdx}; use rustc_target::spec::abi; use rustc_type_ir::sty::TyKind::*; use rustc_type_ir::WithCachedTypeInfo; @@ -2125,7 +2123,7 @@ impl<'tcx> TyCtxt<'tcx> { } } - pub fn mk_place_field(self, place: Place<'tcx>, f: Field, ty: Ty<'tcx>) -> Place<'tcx> { + pub fn mk_place_field(self, place: Place<'tcx>, f: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> { self.mk_place_elem(place, PlaceElem::Field(f, ty)) } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index c6bb8146795..d4f058440b9 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -4,7 +4,7 @@ //! to help with the tedium. use crate::mir::interpret; -use crate::mir::{Field, ProjectionKind}; +use crate::mir::ProjectionKind; use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable}; use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer}; use crate::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor}; @@ -217,6 +217,7 @@ CloneLiftImpls! { // implementation and traversal implementations (the latter only for // TyCtxt<'_> interners). TrivialTypeTraversalAndLiftImpls! { + ::rustc_target::abi::FieldIdx, ::rustc_target::abi::VariantIdx, crate::middle::region::Scope, crate::ty::FloatTy, @@ -268,7 +269,6 @@ TrivialTypeTraversalAndLiftImpls! { ::rustc_span::Span, ::rustc_span::symbol::Ident, ::rustc_errors::ErrorGuaranteed, - Field, interpret::Scalar, rustc_target::abi::Size, ty::BoundVar, diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs index bf58b3090fb..77a5017b363 100644 --- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs @@ -3,7 +3,7 @@ use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::ty::cast::mir_cast_kind; use rustc_middle::{mir::*, thir::*, ty}; use rustc_span::Span; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::{FieldIdx, VariantIdx}; use crate::build::custom::ParseError; use crate::build::expr::as_constant::as_constant_inner; @@ -223,7 +223,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { let (parent, proj) = parse_by_kind!(self, expr_id, expr, "place", @call("mir_field", args) => { let (parent, ty) = self.parse_place_inner(args[0])?; - let field = Field::from_u32(self.parse_integer_literal(args[1])? as u32); + let field = FieldIdx::from_u32(self.parse_integer_literal(args[1])? as u32); let field_ty = ty.field_ty(self.tcx, field); let proj = PlaceElem::Field(field, field_ty); let place = parent.project_deeper(&[proj], self.tcx); diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs index e112bf9829b..0fc99e57d12 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -13,7 +13,7 @@ use rustc_middle::thir::*; use rustc_middle::ty::AdtDef; use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, Variance}; use rustc_span::Span; -use rustc_target::abi::{VariantIdx, FIRST_VARIANT}; +use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT}; use std::assert_matches::assert_matches; use std::iter; @@ -293,7 +293,7 @@ impl<'tcx> PlaceBuilder<'tcx> { &self.projection } - pub(crate) fn field(self, f: Field, ty: Ty<'tcx>) -> Self { + pub(crate) fn field(self, f: FieldIdx, ty: Ty<'tcx>) -> Self { self.project(PlaceElem::Field(f, ty)) } diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index 7fff801b169..d1878bf77ef 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -17,6 +17,7 @@ use rustc_middle::thir::*; use rustc_middle::ty::cast::{mir_cast_kind, CastTy}; use rustc_middle::ty::{self, Ty, UpvarSubsts}; use rustc_span::Span; +use rustc_target::abi::FieldIdx; impl<'a, 'tcx> Builder<'a, 'tcx> { /// Returns an rvalue suitable for use until the end of the current @@ -553,8 +554,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { result_value, Rvalue::CheckedBinaryOp(op, Box::new((lhs.to_copy(), rhs.to_copy()))), ); - let val_fld = Field::new(0); - let of_fld = Field::new(1); + let val_fld = FieldIdx::new(0); + let of_fld = FieldIdx::new(1); let tcx = self.tcx; let val = tcx.mk_place_field(result_value, val_fld, ty); diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index ebe8ea25ad3..b8260c719c8 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -10,6 +10,7 @@ use rustc_index::vec::Idx; use rustc_middle::mir::*; use rustc_middle::thir::*; use rustc_middle::ty::CanonicalUserTypeAnnotation; +use rustc_target::abi::FieldIdx; use std::iter; impl<'a, 'tcx> Builder<'a, 'tcx> { @@ -344,7 +345,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { .collect(); let field_names: Vec<_> = - (0..adt_def.variant(variant_index).fields.len()).map(Field::new).collect(); + (0..adt_def.variant(variant_index).fields.len()).map(FieldIdx::new).collect(); let fields: Vec<_> = if let Some(FruInfo { base, field_types }) = base { let place_builder = diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index 1923e10ddb5..e87e38fd04c 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -25,6 +25,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; use rustc_span::symbol::sym; use rustc_span::Span; use rustc_span::Symbol; +use rustc_target::abi::FieldIdx; use rustc_target::spec::abi::Abi; use super::lints; @@ -793,7 +794,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { let mutability = captured_place.mutability; let mut projs = closure_env_projs.clone(); - projs.push(ProjectionElem::Field(Field::new(i), ty)); + projs.push(ProjectionElem::Field(FieldIdx::new(i), ty)); match capture { ty::UpvarCapture::ByValue => {} ty::UpvarCapture::ByRef(..) => { diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 04e9273fc46..2a0b5d04733 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -10,7 +10,7 @@ use rustc_middle::hir::place::Place as HirPlace; use rustc_middle::hir::place::PlaceBase as HirPlaceBase; use rustc_middle::hir::place::ProjectionKind as HirProjectionKind; use rustc_middle::middle::region; -use rustc_middle::mir::{self, BinOp, BorrowKind, Field, UnOp}; +use rustc_middle::mir::{self, BinOp, BorrowKind, UnOp}; use rustc_middle::thir::*; use rustc_middle::ty::adjustment::{ Adjust, Adjustment, AutoBorrow, AutoBorrowMutability, PointerCast, @@ -20,7 +20,7 @@ use rustc_middle::ty::{ self, AdtKind, InlineConstSubsts, InlineConstSubstsParts, ScalarInt, Ty, UpvarSubsts, UserType, }; use rustc_span::{sym, Span}; -use rustc_target::abi::FIRST_VARIANT; +use rustc_target::abi::{FieldIdx, FIRST_VARIANT}; impl<'tcx> Cx<'tcx> { pub(crate) fn mirror_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) -> ExprId { @@ -379,7 +379,7 @@ impl<'tcx> Cx<'tcx> { .iter() .enumerate() .map(|(idx, e)| FieldExpr { - name: Field::new(idx), + name: FieldIdx::new(idx), expr: self.mirror_expr(e), }) .collect(); @@ -733,7 +733,7 @@ impl<'tcx> Cx<'tcx> { hir::ExprKind::Field(ref source, ..) => ExprKind::Field { lhs: self.mirror_expr(source), variant_index: FIRST_VARIANT, - name: Field::new(self.typeck_results.field_index(expr.hir_id)), + name: FieldIdx::new(self.typeck_results.field_index(expr.hir_id)), }, hir::ExprKind::Cast(ref source, ref cast_ty) => { // Check for a user-given type annotation on this `cast` @@ -1053,7 +1053,7 @@ impl<'tcx> Cx<'tcx> { HirProjectionKind::Field(field, variant_index) => ExprKind::Field { lhs: self.thir.exprs.push(captured_place_expr), variant_index, - name: Field::new(field as usize), + name: FieldIdx::new(field as usize), }, HirProjectionKind::Index | HirProjectionKind::Subslice => { // We don't capture these projections, so we can ignore them here @@ -1107,7 +1107,7 @@ impl<'tcx> Cx<'tcx> { fields .iter() .map(|field| FieldExpr { - name: Field::new(self.typeck_results.field_index(field.hir_id)), + name: FieldIdx::new(self.typeck_results.field_index(field.hir_id)), expr: self.mirror_expr(field.expr), }) .collect() diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 274c2f06137..2dbef740d1a 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -2,11 +2,12 @@ use rustc_hir as hir; use rustc_index::vec::Idx; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::Obligation; -use rustc_middle::mir::{self, Field}; +use rustc_middle::mir; use rustc_middle::thir::{FieldPat, Pat, PatKind}; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::lint; use rustc_span::Span; +use rustc_target::abi::FieldIdx; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; use rustc_trait_selection::traits::{self, ObligationCause}; @@ -218,7 +219,7 @@ impl<'tcx> ConstToPat<'tcx> { ) -> Result>, FallbackToConstRef> { vals.enumerate() .map(|(idx, val)| { - let field = Field::new(idx); + let field = FieldIdx::new(idx); Ok(FieldPat { field, pattern: self.recur(val, false)? }) }) .collect() diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index 8a7b1fce51d..e619e095496 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -53,14 +53,14 @@ use smallvec::{smallvec, SmallVec}; use rustc_data_structures::captures::Captures; use rustc_hir::{HirId, RangeEnd}; use rustc_index::vec::Idx; -use rustc_middle::mir::{self, Field}; +use rustc_middle::mir; use rustc_middle::thir::{FieldPat, Pat, PatKind, PatRange}; use rustc_middle::ty::layout::IntegerExt; use rustc_middle::ty::{self, Ty, TyCtxt, VariantDef}; use rustc_middle::{middle::stability::EvalResult, mir::interpret::ConstValue}; use rustc_session::lint; use rustc_span::{Span, DUMMY_SP}; -use rustc_target::abi::{Integer, Size, VariantIdx, FIRST_VARIANT}; +use rustc_target::abi::{FieldIdx, Integer, Size, VariantIdx, FIRST_VARIANT}; use self::Constructor::*; use self::SliceKind::*; @@ -1126,7 +1126,7 @@ impl<'tcx> SplitWildcard<'tcx> { /// Note that the number of fields of a constructor may not match the fields declared in the /// original struct/variant. This happens if a private or `non_exhaustive` field is uninhabited, /// because the code mustn't observe that it is uninhabited. In that case that field is not -/// included in `fields`. For that reason, when you have a `mir::Field` you must use +/// included in `fields`. For that reason, when you have a `FieldIdx` you must use /// `index_with_declared_idx`. #[derive(Debug, Clone, Copy)] pub(super) struct Fields<'p, 'tcx> { @@ -1165,7 +1165,7 @@ impl<'p, 'tcx> Fields<'p, 'tcx> { cx: &'a MatchCheckCtxt<'p, 'tcx>, ty: Ty<'tcx>, variant: &'a VariantDef, - ) -> impl Iterator)> + Captures<'a> + Captures<'p> { + ) -> impl Iterator)> + Captures<'a> + Captures<'p> { let ty::Adt(adt, substs) = ty.kind() else { bug!() }; // Whether we must not match the fields of this variant exhaustively. let is_non_exhaustive = variant.is_field_list_non_exhaustive() && !adt.did().is_local(); @@ -1180,7 +1180,7 @@ impl<'p, 'tcx> Fields<'p, 'tcx> { if is_uninhabited && (!is_visible || is_non_exhaustive) { None } else { - Some((Field::new(i), ty)) + Some((FieldIdx::new(i), ty)) } }) } @@ -1438,7 +1438,7 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> { ty::Tuple(..) => PatKind::Leaf { subpatterns: subpatterns .enumerate() - .map(|(i, pattern)| FieldPat { field: Field::new(i), pattern }) + .map(|(i, pattern)| FieldPat { field: FieldIdx::new(i), pattern }) .collect(), }, ty::Adt(adt_def, _) if adt_def.is_box() => { diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index f356c8a6838..72b4041aa1b 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -21,12 +21,13 @@ use rustc_middle::mir::interpret::{ ConstValue, ErrorHandled, LitToConstError, LitToConstInput, Scalar, }; use rustc_middle::mir::{self, UserTypeProjection}; -use rustc_middle::mir::{BorrowKind, Field, Mutability}; +use rustc_middle::mir::{BorrowKind, Mutability}; use rustc_middle::thir::{Ascription, BindingMode, FieldPat, LocalVarId, Pat, PatKind, PatRange}; use rustc_middle::ty::subst::{GenericArg, SubstsRef}; use rustc_middle::ty::CanonicalUserTypeAnnotation; use rustc_middle::ty::{self, AdtDef, ConstKind, Region, Ty, TyCtxt, UserType}; use rustc_span::{Span, Symbol}; +use rustc_target::abi::FieldIdx; use std::cmp::Ordering; @@ -356,7 +357,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { let subpatterns = fields .iter() .map(|field| FieldPat { - field: Field::new(self.typeck_results.field_index(field.hir_id)), + field: FieldIdx::new(self.typeck_results.field_index(field.hir_id)), pattern: self.lower_pattern(&field.pat), }) .collect(); @@ -379,7 +380,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { pats.iter() .enumerate_and_adjust(expected_len, gap_pos) .map(|(i, subpattern)| FieldPat { - field: Field::new(i), + field: FieldIdx::new(i), pattern: self.lower_pattern(subpattern), }) .collect() @@ -723,7 +724,7 @@ macro_rules! ClonePatternFoldableImpls { } ClonePatternFoldableImpls! { <'tcx> - Span, Field, Mutability, Symbol, LocalVarId, usize, + Span, FieldIdx, Mutability, Symbol, LocalVarId, usize, Region<'tcx>, Ty<'tcx>, BindingMode, AdtDef<'tcx>, SubstsRef<'tcx>, &'tcx GenericArg<'tcx>, UserType<'tcx>, UserTypeProjection, CanonicalUserTypeAnnotation<'tcx> diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index fe6728fc76e..37787d99c2d 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -7,7 +7,7 @@ use rustc_middle::traits::Reveal; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_target::abi::{VariantIdx, FIRST_VARIANT}; +use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT}; use std::{fmt, iter}; /// The value of an inserted drop flag. @@ -129,7 +129,7 @@ pub trait DropElaborator<'a, 'tcx>: fmt::Debug { /// Returns the subpath of a field of `path` (or `None` if there is no dedicated subpath). /// /// If this returns `None`, `field` will not get a dedicated drop flag. - fn field_subpath(&self, path: Self::Path, field: Field) -> Option; + fn field_subpath(&self, path: Self::Path, field: FieldIdx) -> Option; /// Returns the subpath of a dereference of `path` (or `None` if there is no dedicated subpath). /// @@ -269,7 +269,7 @@ where .iter() .enumerate() .map(|(i, f)| { - let field = Field::new(i); + let field = FieldIdx::new(i); let subpath = self.elaborator.field_subpath(variant_path, field); let tcx = self.tcx(); @@ -397,8 +397,8 @@ where .enumerate() .map(|(i, &ty)| { ( - self.tcx().mk_place_field(self.place, Field::new(i), ty), - self.elaborator.field_subpath(self.path, Field::new(i)), + self.tcx().mk_place_field(self.place, FieldIdx::new(i), ty), + self.elaborator.field_subpath(self.path, FieldIdx::new(i)), ) }) .collect(); @@ -416,9 +416,9 @@ where unique_ty.ty_adt_def().unwrap().non_enum_variant().fields[0].ty(self.tcx(), substs); let ptr_ty = self.tcx().mk_imm_ptr(substs[0].expect_ty()); - let unique_place = self.tcx().mk_place_field(self.place, Field::new(0), unique_ty); - let nonnull_place = self.tcx().mk_place_field(unique_place, Field::new(0), nonnull_ty); - let ptr_place = self.tcx().mk_place_field(nonnull_place, Field::new(0), ptr_ty); + let unique_place = self.tcx().mk_place_field(self.place, FieldIdx::new(0), unique_ty); + let nonnull_place = self.tcx().mk_place_field(unique_place, FieldIdx::new(0), nonnull_ty); + let ptr_place = self.tcx().mk_place_field(nonnull_place, FieldIdx::new(0), ptr_ty); let interior = self.tcx().mk_place_deref(ptr_place); let interior_path = self.elaborator.deref_subpath(self.path); @@ -899,7 +899,7 @@ where .iter() .enumerate() .map(|(i, f)| { - let field = Field::new(i); + let field = FieldIdx::new(i); let field_ty = f.ty(tcx, substs); Operand::Move(tcx.mk_place_field(self.place, field, field_ty)) }) diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index 7f560d61194..63e553bec53 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -40,7 +40,7 @@ use rustc_index::vec::IndexVec; use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::{self, Ty, TyCtxt}; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::{FieldIdx, VariantIdx}; use crate::lattice::{HasBottom, HasTop}; use crate::{ @@ -919,7 +919,7 @@ impl ValueOrPlace { /// Although only field projections are currently allowed, this could change in the future. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub enum TrackElem { - Field(Field), + Field(FieldIdx), Variant(VariantIdx), Discriminant, } @@ -941,7 +941,7 @@ pub fn iter_fields<'tcx>( ty: Ty<'tcx>, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, - mut f: impl FnMut(Option, Field, Ty<'tcx>), + mut f: impl FnMut(Option, FieldIdx, Ty<'tcx>), ) { match ty.kind() { ty::Tuple(list) => { diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index a7218a4f250..15f5df41153 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -13,8 +13,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_mir_dataflow::value_analysis::{Map, State, TrackElem, ValueAnalysis, ValueOrPlace}; use rustc_mir_dataflow::{lattice::FlatSet, Analysis, ResultsVisitor, SwitchIntEdgeEffects}; use rustc_span::DUMMY_SP; -use rustc_target::abi::Align; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::{Align, FieldIdx, VariantIdx}; use crate::MirPass; @@ -148,7 +147,7 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> { for (field_index, operand) in operands.iter().enumerate() { if let Some(field) = self.map().apply( variant_target_idx, - TrackElem::Field(Field::from_usize(field_index)), + TrackElem::Field(FieldIdx::from_usize(field_index)), ) { let result = self.handle_operand(operand, state); state.insert_idx(field, result, self.map()); diff --git a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs index 954bb5aff8d..58bc083280a 100644 --- a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs +++ b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs @@ -9,6 +9,7 @@ use rustc_middle::mir::patch::MirPatch; use rustc_middle::mir::visit::MutVisitor; use rustc_middle::mir::*; use rustc_middle::ty::{Ty, TyCtxt}; +use rustc_target::abi::FieldIdx; /// Constructs the types used when accessing a Box's pointer pub fn build_ptr_tys<'tcx>( @@ -32,9 +33,9 @@ pub fn build_projection<'tcx>( ptr_ty: Ty<'tcx>, ) -> [PlaceElem<'tcx>; 3] { [ - PlaceElem::Field(Field::new(0), unique_ty), - PlaceElem::Field(Field::new(0), nonnull_ty), - PlaceElem::Field(Field::new(0), ptr_ty), + PlaceElem::Field(FieldIdx::new(0), unique_ty), + PlaceElem::Field(FieldIdx::new(0), nonnull_ty), + PlaceElem::Field(FieldIdx::new(0), ptr_ty), ] } diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs index 3faccca823a..a028d6356d5 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drops.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs @@ -15,7 +15,7 @@ use rustc_mir_dataflow::MoveDataParamEnv; use rustc_mir_dataflow::{on_all_children_bits, on_all_drop_children_bits}; use rustc_mir_dataflow::{Analysis, ResultsCursor}; use rustc_span::{DesugaringKind, Span}; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::{FieldIdx, VariantIdx}; use std::fmt; /// During MIR building, Drop terminators are inserted in every place where a drop may occur. @@ -252,7 +252,7 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, 'tcx> { } } - fn field_subpath(&self, path: Self::Path, field: Field) -> Option { + fn field_subpath(&self, path: Self::Path, field: FieldIdx) -> Option { rustc_mir_dataflow::move_path_children_matching(self.ctxt.move_data(), path, |e| match e { ProjectionElem::Field(idx, _) => idx == field, _ => false, diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index 8a6360114dc..50538248d91 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -73,7 +73,7 @@ use rustc_mir_dataflow::{self, Analysis}; use rustc_span::def_id::{DefId, LocalDefId}; use rustc_span::symbol::sym; use rustc_span::Span; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::{FieldIdx, VariantIdx}; use rustc_target::spec::PanicStrategy; use std::{iter, ops}; @@ -162,9 +162,10 @@ impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> { place, Place { local: SELF_ARG, - projection: self - .tcx() - .mk_place_elems(&[ProjectionElem::Field(Field::new(0), self.ref_gen_ty)]), + projection: self.tcx().mk_place_elems(&[ProjectionElem::Field( + FieldIdx::new(0), + self.ref_gen_ty, + )]), }, self.tcx, ); @@ -297,7 +298,7 @@ impl<'tcx> TransformVisitor<'tcx> { let self_place = Place::from(SELF_ARG); let base = self.tcx.mk_place_downcast_unnamed(self_place, variant_index); let mut projection = base.projection.to_vec(); - projection.push(ProjectionElem::Field(Field::new(idx), ty)); + projection.push(ProjectionElem::Field(FieldIdx::new(idx), ty)); Place { local: base.local, projection: self.tcx.mk_place_elems(&projection) } } @@ -967,7 +968,7 @@ fn compute_layout<'tcx>( // Build the generator variant field list. // Create a map from local indices to generator struct indices. - let mut variant_fields: IndexVec> = + let mut variant_fields: IndexVec> = iter::repeat(IndexVec::new()).take(RESERVED_VARIANTS).collect(); let mut remap = FxHashMap::default(); for (suspension_point_idx, live_locals) in live_locals_at_suspension_points.iter().enumerate() { diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index b69186c9451..8574dee4ad0 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -10,7 +10,7 @@ use rustc_middle::mir::*; use rustc_middle::ty::{self, Instance, InstanceDef, ParamEnv, Ty, TyCtxt}; use rustc_session::config::OptLevel; use rustc_span::{hygiene::ExpnKind, ExpnData, LocalExpnId, Span}; -use rustc_target::abi::FIRST_VARIANT; +use rustc_target::abi::{FieldIdx, FIRST_VARIANT}; use rustc_target::spec::abi::Abi; use crate::simplify::{remove_dead_blocks, CfgSimplifier}; @@ -700,7 +700,7 @@ impl<'tcx> Inliner<'tcx> { // The `tmp0`, `tmp1`, and `tmp2` in our example above. let tuple_tmp_args = tuple_tys.iter().enumerate().map(|(i, ty)| { // This is e.g., `tuple_tmp.0` in our example above. - let tuple_field = Operand::Move(tcx.mk_place_field(tuple, Field::new(i), ty)); + let tuple_field = Operand::Move(tcx.mk_place_field(tuple, FieldIdx::new(i), ty)); // Spill to a local to make e.g., `tmp0`. self.create_temp_if_necessary(tuple_field, callsite, caller_body) diff --git a/compiler/rustc_mir_transform/src/instcombine.rs b/compiler/rustc_mir_transform/src/instcombine.rs index c9750e899a5..3d06a0a495f 100644 --- a/compiler/rustc_mir_transform/src/instcombine.rs +++ b/compiler/rustc_mir_transform/src/instcombine.rs @@ -3,14 +3,14 @@ use crate::MirPass; use rustc_hir::Mutability; use rustc_middle::mir::{ - BinOp, Body, CastKind, Constant, ConstantKind, Field, LocalDecls, Operand, Place, - ProjectionElem, Rvalue, SourceInfo, Statement, StatementKind, SwitchTargets, Terminator, - TerminatorKind, UnOp, + BinOp, Body, CastKind, Constant, ConstantKind, LocalDecls, Operand, Place, ProjectionElem, + Rvalue, SourceInfo, Statement, StatementKind, SwitchTargets, Terminator, TerminatorKind, UnOp, }; use rustc_middle::ty::layout::ValidityRequirement; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, ParamEnv, SubstsRef, Ty, TyCtxt}; use rustc_span::symbol::Symbol; +use rustc_target::abi::FieldIdx; pub struct InstCombine; @@ -187,7 +187,7 @@ impl<'tcx> InstCombineContext<'tcx, '_> { for (i, field) in variant.fields.iter().enumerate() { let field_ty = field.ty(self.tcx, substs); if field_ty == *cast_ty { - let place = place.project_deeper(&[ProjectionElem::Field(Field::from_usize(i), *cast_ty)], self.tcx); + let place = place.project_deeper(&[ProjectionElem::Field(FieldIdx::from_usize(i), *cast_ty)], self.tcx); let operand = if operand.is_move() { Operand::Move(place) } else { Operand::Copy(place) }; *rvalue = Rvalue::Use(operand); return; diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs index 6a7ceb8fef7..c136642dff2 100644 --- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs +++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs @@ -6,7 +6,7 @@ use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_span::symbol::{sym, Symbol}; use rustc_span::Span; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::{FieldIdx, VariantIdx}; pub struct LowerIntrinsics; @@ -211,7 +211,7 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics { Some(sym::Some), VariantIdx::from_u32(1), ), - PlaceElem::Field(Field::from_u32(0), *dest_ty), + PlaceElem::Field(FieldIdx::from_u32(0), *dest_ty), ], tcx, ), diff --git a/compiler/rustc_mir_transform/src/remove_uninit_drops.rs b/compiler/rustc_mir_transform/src/remove_uninit_drops.rs index e72729b152e..1f9e521d315 100644 --- a/compiler/rustc_mir_transform/src/remove_uninit_drops.rs +++ b/compiler/rustc_mir_transform/src/remove_uninit_drops.rs @@ -1,10 +1,11 @@ use rustc_index::bit_set::ChunkedBitSet; -use rustc_middle::mir::{Body, Field, TerminatorKind}; +use rustc_middle::mir::{Body, TerminatorKind}; use rustc_middle::ty::subst::SubstsRef; use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt, VariantDef}; use rustc_mir_dataflow::impls::MaybeInitializedPlaces; use rustc_mir_dataflow::move_paths::{LookupResult, MoveData, MovePathIndex}; use rustc_mir_dataflow::{self, move_path_children_matching, Analysis, MoveDataParamEnv}; +use rustc_target::abi::FieldIdx; use crate::MirPass; @@ -130,7 +131,7 @@ fn is_needs_drop_and_init<'tcx>( .fields .iter() .enumerate() - .map(|(f, field)| (Field::from_usize(f), field.ty(tcx, substs), mpi)) + .map(|(f, field)| (FieldIdx::from_usize(f), field.ty(tcx, substs), mpi)) .any(field_needs_drop_and_init) }) } @@ -138,7 +139,7 @@ fn is_needs_drop_and_init<'tcx>( ty::Tuple(fields) => fields .iter() .enumerate() - .map(|(f, f_ty)| (Field::from_usize(f), f_ty, mpi)) + .map(|(f, f_ty)| (FieldIdx::from_usize(f), f_ty, mpi)) .any(field_needs_drop_and_init), _ => true, diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 06a6deeee43..c89c09248ee 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -5,7 +5,7 @@ use rustc_middle::mir::*; use rustc_middle::ty::query::Providers; use rustc_middle::ty::InternalSubsts; use rustc_middle::ty::{self, EarlyBinder, GeneratorSubsts, Ty, TyCtxt}; -use rustc_target::abi::{VariantIdx, FIRST_VARIANT}; +use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT}; use rustc_index::vec::{Idx, IndexVec}; @@ -308,7 +308,7 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for DropShimElaborator<'a, 'tcx> { fn clear_drop_flag(&mut self, _location: Location, _path: Self::Path, _mode: DropFlagMode) {} - fn field_subpath(&self, _path: Self::Path, _field: Field) -> Option { + fn field_subpath(&self, _path: Self::Path, _field: FieldIdx) -> Option { None } fn deref_subpath(&self, _path: Self::Path) -> Option { @@ -501,7 +501,7 @@ impl<'tcx> CloneShimBuilder<'tcx> { // created by block 2*i. We store this block in `unwind` so that the next clone block // will unwind to it if cloning fails. - let field = Field::new(i); + let field = FieldIdx::new(i); let src_field = self.tcx.mk_place_field(src, field, ity); let dest_field = self.tcx.mk_place_field(dest, field, ity); @@ -724,7 +724,7 @@ fn build_call_shim<'tcx>( if let Some(untuple_args) = untuple_args { let tuple_arg = Local::new(1 + (sig.inputs().len() - 1)); args.extend(untuple_args.iter().enumerate().map(|(i, ity)| { - Operand::Move(tcx.mk_place_field(Place::from(tuple_arg), Field::new(i), *ity)) + Operand::Move(tcx.mk_place_field(Place::from(tuple_arg), FieldIdx::new(i), *ity)) })); } diff --git a/compiler/rustc_mir_transform/src/sroa.rs b/compiler/rustc_mir_transform/src/sroa.rs index ca2221520c8..c798bd05345 100644 --- a/compiler/rustc_mir_transform/src/sroa.rs +++ b/compiler/rustc_mir_transform/src/sroa.rs @@ -6,6 +6,7 @@ use rustc_middle::mir::visit::*; use rustc_middle::mir::*; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_mir_dataflow::value_analysis::{excluded_locals, iter_fields}; +use rustc_target::abi::FieldIdx; pub struct ScalarReplacementOfAggregates; @@ -115,7 +116,7 @@ fn escaping_locals(excluded: &BitSet, body: &Body<'_>) -> BitSet { struct ReplacementMap<'tcx> { /// Pre-computed list of all "new" locals for each "old" local. This is used to expand storage /// and deinit statement and debuginfo. - fragments: IndexVec, Local)>>>>, + fragments: IndexVec, Local)>>>>, } impl<'tcx> ReplacementMap<'tcx> { @@ -129,7 +130,7 @@ impl<'tcx> ReplacementMap<'tcx> { fn place_fragments( &self, place: Place<'tcx>, - ) -> Option, Local)> + '_> { + ) -> Option, Local)> + '_> { let local = place.as_local()?; let fields = self.fragments[local].as_ref()?; Some(fields.iter_enumerated().filter_map(|(field, &opt_ty_local)| { From 0d89c6a2d44b78d052280d7faecfcb79e6f3d4a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Fri, 3 Feb 2023 09:04:12 +0100 Subject: [PATCH 238/346] Support TLS access into dylibs on Windows --- .../rustc_codegen_cranelift/src/constant.rs | 22 +++++++--- .../src/back/symbol_export.rs | 43 ++++++++++++++++--- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 14 +++++- .../src/interpret/terminator.rs | 1 + .../src/middle/exported_symbols.rs | 5 +++ compiler/rustc_middle/src/mir/mono.rs | 1 + compiler/rustc_middle/src/mir/tcx.rs | 12 +----- compiler/rustc_middle/src/mir/visit.rs | 1 + compiler/rustc_middle/src/ty/instance.rs | 17 +++++++- compiler/rustc_middle/src/ty/mod.rs | 1 + compiler/rustc_middle/src/ty/util.rs | 22 ++++++++++ compiler/rustc_mir_transform/src/inline.rs | 1 + .../rustc_mir_transform/src/inline/cycle.rs | 1 + compiler/rustc_mir_transform/src/shim.rs | 29 +++++++++++++ compiler/rustc_monomorphize/src/collector.rs | 24 ++++++++--- .../src/partitioning/default.rs | 35 +++++++++------ compiler/rustc_symbol_mangling/src/legacy.rs | 4 ++ compiler/rustc_symbol_mangling/src/v0.rs | 1 + compiler/rustc_target/src/spec/mod.rs | 5 +++ compiler/rustc_target/src/spec/msvc_base.rs | 1 + .../rustc_target/src/spec/windows_gnu_base.rs | 1 + .../src/spec/windows_gnullvm_base.rs | 1 + compiler/rustc_ty_utils/src/abi.rs | 12 +++++- 23 files changed, 207 insertions(+), 47 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/constant.rs b/compiler/rustc_codegen_cranelift/src/constant.rs index 31278f810e9..ebb4de33f99 100644 --- a/compiler/rustc_codegen_cranelift/src/constant.rs +++ b/compiler/rustc_codegen_cranelift/src/constant.rs @@ -54,12 +54,22 @@ pub(crate) fn codegen_tls_ref<'tcx>( def_id: DefId, layout: TyAndLayout<'tcx>, ) -> CValue<'tcx> { - let data_id = data_id_for_static(fx.tcx, fx.module, def_id, false); - let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); - if fx.clif_comments.enabled() { - fx.add_comment(local_data_id, format!("tls {:?}", def_id)); - } - let tls_ptr = fx.bcx.ins().tls_value(fx.pointer_type, local_data_id); + let tls_ptr = if !def_id.is_local() && fx.tcx.needs_thread_local_shim(def_id) { + let instance = ty::Instance { + def: ty::InstanceDef::ThreadLocalShim(def_id), + substs: ty::InternalSubsts::empty(), + }; + let func_ref = fx.get_function_ref(instance); + let call = fx.bcx.ins().call(func_ref, &[]); + fx.bcx.func.dfg.first_result(call) + } else { + let data_id = data_id_for_static(fx.tcx, fx.module, def_id, false); + let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func); + if fx.clif_comments.enabled() { + fx.add_comment(local_data_id, format!("tls {:?}", def_id)); + } + fx.bcx.ins().tls_value(fx.pointer_type, local_data_id) + }; CValue::by_val(tls_ptr, layout) } diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs index e403a1fd8ae..d0fd3cd7666 100644 --- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs +++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs @@ -177,14 +177,29 @@ fn exported_symbols_provider_local( // FIXME: Sorting this is unnecessary since we are sorting later anyway. // Can we skip the later sorting? - let mut symbols: Vec<_> = tcx.with_stable_hashing_context(|hcx| { - tcx.reachable_non_generics(LOCAL_CRATE) - .to_sorted(&hcx, true) - .into_iter() - .map(|(&def_id, &info)| (ExportedSymbol::NonGeneric(def_id), info)) - .collect() + let sorted = tcx.with_stable_hashing_context(|hcx| { + tcx.reachable_non_generics(LOCAL_CRATE).to_sorted(&hcx, true) }); + let mut symbols: Vec<_> = + sorted.iter().map(|(&def_id, &info)| (ExportedSymbol::NonGeneric(def_id), info)).collect(); + + // Export TLS shims + if !tcx.sess.target.dll_tls_export { + symbols.extend(sorted.iter().filter_map(|(&def_id, &info)| { + tcx.needs_thread_local_shim(def_id).then(|| { + ( + ExportedSymbol::ThreadLocalShim(def_id), + SymbolExportInfo { + level: info.level, + kind: SymbolExportKind::Text, + used: info.used, + }, + ) + }) + })) + } + if tcx.entry_fn(()).is_some() { let exported_symbol = ExportedSymbol::NoDefId(SymbolName::new(tcx, tcx.sess.target.entry_name.as_ref())); @@ -380,7 +395,9 @@ fn upstream_monomorphizations_provider( continue; } } - ExportedSymbol::NonGeneric(..) | ExportedSymbol::NoDefId(..) => { + ExportedSymbol::NonGeneric(..) + | ExportedSymbol::ThreadLocalShim(..) + | ExportedSymbol::NoDefId(..) => { // These are no monomorphizations continue; } @@ -500,6 +517,16 @@ pub fn symbol_name_for_instance_in_crate<'tcx>( instantiating_crate, ) } + ExportedSymbol::ThreadLocalShim(def_id) => { + rustc_symbol_mangling::symbol_name_for_instance_in_crate( + tcx, + ty::Instance { + def: ty::InstanceDef::ThreadLocalShim(def_id), + substs: ty::InternalSubsts::empty(), + }, + instantiating_crate, + ) + } ExportedSymbol::DropGlue(ty) => rustc_symbol_mangling::symbol_name_for_instance_in_crate( tcx, Instance::resolve_drop_in_place(tcx, ty), @@ -548,6 +575,8 @@ pub fn linking_symbol_name_for_instance_in_crate<'tcx>( ExportedSymbol::DropGlue(..) => None, // NoDefId always follow the target's default symbol decoration scheme. ExportedSymbol::NoDefId(..) => None, + // ThreadLocalShim always follow the target's default symbol decoration scheme. + ExportedSymbol::ThreadLocalShim(..) => None, }; let (conv, args) = instance diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index d867d6b0cd4..0a59fabdc17 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -516,8 +516,20 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { mir::Rvalue::ThreadLocalRef(def_id) => { assert!(bx.cx().tcx().is_static(def_id)); - let static_ = bx.get_static(def_id); let layout = bx.layout_of(bx.cx().tcx().static_ptr_ty(def_id)); + let static_ = if !def_id.is_local() && bx.cx().tcx().needs_thread_local_shim(def_id) + { + let instance = ty::Instance { + def: ty::InstanceDef::ThreadLocalShim(def_id), + substs: ty::InternalSubsts::empty(), + }; + let fn_ptr = bx.get_fn_addr(instance); + let fn_abi = bx.fn_abi_of_instance(instance, ty::List::empty()); + let fn_ty = bx.fn_decl_backend_type(&fn_abi); + bx.call(fn_ty, Some(fn_abi), fn_ptr, &[], None) + } else { + bx.get_static(def_id) + }; OperandRef { val: OperandValue::Immediate(static_), layout } } mir::Rvalue::Use(ref operand) => self.codegen_operand(bx, operand), diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index 54d67bd1f29..2d9fee9852c 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -383,6 +383,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { | ty::InstanceDef::DropGlue(..) | ty::InstanceDef::CloneShim(..) | ty::InstanceDef::FnPtrAddrShim(..) + | ty::InstanceDef::ThreadLocalShim(..) | ty::InstanceDef::Item(_) => { // We need MIR for this fn let Some((body, instance)) = diff --git a/compiler/rustc_middle/src/middle/exported_symbols.rs b/compiler/rustc_middle/src/middle/exported_symbols.rs index 631fd09ec4c..c0c0fd07b6e 100644 --- a/compiler/rustc_middle/src/middle/exported_symbols.rs +++ b/compiler/rustc_middle/src/middle/exported_symbols.rs @@ -43,6 +43,7 @@ pub enum ExportedSymbol<'tcx> { NonGeneric(DefId), Generic(DefId, SubstsRef<'tcx>), DropGlue(Ty<'tcx>), + ThreadLocalShim(DefId), NoDefId(ty::SymbolName<'tcx>), } @@ -58,6 +59,10 @@ impl<'tcx> ExportedSymbol<'tcx> { ExportedSymbol::DropGlue(ty) => { tcx.symbol_name(ty::Instance::resolve_drop_in_place(tcx, ty)) } + ExportedSymbol::ThreadLocalShim(def_id) => tcx.symbol_name(ty::Instance { + def: ty::InstanceDef::ThreadLocalShim(def_id), + substs: ty::InternalSubsts::empty(), + }), ExportedSymbol::NoDefId(symbol_name) => symbol_name, } } diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index 90397f01bc8..f592f1515c1 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -382,6 +382,7 @@ impl<'tcx> CodegenUnit<'tcx> { | InstanceDef::ClosureOnceShim { .. } | InstanceDef::DropGlue(..) | InstanceDef::CloneShim(..) + | InstanceDef::ThreadLocalShim(..) | InstanceDef::FnPtrAddrShim(..) => None, } } diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index 0aa2c500f51..ee439df8b6b 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -164,17 +164,7 @@ impl<'tcx> Rvalue<'tcx> { Rvalue::Repeat(ref operand, count) => { tcx.mk_array_with_const_len(operand.ty(local_decls, tcx), count) } - Rvalue::ThreadLocalRef(did) => { - let static_ty = tcx.type_of(did).subst_identity(); - if tcx.is_mutable_static(did) { - tcx.mk_mut_ptr(static_ty) - } else if tcx.is_foreign_item(did) { - tcx.mk_imm_ptr(static_ty) - } else { - // FIXME: These things don't *really* have 'static lifetime. - tcx.mk_imm_ref(tcx.lifetimes.re_static, static_ty) - } - } + Rvalue::ThreadLocalRef(did) => tcx.thread_local_ptr_ty(did), Rvalue::Ref(reg, bk, ref place) => { let place_ty = place.ty(local_decls, tcx).ty; tcx.mk_ref(reg, ty::TypeAndMut { ty: place_ty, mutbl: bk.to_mutbl_lossy() }) diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 9b31ad783fc..b39fc3aaaff 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -335,6 +335,7 @@ macro_rules! make_mir_visitor { ty::InstanceDef::VTableShim(_def_id) | ty::InstanceDef::ReifyShim(_def_id) | ty::InstanceDef::Virtual(_def_id, _) | + ty::InstanceDef::ThreadLocalShim(_def_id) | ty::InstanceDef::ClosureOnceShim { call_once: _def_id, track_caller: _ } | ty::InstanceDef::DropGlue(_def_id, None) => {} diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index 036b4477679..e73225f70cc 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -82,6 +82,11 @@ pub enum InstanceDef<'tcx> { /// The `DefId` is the ID of the `call_once` method in `FnOnce`. ClosureOnceShim { call_once: DefId, track_caller: bool }, + /// Compiler-generated accessor for thread locals which returns a reference to the thread local + /// the `DefId` defines. This is used to export thread locals from dylibs on platforms lacking + /// native support. + ThreadLocalShim(DefId), + /// `core::ptr::drop_in_place::`. /// /// The `DefId` is for `core::ptr::drop_in_place`. @@ -156,6 +161,7 @@ impl<'tcx> InstanceDef<'tcx> { | InstanceDef::FnPtrShim(def_id, _) | InstanceDef::Virtual(def_id, _) | InstanceDef::Intrinsic(def_id) + | InstanceDef::ThreadLocalShim(def_id) | InstanceDef::ClosureOnceShim { call_once: def_id, track_caller: _ } | InstanceDef::DropGlue(def_id, _) | InstanceDef::CloneShim(def_id, _) @@ -167,7 +173,9 @@ impl<'tcx> InstanceDef<'tcx> { pub fn def_id_if_not_guaranteed_local_codegen(self) -> Option { match self { ty::InstanceDef::Item(def) => Some(def.did), - ty::InstanceDef::DropGlue(def_id, Some(_)) => Some(def_id), + ty::InstanceDef::DropGlue(def_id, Some(_)) | InstanceDef::ThreadLocalShim(def_id) => { + Some(def_id) + } InstanceDef::VTableShim(..) | InstanceDef::ReifyShim(..) | InstanceDef::FnPtrShim(..) @@ -192,6 +200,7 @@ impl<'tcx> InstanceDef<'tcx> { | InstanceDef::ClosureOnceShim { call_once: def_id, track_caller: _ } | InstanceDef::DropGlue(def_id, _) | InstanceDef::CloneShim(def_id, _) + | InstanceDef::ThreadLocalShim(def_id) | InstanceDef::FnPtrAddrShim(def_id, _) => ty::WithOptConstParam::unknown(def_id), } } @@ -215,6 +224,7 @@ impl<'tcx> InstanceDef<'tcx> { let def_id = match *self { ty::InstanceDef::Item(def) => def.did, ty::InstanceDef::DropGlue(_, Some(_)) => return false, + ty::InstanceDef::ThreadLocalShim(_) => return false, _ => return true, }; matches!( @@ -255,6 +265,9 @@ impl<'tcx> InstanceDef<'tcx> { ) }); } + if let ty::InstanceDef::ThreadLocalShim(..) = *self { + return false; + } tcx.codegen_fn_attrs(self.def_id()).requests_inline() } @@ -278,6 +291,7 @@ impl<'tcx> InstanceDef<'tcx> { pub fn has_polymorphic_mir_body(&self) -> bool { match *self { InstanceDef::CloneShim(..) + | InstanceDef::ThreadLocalShim(..) | InstanceDef::FnPtrAddrShim(..) | InstanceDef::FnPtrShim(..) | InstanceDef::DropGlue(_, Some(_)) => false, @@ -310,6 +324,7 @@ fn fmt_instance( InstanceDef::Item(_) => Ok(()), InstanceDef::VTableShim(_) => write!(f, " - shim(vtable)"), InstanceDef::ReifyShim(_) => write!(f, " - shim(reify)"), + InstanceDef::ThreadLocalShim(_) => write!(f, " - shim(tls)"), InstanceDef::Intrinsic(_) => write!(f, " - intrinsic"), InstanceDef::Virtual(_, num) => write!(f, " - virtual#{}", num), InstanceDef::FnPtrShim(_, ty) => write!(f, " - shim({})", ty), diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index c9dd3e499a8..7df90fab56f 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2386,6 +2386,7 @@ impl<'tcx> TyCtxt<'tcx> { | ty::InstanceDef::ClosureOnceShim { .. } | ty::InstanceDef::DropGlue(..) | ty::InstanceDef::CloneShim(..) + | ty::InstanceDef::ThreadLocalShim(..) | ty::InstanceDef::FnPtrAddrShim(..) => self.mir_shims(instance), } } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index dcd9743196e..e9c0552812b 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -597,6 +597,28 @@ impl<'tcx> TyCtxt<'tcx> { self.static_mutability(def_id) == Some(hir::Mutability::Mut) } + /// Returns `true` if the item pointed to by `def_id` is a thread local which needs a + /// thread local shim generated. + #[inline] + pub fn needs_thread_local_shim(self, def_id: DefId) -> bool { + !self.sess.target.dll_tls_export + && self.is_thread_local_static(def_id) + && !self.is_foreign_item(def_id) + } + + /// Returns the type a reference to the thread local takes in MIR. + pub fn thread_local_ptr_ty(self, def_id: DefId) -> Ty<'tcx> { + let static_ty = self.type_of(def_id).subst_identity(); + if self.is_mutable_static(def_id) { + self.mk_mut_ptr(static_ty) + } else if self.is_foreign_item(def_id) { + self.mk_imm_ptr(static_ty) + } else { + // FIXME: These things don't *really* have 'static lifetime. + self.mk_imm_ref(self.lifetimes.re_static, static_ty) + } + } + /// Get the type of the pointer to the static that we use in MIR. pub fn static_ptr_ty(self, def_id: DefId) -> Ty<'tcx> { // Make sure that any constants in the static's type are evaluated. diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index b69186c9451..5c7415192b9 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -271,6 +271,7 @@ impl<'tcx> Inliner<'tcx> { | InstanceDef::ClosureOnceShim { .. } | InstanceDef::DropGlue(..) | InstanceDef::CloneShim(..) + | InstanceDef::ThreadLocalShim(..) | InstanceDef::FnPtrAddrShim(..) => return Ok(()), } diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs index faf404c7771..8aa3c23d019 100644 --- a/compiler/rustc_mir_transform/src/inline/cycle.rs +++ b/compiler/rustc_mir_transform/src/inline/cycle.rs @@ -83,6 +83,7 @@ pub(crate) fn mir_callgraph_reachable<'tcx>( | InstanceDef::ReifyShim(_) | InstanceDef::FnPtrShim(..) | InstanceDef::ClosureOnceShim { .. } + | InstanceDef::ThreadLocalShim { .. } | InstanceDef::CloneShim(..) => {} // This shim does not call any other functions, thus there can be no recursion. diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 06a6deeee43..2ef5c1062fe 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -76,6 +76,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<' build_drop_shim(tcx, def_id, ty) } + ty::InstanceDef::ThreadLocalShim(..) => build_thread_local_shim(tcx, instance), ty::InstanceDef::CloneShim(def_id, ty) => build_clone_shim(tcx, def_id, ty), ty::InstanceDef::FnPtrAddrShim(def_id, ty) => build_fn_ptr_addr_shim(tcx, def_id, ty), ty::InstanceDef::Virtual(..) => { @@ -322,6 +323,34 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for DropShimElaborator<'a, 'tcx> { } } +fn build_thread_local_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<'tcx> { + let def_id = instance.def_id(); + + let span = tcx.def_span(def_id); + let source_info = SourceInfo::outermost(span); + + let mut blocks = IndexVec::with_capacity(1); + blocks.push(BasicBlockData { + statements: vec![Statement { + source_info, + kind: StatementKind::Assign(Box::new(( + Place::return_place(), + Rvalue::ThreadLocalRef(def_id), + ))), + }], + terminator: Some(Terminator { source_info, kind: TerminatorKind::Return }), + is_cleanup: false, + }); + + new_body( + MirSource::from_instance(instance), + blocks, + IndexVec::from_raw(vec![LocalDecl::new(tcx.thread_local_ptr_ty(def_id), span)]), + 0, + span, + ) +} + /// Builds a `Clone::clone` shim for `self_ty`. Here, `def_id` is `Clone::clone`. fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -> Body<'tcx> { debug!("build_clone_shim(def_id={:?})", def_id); diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 98265d58a0a..af0222c8172 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -190,7 +190,8 @@ use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::query::TyCtxtAt; use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts}; use rustc_middle::ty::{ - self, GenericParamDefKind, Instance, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, VtblEntry, + self, GenericParamDefKind, Instance, InstanceDef, Ty, TyCtxt, TypeFoldable, TypeVisitableExt, + VtblEntry, }; use rustc_middle::{middle::codegen_fn_attrs::CodegenFnAttrFlags, mir::visit::TyContext}; use rustc_session::config::EntryFnType; @@ -462,6 +463,16 @@ fn collect_items_rec<'tcx>( collect_miri(tcx, id, &mut neighbors); } } + + if tcx.needs_thread_local_shim(def_id) { + neighbors.push(respan( + starting_point.span, + MonoItem::Fn(Instance { + def: InstanceDef::ThreadLocalShim(def_id), + substs: InternalSubsts::empty(), + }), + )); + } } MonoItem::Fn(instance) => { // Sanity check whether this ended up being collected accidentally @@ -962,6 +973,9 @@ fn visit_instance_use<'tcx>( bug!("{:?} being reified", instance); } } + ty::InstanceDef::ThreadLocalShim(..) => { + bug!("{:?} being reified", instance); + } ty::InstanceDef::DropGlue(_, None) => { // Don't need to emit noop drop glue if we are calling directly. if !is_direct_call { @@ -1210,11 +1224,9 @@ impl<'v> RootCollector<'_, 'v> { self.output.push(dummy_spanned(MonoItem::GlobalAsm(id))); } DefKind::Static(..) => { - debug!( - "RootCollector: ItemKind::Static({})", - self.tcx.def_path_str(id.owner_id.to_def_id()) - ); - self.output.push(dummy_spanned(MonoItem::Static(id.owner_id.to_def_id()))); + let def_id = id.owner_id.to_def_id(); + debug!("RootCollector: ItemKind::Static({})", self.tcx.def_path_str(def_id)); + self.output.push(dummy_spanned(MonoItem::Static(def_id))); } DefKind::Const => { // const items only generate mono items if they are diff --git a/compiler/rustc_monomorphize/src/partitioning/default.rs b/compiler/rustc_monomorphize/src/partitioning/default.rs index 64968a76ab5..50bcc3336d6 100644 --- a/compiler/rustc_monomorphize/src/partitioning/default.rs +++ b/compiler/rustc_monomorphize/src/partitioning/default.rs @@ -279,6 +279,7 @@ fn characteristic_def_id_of_mono_item<'tcx>( | ty::InstanceDef::DropGlue(..) | ty::InstanceDef::Virtual(..) | ty::InstanceDef::CloneShim(..) + | ty::InstanceDef::ThreadLocalShim(..) | ty::InstanceDef::FnPtrAddrShim(..) => return None, }; @@ -392,6 +393,19 @@ fn mono_item_linkage_and_visibility<'tcx>( type CguNameCache = FxHashMap<(DefId, bool), Symbol>; +fn static_visibility<'tcx>( + tcx: TyCtxt<'tcx>, + can_be_internalized: &mut bool, + def_id: DefId, +) -> Visibility { + if tcx.is_reachable_non_generic(def_id) { + *can_be_internalized = false; + default_visibility(tcx, def_id, false) + } else { + Visibility::Hidden + } +} + fn mono_item_visibility<'tcx>( tcx: TyCtxt<'tcx>, mono_item: &MonoItem<'tcx>, @@ -403,21 +417,9 @@ fn mono_item_visibility<'tcx>( MonoItem::Fn(instance) => instance, // Misc handling for generics and such, but otherwise: - MonoItem::Static(def_id) => { - return if tcx.is_reachable_non_generic(*def_id) { - *can_be_internalized = false; - default_visibility(tcx, *def_id, false) - } else { - Visibility::Hidden - }; - } + MonoItem::Static(def_id) => return static_visibility(tcx, can_be_internalized, *def_id), MonoItem::GlobalAsm(item_id) => { - return if tcx.is_reachable_non_generic(item_id.owner_id) { - *can_be_internalized = false; - default_visibility(tcx, item_id.owner_id.to_def_id(), false) - } else { - Visibility::Hidden - }; + return static_visibility(tcx, can_be_internalized, item_id.owner_id.to_def_id()); } }; @@ -425,6 +427,11 @@ fn mono_item_visibility<'tcx>( InstanceDef::Item(def) => def.did, InstanceDef::DropGlue(def_id, Some(_)) => def_id, + // We match the visiblity of statics here + InstanceDef::ThreadLocalShim(def_id) => { + return static_visibility(tcx, can_be_internalized, def_id); + } + // These are all compiler glue and such, never exported, always hidden. InstanceDef::VTableShim(..) | InstanceDef::ReifyShim(..) diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs index 2368468c891..5cbca81926b 100644 --- a/compiler/rustc_symbol_mangling/src/legacy.rs +++ b/compiler/rustc_symbol_mangling/src/legacy.rs @@ -65,6 +65,10 @@ pub(super) fn mangle<'tcx>( ) .unwrap(); + if let ty::InstanceDef::ThreadLocalShim(..) = instance.def { + let _ = printer.write_str("{{tls-shim}}"); + } + if let ty::InstanceDef::VTableShim(..) = instance.def { let _ = printer.write_str("{{vtable-shim}}"); } diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 2f20d42139c..cac7ff72267 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -42,6 +42,7 @@ pub(super) fn mangle<'tcx>( // Append `::{shim:...#0}` to shims that can coexist with a non-shim instance. let shim_kind = match instance.def { + ty::InstanceDef::ThreadLocalShim(_) => Some("tls"), ty::InstanceDef::VTableShim(_) => Some("vtable"), ty::InstanceDef::ReifyShim(_) => Some("reify"), diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 2553b11d878..b53cd2e7df1 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1468,6 +1468,8 @@ pub struct TargetOptions { pub features: StaticCow, /// Whether dynamic linking is available on this target. Defaults to false. pub dynamic_linking: bool, + /// Whether dynamic linking can export TLS globals. Defaults to true. + pub dll_tls_export: bool, /// If dynamic linking is available, whether only cdylibs are supported. pub only_cdylib: bool, /// Whether executables are available on this target. Defaults to true. @@ -1859,6 +1861,7 @@ impl Default for TargetOptions { cpu: "generic".into(), features: "".into(), dynamic_linking: false, + dll_tls_export: true, only_cdylib: false, executables: true, relocation_model: RelocModel::Pic, @@ -2530,6 +2533,7 @@ impl Target { key!(cpu); key!(features); key!(dynamic_linking, bool); + key!(dll_tls_export, bool); key!(only_cdylib, bool); key!(executables, bool); key!(relocation_model, RelocModel)?; @@ -2783,6 +2787,7 @@ impl ToJson for Target { target_option_val!(cpu); target_option_val!(features); target_option_val!(dynamic_linking); + target_option_val!(dll_tls_export); target_option_val!(only_cdylib); target_option_val!(executables); target_option_val!(relocation_model); diff --git a/compiler/rustc_target/src/spec/msvc_base.rs b/compiler/rustc_target/src/spec/msvc_base.rs index 1dad9133ea3..efe949a4e90 100644 --- a/compiler/rustc_target/src/spec/msvc_base.rs +++ b/compiler/rustc_target/src/spec/msvc_base.rs @@ -8,6 +8,7 @@ pub fn opts() -> TargetOptions { TargetOptions { linker_flavor: LinkerFlavor::Msvc(Lld::No), + dll_tls_export: false, is_like_windows: true, is_like_msvc: true, pre_link_args, diff --git a/compiler/rustc_target/src/spec/windows_gnu_base.rs b/compiler/rustc_target/src/spec/windows_gnu_base.rs index a32ca469b2f..2231983f071 100644 --- a/compiler/rustc_target/src/spec/windows_gnu_base.rs +++ b/compiler/rustc_target/src/spec/windows_gnu_base.rs @@ -78,6 +78,7 @@ pub fn opts() -> TargetOptions { function_sections: false, linker: Some("gcc".into()), dynamic_linking: true, + dll_tls_export: false, dll_prefix: "".into(), dll_suffix: ".dll".into(), exe_suffix: ".exe".into(), diff --git a/compiler/rustc_target/src/spec/windows_gnullvm_base.rs b/compiler/rustc_target/src/spec/windows_gnullvm_base.rs index cada28652f9..b1d8e2be5a6 100644 --- a/compiler/rustc_target/src/spec/windows_gnullvm_base.rs +++ b/compiler/rustc_target/src/spec/windows_gnullvm_base.rs @@ -23,6 +23,7 @@ pub fn opts() -> TargetOptions { abi: "llvm".into(), linker: Some("clang".into()), dynamic_linking: true, + dll_tls_export: false, dll_prefix: "".into(), dll_suffix: ".dll".into(), exe_suffix: ".exe".into(), diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs index ee5a7909ba3..271284b2d81 100644 --- a/compiler/rustc_ty_utils/src/abi.rs +++ b/compiler/rustc_ty_utils/src/abi.rs @@ -3,7 +3,7 @@ use rustc_hir::lang_items::LangItem; use rustc_middle::ty::layout::{ fn_can_unwind, FnAbiError, HasParamEnv, HasTyCtxt, LayoutCx, LayoutOf, TyAndLayout, }; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::ty::{self, InstanceDef, Ty, TyCtxt}; use rustc_session::config::OptLevel; use rustc_span::def_id::DefId; use rustc_target::abi::call::{ @@ -29,6 +29,16 @@ fn fn_sig_for_fn_abi<'tcx>( instance: ty::Instance<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> ty::PolyFnSig<'tcx> { + if let InstanceDef::ThreadLocalShim(..) = instance.def { + return ty::Binder::dummy(tcx.mk_fn_sig( + [], + tcx.thread_local_ptr_ty(instance.def_id()), + false, + hir::Unsafety::Normal, + rustc_target::spec::abi::Abi::Unadjusted, + )); + } + let ty = instance.ty(tcx, param_env); match *ty.kind() { ty::FnDef(..) => { From 3019a341f328f1c5e4a671df2b61171ae925b034 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 15 Feb 2023 16:50:28 +0100 Subject: [PATCH 239/346] Use #[inline] on Windows for thread local access --- .../src/sys/common/thread_local/fast_local.rs | 26 ++----------------- .../src/sys/common/thread_local/os_local.rs | 26 ++----------------- 2 files changed, 4 insertions(+), 48 deletions(-) diff --git a/library/std/src/sys/common/thread_local/fast_local.rs b/library/std/src/sys/common/thread_local/fast_local.rs index 2addcc4a759..e229eb16aa1 100644 --- a/library/std/src/sys/common/thread_local/fast_local.rs +++ b/library/std/src/sys/common/thread_local/fast_local.rs @@ -10,7 +10,7 @@ macro_rules! __thread_local_inner { // used to generate the `LocalKey` value for const-initialized thread locals (@key $t:ty, const $init:expr) => {{ - #[cfg_attr(not(windows), inline)] // see comments below + #[cfg_attr(not(bootstrap), inline)] #[deny(unsafe_op_in_unsafe_fn)] unsafe fn __getit( _init: $crate::option::Option<&mut $crate::option::Option<$t>>, @@ -77,29 +77,7 @@ macro_rules! __thread_local_inner { #[inline] fn __init() -> $t { $init } - // When reading this function you might ask "why is this inlined - // everywhere other than Windows?", and that's a very reasonable - // question to ask. The short story is that it segfaults rustc if - // this function is inlined. The longer story is that Windows looks - // to not support `extern` references to thread locals across DLL - // boundaries. This appears to at least not be supported in the ABI - // that LLVM implements. - // - // Because of this we never inline on Windows, but we do inline on - // other platforms (where external references to thread locals - // across DLLs are supported). A better fix for this would be to - // inline this function on Windows, but only for "statically linked" - // components. For example if two separately compiled rlibs end up - // getting linked into a DLL then it's fine to inline this function - // across that boundary. It's only not fine to inline this function - // across a DLL boundary. Unfortunately rustc doesn't currently - // have this sort of logic available in an attribute, and it's not - // clear that rustc is even equipped to answer this (it's more of a - // Cargo question kinda). This means that, unfortunately, Windows - // gets the pessimistic path for now where it's never inlined. - // - // The issue of "should enable on Windows sometimes" is #84933 - #[cfg_attr(not(windows), inline)] + #[cfg_attr(not(bootstrap), inline)] unsafe fn __getit( init: $crate::option::Option<&mut $crate::option::Option<$t>>, ) -> $crate::option::Option<&'static $t> { diff --git a/library/std/src/sys/common/thread_local/os_local.rs b/library/std/src/sys/common/thread_local/os_local.rs index 6f6560c4aa9..ce74ad3486e 100644 --- a/library/std/src/sys/common/thread_local/os_local.rs +++ b/library/std/src/sys/common/thread_local/os_local.rs @@ -10,7 +10,7 @@ macro_rules! __thread_local_inner { // used to generate the `LocalKey` value for const-initialized thread locals (@key $t:ty, const $init:expr) => {{ - #[cfg_attr(not(windows), inline)] // see comments below + #[cfg_attr(not(bootstrap), inline)] #[deny(unsafe_op_in_unsafe_fn)] unsafe fn __getit( _init: $crate::option::Option<&mut $crate::option::Option<$t>>, @@ -49,29 +49,7 @@ macro_rules! __thread_local_inner { #[inline] fn __init() -> $t { $init } - // When reading this function you might ask "why is this inlined - // everywhere other than Windows?", and that's a very reasonable - // question to ask. The short story is that it segfaults rustc if - // this function is inlined. The longer story is that Windows looks - // to not support `extern` references to thread locals across DLL - // boundaries. This appears to at least not be supported in the ABI - // that LLVM implements. - // - // Because of this we never inline on Windows, but we do inline on - // other platforms (where external references to thread locals - // across DLLs are supported). A better fix for this would be to - // inline this function on Windows, but only for "statically linked" - // components. For example if two separately compiled rlibs end up - // getting linked into a DLL then it's fine to inline this function - // across that boundary. It's only not fine to inline this function - // across a DLL boundary. Unfortunately rustc doesn't currently - // have this sort of logic available in an attribute, and it's not - // clear that rustc is even equipped to answer this (it's more of a - // Cargo question kinda). This means that, unfortunately, Windows - // gets the pessimistic path for now where it's never inlined. - // - // The issue of "should enable on Windows sometimes" is #84933 - #[cfg_attr(not(windows), inline)] + #[cfg_attr(not(bootstrap), inline)] unsafe fn __getit( init: $crate::option::Option<&mut $crate::option::Option<$t>>, ) -> $crate::option::Option<&'static $t> { From d3cc2f76465b854129daa4dca2a10b137a8699bf Mon Sep 17 00:00:00 2001 From: Kai Luo Date: Wed, 29 Mar 2023 14:55:30 +0800 Subject: [PATCH 240/346] Use LIBPATH in compiletest --- src/tools/compiletest/src/util.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index 5f6a27e5366..748240cc94b 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -156,6 +156,8 @@ pub fn dylib_env_var() -> &'static str { "DYLD_LIBRARY_PATH" } else if cfg!(target_os = "haiku") { "LIBRARY_PATH" + } else if cfg!(target_os = "aix") { + "LIBPATH" } else { "LD_LIBRARY_PATH" } From 843c5e361e1b392f89f71ac26a951f8dfd84e43a Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Wed, 29 Mar 2023 00:04:14 -0700 Subject: [PATCH 241/346] =?UTF-8?q?Rename=20`IndexVec::last`=20=E2=86=92?= =?UTF-8?q?=20`last=5Findex`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As I've been trying to replace a `Vec` with an `IndexVec`, having `last` exist on both but returning very different types makes the transition a bit awkward -- the errors are later, where you get things like "there's no `ty` method on `mir::Field`" rather than a more localized error like "hey, there's no `last` on `IndexVec`". So I propose renaming `last` to `last_index` to help distinguish `Vec::last`, which returns an element, and `IndexVec::last_index`, which returns an index. (Similarly, `Iterator::last` also returns an element, not an index.) --- compiler/rustc_const_eval/src/transform/promote_consts.rs | 4 ++-- compiler/rustc_index/src/vec.rs | 2 +- compiler/rustc_mir_transform/src/coverage/tests.rs | 2 +- compiler/rustc_trait_selection/src/solve/search_graph/mod.rs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs index 648a86d32fc..40c848de2be 100644 --- a/compiler/rustc_const_eval/src/transform/promote_consts.rs +++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs @@ -707,7 +707,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { } fn assign(&mut self, dest: Local, rvalue: Rvalue<'tcx>, span: Span) { - let last = self.promoted.basic_blocks.last().unwrap(); + let last = self.promoted.basic_blocks.last_index().unwrap(); let data = &mut self.promoted[last]; data.statements.push(Statement { source_info: SourceInfo::outermost(span), @@ -800,7 +800,7 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> { self.visit_operand(arg, loc); } - let last = self.promoted.basic_blocks.last().unwrap(); + let last = self.promoted.basic_blocks.last_index().unwrap(); let new_target = self.new_block(); *self.promoted[last].terminator_mut() = Terminator { diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs index 68cdc6d7711..acf883fe90c 100644 --- a/compiler/rustc_index/src/vec.rs +++ b/compiler/rustc_index/src/vec.rs @@ -216,7 +216,7 @@ impl IndexVec { } #[inline] - pub fn last(&self) -> Option { + pub fn last_index(&self) -> Option { self.len().checked_sub(1).map(I::new) } diff --git a/compiler/rustc_mir_transform/src/coverage/tests.rs b/compiler/rustc_mir_transform/src/coverage/tests.rs index aded8039dc3..59b506e7345 100644 --- a/compiler/rustc_mir_transform/src/coverage/tests.rs +++ b/compiler/rustc_mir_transform/src/coverage/tests.rs @@ -65,7 +65,7 @@ impl<'tcx> MockBlocks<'tcx> { } fn push(&mut self, kind: TerminatorKind<'tcx>) -> BasicBlock { - let next_lo = if let Some(last) = self.blocks.last() { + let next_lo = if let Some(last) = self.blocks.last_index() { self.blocks[last].terminator().source_info.span.hi() } else { BytePos(1) diff --git a/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs b/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs index 9773a3eacd6..717905e55e5 100644 --- a/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs @@ -54,7 +54,7 @@ impl<'tcx> SearchGraph<'tcx> { /// Whether we're currently in a cycle. This should only be used /// for debug assertions. pub(super) fn in_cycle(&self) -> bool { - if let Some(stack_depth) = self.stack.last() { + if let Some(stack_depth) = self.stack.last_index() { // Either the current goal on the stack is the root of a cycle... if self.stack[stack_depth].has_been_used { return true; From 712bff2422ec6c88358e3b163f29e9f0a9b53fc1 Mon Sep 17 00:00:00 2001 From: Asger Hautop Drewsen Date: Wed, 29 Mar 2023 09:54:32 +0200 Subject: [PATCH 242/346] RELEASES: Add "Only support Android NDK 25 or newer" to 1.68.0 --- RELEASES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASES.md b/RELEASES.md index e453b8d6891..b923f87abfd 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -94,6 +94,7 @@ Misc Compatibility Notes ------------------- +- [Only support Android NDK 25 or newer](https://blog.rust-lang.org/2023/01/09/android-ndk-update-r25.html) - [Add `SEMICOLON_IN_EXPRESSIONS_FROM_MACROS` to future-incompat report](https://github.com/rust-lang/rust/pull/103418/) - [Only specify `--target` by default for `-Zgcc-ld=lld` on wasm](https://github.com/rust-lang/rust/pull/101792/) - [Bump `IMPLIED_BOUNDS_ENTAILMENT` to Deny + ReportNow](https://github.com/rust-lang/rust/pull/106465/) From f6bde0352b52eb3b31c78b7abd70c1be396ccb0f Mon Sep 17 00:00:00 2001 From: joboet Date: Wed, 29 Mar 2023 10:52:48 +0200 Subject: [PATCH 243/346] std: use `cvt` to handle errors from `read_entropy` on Hermit --- library/std/src/sys/hermit/mod.rs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/library/std/src/sys/hermit/mod.rs b/library/std/src/sys/hermit/mod.rs index d0e09890b8b..111150b06e1 100644 --- a/library/std/src/sys/hermit/mod.rs +++ b/library/std/src/sys/hermit/mod.rs @@ -80,15 +80,9 @@ pub fn hashmap_random_keys() -> (u64, u64) { let mut buf = [0; 16]; let mut slice = &mut buf[..]; while !slice.is_empty() { - let res = unsafe { abi::read_entropy(slice.as_mut_ptr(), slice.len(), 0) }; - if res < 0 { - panic!( - "random key generation failed: {}", - crate::io::Error::from_raw_os_error(-res as i32) - ); - } else { - slice = &mut slice[res as usize..]; - } + let res = cvt(unsafe { abi::read_entropy(slice.as_mut_ptr(), slice.len(), 0) }) + .expect("failed to generate random hashmap keys"); + slice = &mut slice[res as usize..]; } let key1 = buf[..8].try_into().unwrap(); From 37ed3cebbc24c9953ae0c2a17dd74ae1268b8650 Mon Sep 17 00:00:00 2001 From: jofas Date: Wed, 29 Mar 2023 11:14:23 +0200 Subject: [PATCH 244/346] enhanced documentation of binary search methods for slice and VecDeque for unsorted instances --- library/alloc/src/collections/vec_deque/mod.rs | 17 ++++++++++------- library/core/src/slice/mod.rs | 17 ++++++++++------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 451e4936bc5..1ae72b715cd 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -2378,7 +2378,8 @@ impl VecDeque { } /// Binary searches this `VecDeque` for a given element. - /// This behaves similarly to [`contains`] if this `VecDeque` is sorted. + /// If the `VecDeque` is not sorted, the returned result is unspecified and + /// meaningless. /// /// If the value is found then [`Result::Ok`] is returned, containing the /// index of the matching element. If there are multiple matches, then any @@ -2434,12 +2435,13 @@ impl VecDeque { } /// Binary searches this `VecDeque` with a comparator function. - /// This behaves similarly to [`contains`] if this `VecDeque` is sorted. /// - /// The comparator function should implement an order consistent - /// with the sort order of the deque, returning an order code that - /// indicates whether its argument is `Less`, `Equal` or `Greater` - /// than the desired target. + /// The comparator function should return an order code that indicates + /// whether its argument is `Less`, `Equal` or `Greater` the desired + /// target. + /// If the `VecDeque` is not sorted or if the comparator function does not + /// implement an order consistent with the sort order of the underlying + /// `VecDeque`, the returned result is unspecified and meaningless. /// /// If the value is found then [`Result::Ok`] is returned, containing the /// index of the matching element. If there are multiple matches, then any @@ -2489,10 +2491,11 @@ impl VecDeque { } /// Binary searches this `VecDeque` with a key extraction function. - /// This behaves similarly to [`contains`] if this `VecDeque` is sorted. /// /// Assumes that the deque is sorted by the key, for instance with /// [`make_contiguous().sort_by_key()`] using the same key extraction function. + /// If the deque is not sorted by the key, the returned result is + /// unspecified and meaningless. /// /// If the value is found then [`Result::Ok`] is returned, containing the /// index of the matching element. If there are multiple matches, then any diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index df7fe2bf76d..eb571824065 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -2343,7 +2343,8 @@ impl [T] { } /// Binary searches this slice for a given element. - /// This behaves similarly to [`contains`] if this slice is sorted. + /// If the slice is not sorted, the returned result is unspecified and + /// meaningless. /// /// If the value is found then [`Result::Ok`] is returned, containing the /// index of the matching element. If there are multiple matches, then any @@ -2418,12 +2419,13 @@ impl [T] { } /// Binary searches this slice with a comparator function. - /// This behaves similarly to [`contains`] if this slice is sorted. /// - /// The comparator function should implement an order consistent - /// with the sort order of the underlying slice, returning an - /// order code that indicates whether its argument is `Less`, - /// `Equal` or `Greater` the desired target. + /// The comparator function should return an order code that indicates + /// whether its argument is `Less`, `Equal` or `Greater` the desired + /// target. + /// If the slice is not sorted or if the comparator function does not + /// implement an order consistent with the sort order of the underlying + /// slice, the returned result is unspecified and meaningless. /// /// If the value is found then [`Result::Ok`] is returned, containing the /// index of the matching element. If there are multiple matches, then any @@ -2504,10 +2506,11 @@ impl [T] { } /// Binary searches this slice with a key extraction function. - /// This behaves similarly to [`contains`] if this slice is sorted. /// /// Assumes that the slice is sorted by the key, for instance with /// [`sort_by_key`] using the same key extraction function. + /// If the slice is not sorted by the key, the returned result is + /// unspecified and meaningless. /// /// If the value is found then [`Result::Ok`] is returned, containing the /// index of the matching element. If there are multiple matches, then any From 7b40eb71a90d93e825e32394d30f199a8492342d Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Wed, 29 Mar 2023 11:20:36 +0200 Subject: [PATCH 245/346] Update Emscripten on CI to 2.0.5 `getentropy()` is available since Emscripten 2.0.5. See: https://github.com/emscripten-core/emscripten/pull/12240 --- src/ci/docker/scripts/emscripten.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ci/docker/scripts/emscripten.sh b/src/ci/docker/scripts/emscripten.sh index 56dc96283ed..3f5e2c6ff1d 100644 --- a/src/ci/docker/scripts/emscripten.sh +++ b/src/ci/docker/scripts/emscripten.sh @@ -20,5 +20,5 @@ exit 1 git clone https://github.com/emscripten-core/emsdk.git /emsdk-portable cd /emsdk-portable -hide_output ./emsdk install 1.39.20 -./emsdk activate 1.39.20 +hide_output ./emsdk install 2.0.5 +./emsdk activate 2.0.5 From 3811275f0902517cef24e86890737f09d082cff2 Mon Sep 17 00:00:00 2001 From: Quinn Painter Date: Wed, 29 Mar 2023 12:51:11 +0100 Subject: [PATCH 246/346] Switch to LLD as default linker for {arm,thumb}v4t-none-eabi --- compiler/rustc_target/src/spec/armv4t_none_eabi.rs | 11 ++--------- compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs | 11 +---------- .../rustc/src/platform-support/armv4t-none-eabi.md | 7 ------- 3 files changed, 3 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_target/src/spec/armv4t_none_eabi.rs b/compiler/rustc_target/src/spec/armv4t_none_eabi.rs index 28b109889e9..d0f988b278f 100644 --- a/compiler/rustc_target/src/spec/armv4t_none_eabi.rs +++ b/compiler/rustc_target/src/spec/armv4t_none_eabi.rs @@ -4,13 +4,6 @@ //! //! Please ping @Lokathor if changes are needed. //! -//! This target profile assumes that you have the ARM binutils in your path -//! (specifically the linker, `arm-none-eabi-ld`). They can be obtained for free -//! for all major OSes from the ARM developer's website, and they may also be -//! available in your system's package manager. Unfortunately, the standard -//! linker that Rust uses (`lld`) only supports as far back as `ARMv5TE`, so we -//! must use the GNU `ld` linker. -//! //! **Important:** This target profile **does not** specify a linker script. You //! just get the default link script when you build a binary for this target. //! The default link script is very likely wrong, so you should use @@ -35,8 +28,8 @@ pub fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), options: TargetOptions { abi: "eabi".into(), - linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::No), - linker: Some("arm-none-eabi-ld".into()), + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), + linker: Some("rust-lld".into()), asm_args: cvs!["-mthumb-interwork", "-march=armv4t", "-mlittle-endian",], // Force-enable 32-bit atomics, which allows the use of atomic load/store only. // The resulting atomics are ABI incompatible with atomics backed by libatomic. diff --git a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs index e3734932f88..9c59bb9114e 100644 --- a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs +++ b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs @@ -4,19 +4,12 @@ //! //! Please ping @Lokathor if changes are needed. //! -//! This target profile assumes that you have the ARM binutils in your path -//! (specifically the linker, `arm-none-eabi-ld`). They can be obtained for free -//! for all major OSes from the ARM developer's website, and they may also be -//! available in your system's package manager. Unfortunately, the standard -//! linker that Rust uses (`lld`) only supports as far back as `ARMv5TE`, so we -//! must use the GNU `ld` linker. -//! //! **Important:** This target profile **does not** specify a linker script. You //! just get the default link script when you build a binary for this target. //! The default link script is very likely wrong, so you should use //! `-Clink-arg=-Tmy_script.ld` to override that with a correct linker script. -use crate::spec::{cvs, Cc, FramePointer, LinkerFlavor, Lld}; +use crate::spec::{cvs, FramePointer}; use crate::spec::{PanicStrategy, RelocModel, Target, TargetOptions}; pub fn target() -> Target { @@ -36,8 +29,6 @@ pub fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), options: TargetOptions { abi: "eabi".into(), - linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::No), - linker: Some("arm-none-eabi-ld".into()), // extra args passed to the external assembler (assuming `arm-none-eabi-as`): // * activate t32/a32 interworking diff --git a/src/doc/rustc/src/platform-support/armv4t-none-eabi.md b/src/doc/rustc/src/platform-support/armv4t-none-eabi.md index cf831e1595e..a230eba6bf9 100644 --- a/src/doc/rustc/src/platform-support/armv4t-none-eabi.md +++ b/src/doc/rustc/src/platform-support/armv4t-none-eabi.md @@ -17,13 +17,6 @@ specific with this target, so any ARMv4T device should work fine. The target is cross-compiled, and uses static linking. -The linker that comes with rustc cannot link for this platform (the platform is -too old). You will need the `arm-none-eabi-ld` linker from a GNU Binutils -targeting ARM. This can be obtained for Windows/Mac/Linux from the [ARM -Developer Website][arm-dev], or possibly from your OS's package manager. - -[arm-dev]: https://developer.arm.com/Tools%20and%20Software/GNU%20Toolchain - This target doesn't provide a linker script, you'll need to bring your own according to the specific device you want to target. Pass `-Clink-arg=-Tyour_script.ld` as a rustc argument to make the linker use From d499bbb99d72c991f1d1691f83ffe96bcfafc80a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Wed, 29 Mar 2023 14:50:10 +0200 Subject: [PATCH 247/346] Use #[cfg(target_thread_local)] on items --- tests/ui/thread-local/auxiliary/tls-export.rs | 3 ++- tests/ui/thread-local/auxiliary/tls-rlib.rs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/ui/thread-local/auxiliary/tls-export.rs b/tests/ui/thread-local/auxiliary/tls-export.rs index aab48f871c9..027213bc033 100644 --- a/tests/ui/thread-local/auxiliary/tls-export.rs +++ b/tests/ui/thread-local/auxiliary/tls-export.rs @@ -1,15 +1,16 @@ #![crate_type = "dylib"] #![feature(thread_local)] #![feature(cfg_target_thread_local)] -#![cfg(target_thread_local)] extern crate tls_rlib; pub use tls_rlib::*; +#[cfg(target_thread_local)] #[thread_local] pub static FOO: bool = true; +#[cfg(target_thread_local)] #[inline(never)] pub fn foo_addr() -> usize { &FOO as *const bool as usize diff --git a/tests/ui/thread-local/auxiliary/tls-rlib.rs b/tests/ui/thread-local/auxiliary/tls-rlib.rs index 0fbcf387b5f..20bc998ec11 100644 --- a/tests/ui/thread-local/auxiliary/tls-rlib.rs +++ b/tests/ui/thread-local/auxiliary/tls-rlib.rs @@ -3,11 +3,12 @@ #![crate_type = "rlib"] #![feature(thread_local)] #![feature(cfg_target_thread_local)] -#![cfg(target_thread_local)] +#[cfg(target_thread_local)] #[thread_local] pub static BAR: bool = true; +#[cfg(target_thread_local)] #[inline(never)] pub fn bar_addr() -> usize { &BAR as *const bool as usize From a9aaf3fedba1ddbfa4e60c47794bd78688297ec2 Mon Sep 17 00:00:00 2001 From: Stefan Lankes Date: Wed, 29 Mar 2023 15:29:36 +0200 Subject: [PATCH 248/346] Implement read_buf for RustHermit In principle, this PR extends rust-lang/rust#108326 for RustyHermit. Signed-off-by: Stefan Lankes --- library/std/src/sys/hermit/net.rs | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/library/std/src/sys/hermit/net.rs b/library/std/src/sys/hermit/net.rs index 5fb6281aa1e..d6f64a29719 100644 --- a/library/std/src/sys/hermit/net.rs +++ b/library/std/src/sys/hermit/net.rs @@ -1,7 +1,7 @@ #![allow(dead_code)] use crate::cmp; -use crate::io::{self, IoSlice, IoSliceMut}; +use crate::io::{self, BorrowedBuf, BorrowedCursor, IoSlice, IoSliceMut}; use crate::mem; use crate::net::{Shutdown, SocketAddr}; use crate::os::hermit::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, RawFd}; @@ -146,18 +146,35 @@ impl Socket { Ok(Socket(unsafe { FileDesc::from_raw_fd(fd) })) } - fn recv_with_flags(&self, buf: &mut [u8], flags: i32) -> io::Result { - let ret = - cvt(unsafe { netc::recv(self.0.as_raw_fd(), buf.as_mut_ptr(), buf.len(), flags) })?; - Ok(ret as usize) + fn recv_with_flags(&self, mut buf: BorrowedCursor<'_>, flags: i32) -> io::Result<()> { + let ret = cvt(unsafe { + netc::recv( + self.0.as_raw_fd(), + buf.as_mut().as_mut_ptr() as *mut u8, + buf.capacity(), + flags, + ) + })?; + unsafe { + buf.advance(ret as usize); + } + Ok(()) } pub fn read(&self, buf: &mut [u8]) -> io::Result { - self.recv_with_flags(buf, 0) + let mut buf = BorrowedBuf::from(buf); + self.recv_with_flags(buf.unfilled(), 0)?; + Ok(buf.len()) } pub fn peek(&self, buf: &mut [u8]) -> io::Result { - self.recv_with_flags(buf, netc::MSG_PEEK) + let mut buf = BorrowedBuf::from(buf); + self.recv_with_flags(buf.unfilled(), netc::MSG_PEEK)?; + Ok(buf.len()) + } + + pub fn read_buf(&self, buf: BorrowedCursor<'_>) -> io::Result<()> { + self.recv_with_flags(buf, 0) } pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { From f93ef09319d78b5878222b8cfe91f6efbe71ed1e Mon Sep 17 00:00:00 2001 From: Ben Kimock Date: Wed, 29 Mar 2023 09:54:01 -0400 Subject: [PATCH 249/346] Add ignore-debug to static-relocation-model test --- tests/assembly/static-relocation-model.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/assembly/static-relocation-model.rs b/tests/assembly/static-relocation-model.rs index faa2e395209..41aa9a46103 100644 --- a/tests/assembly/static-relocation-model.rs +++ b/tests/assembly/static-relocation-model.rs @@ -6,6 +6,7 @@ // [A64] needs-llvm-components: aarch64 // [ppc64le] compile-flags: --target powerpc64le-unknown-linux-gnu -Crelocation-model=static // [ppc64le] needs-llvm-components: powerpc +// ignore-debug: alignment checks insert panics that we don't have a lang item for #![feature(no_core, lang_items)] #![no_core] From 71ff7ef17c260e1b29b58cdf359b50799d9449da Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 29 Mar 2023 16:16:02 +0200 Subject: [PATCH 250/346] Don't strip crate module --- src/librustdoc/passes/strip_hidden.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs index 890b3e8d67f..a688aa14863 100644 --- a/src/librustdoc/passes/strip_hidden.rs +++ b/src/librustdoc/passes/strip_hidden.rs @@ -121,9 +121,14 @@ impl<'a, 'tcx> DocFolder for Stripper<'a, 'tcx> { // strip things like impl methods but when doing so // we must not add any items to the `retained` set. let old = mem::replace(&mut self.update_retained, false); - let ret = strip_item(self.set_is_in_hidden_item_and_fold(true, i)); + let ret = self.set_is_in_hidden_item_and_fold(true, i); self.update_retained = old; - Some(ret) + if ret.is_crate() { + // We don't strip the crate, even if it has `#[doc(hidden)]`. + Some(ret) + } else { + Some(strip_item(ret)) + } } _ => { let ret = self.set_is_in_hidden_item_and_fold(true, i); From cdc4fa45896c2b086646c8c9c91adb8d9dc5e45f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 29 Mar 2023 16:16:19 +0200 Subject: [PATCH 251/346] Add regression test for #109695 --- tests/rustdoc/issue-109695-crate-doc-hidden.rs | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 tests/rustdoc/issue-109695-crate-doc-hidden.rs diff --git a/tests/rustdoc/issue-109695-crate-doc-hidden.rs b/tests/rustdoc/issue-109695-crate-doc-hidden.rs new file mode 100644 index 00000000000..7a3e53a0d32 --- /dev/null +++ b/tests/rustdoc/issue-109695-crate-doc-hidden.rs @@ -0,0 +1,8 @@ +// This test ensures that even if the crate module is `#[doc(hidden)]`, the file +// is generated. + +// @has 'foo/index.html' +// @has 'foo/all.html' + +#![crate_name = "foo"] +#![doc(hidden)] From 76b0cf812b70b458cbae480af75d788a29a43adc Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 21 Mar 2023 18:06:04 +0000 Subject: [PATCH 252/346] Walk return-position impl trait in trait deeply in associated_item_def_ids --- compiler/rustc_ty_utils/src/assoc.rs | 35 ++++++++++--------- .../impl-trait/in-trait/auxiliary/rpitit.rs | 7 ++-- tests/ui/impl-trait/in-trait/foreign.rs | 16 +++++++-- 3 files changed, 36 insertions(+), 22 deletions(-) diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index bf0bc202852..de1e1a527d5 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -1,3 +1,4 @@ +use rustc_data_structures::fx::FxIndexSet; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId}; @@ -196,20 +197,26 @@ fn associated_types_for_impl_traits_in_associated_fn( match tcx.def_kind(parent_def_id) { DefKind::Trait => { - struct RPITVisitor { - rpits: Vec, + struct RPITVisitor<'tcx> { + rpits: FxIndexSet, + tcx: TyCtxt<'tcx>, } - impl<'v> Visitor<'v> for RPITVisitor { - fn visit_ty(&mut self, ty: &'v hir::Ty<'v>) { - if let hir::TyKind::OpaqueDef(item_id, _, _) = ty.kind { - self.rpits.push(item_id.owner_id.def_id) + impl<'tcx> Visitor<'tcx> for RPITVisitor<'tcx> { + fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) { + if let hir::TyKind::OpaqueDef(item_id, _, _) = ty.kind + && self.rpits.insert(item_id.owner_id.def_id) + { + let opaque_item = self.tcx.hir().expect_item(item_id.owner_id.def_id).expect_opaque_ty(); + for bound in opaque_item.bounds { + intravisit::walk_param_bound(self, bound); + } } intravisit::walk_ty(self, ty) } } - let mut visitor = RPITVisitor { rpits: Vec::new() }; + let mut visitor = RPITVisitor { tcx, rpits: FxIndexSet::default() }; if let Some(output) = tcx.hir().get_fn_output(fn_def_id) { visitor.visit_fn_ret_ty(output); @@ -227,13 +234,9 @@ fn associated_types_for_impl_traits_in_associated_fn( tcx.arena.alloc_from_iter( tcx.associated_types_for_impl_traits_in_associated_fn(trait_fn_def_id).iter().map( - move |trait_assoc_def_id| { - associated_type_for_impl_trait_in_impl( - tcx, - trait_assoc_def_id.expect_local(), - fn_def_id, - ) - .to_def_id() + move |&trait_assoc_def_id| { + associated_type_for_impl_trait_in_impl(tcx, trait_assoc_def_id, fn_def_id) + .to_def_id() }, ), ) @@ -355,7 +358,7 @@ fn associated_type_for_impl_trait_in_trait( /// that inherits properties that we infer from the method and the associated type. fn associated_type_for_impl_trait_in_impl( tcx: TyCtxt<'_>, - trait_assoc_def_id: LocalDefId, + trait_assoc_def_id: DefId, impl_fn_def_id: LocalDefId, ) -> LocalDefId { let impl_local_def_id = tcx.local_parent(impl_fn_def_id); @@ -380,7 +383,7 @@ fn associated_type_for_impl_trait_in_impl( name: kw::Empty, kind: ty::AssocKind::Type, def_id, - trait_item_def_id: Some(trait_assoc_def_id.to_def_id()), + trait_item_def_id: Some(trait_assoc_def_id), container: ty::ImplContainer, fn_has_self_parameter: false, opt_rpitit_info: Some(ImplTraitInTraitData::Impl { fn_def_id: impl_fn_def_id.to_def_id() }), diff --git a/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs b/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs index 74f7bc603aa..ffeabe5c2ed 100644 --- a/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs +++ b/tests/ui/impl-trait/in-trait/auxiliary/rpitit.rs @@ -2,12 +2,13 @@ #![feature(return_position_impl_trait_in_trait)] +use std::ops::Deref; + pub trait Foo { - fn bar() -> impl Sized; + fn bar() -> impl Deref; } pub struct Foreign; - impl Foo for Foreign { - fn bar() {} + fn bar() -> &'static () { &() } } diff --git a/tests/ui/impl-trait/in-trait/foreign.rs b/tests/ui/impl-trait/in-trait/foreign.rs index df77372aabd..f4972d948b2 100644 --- a/tests/ui/impl-trait/in-trait/foreign.rs +++ b/tests/ui/impl-trait/in-trait/foreign.rs @@ -5,7 +5,17 @@ extern crate rpitit; -fn main() { - // Witness an RPITIT from another crate - let () = ::bar(); +use std::sync::Arc; + +// Implement an RPITIT from another crate. +struct Local; +impl rpitit::Foo for Local { + fn bar() -> Arc { Arc::new(String::new()) } +} + +fn main() { + // Witness an RPITIT from another crate. + let &() = ::bar(); + + let x: Arc = ::bar(); } From 66714658d0bb9cd5b3c10a876275f9646da2148f Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 27 Mar 2023 18:33:04 -0300 Subject: [PATCH 253/346] Properly skip RPITITs from ModChild and give a name in AssocItem --- compiler/rustc_hir/src/definitions.rs | 6 +----- compiler/rustc_metadata/src/rmeta/decoder.rs | 11 ++++++++--- .../ui/impl-trait/in-trait/doesnt-satisfy.next.stderr | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index 3c4fc9cb530..8ceb176491b 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -404,12 +404,8 @@ impl DefPathData { match *self { TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) => Some(name), - // We use this name when collecting `ModChild`s. - // FIXME this could probably be removed with some refactoring to the name resolver. - ImplTraitAssocTy => Some(kw::Empty), - Impl | ForeignMod | CrateRoot | Use | GlobalAsm | ClosureExpr | Ctor | AnonConst - | ImplTrait => None, + | ImplTrait | ImplTraitAssocTy => None, } } diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 06a64f0db0e..43e5946f313 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1021,7 +1021,9 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { } else { // Iterate over all children. for child_index in self.root.tables.children.get(self, id).unwrap().decode(self) { - yield self.get_mod_child(child_index, sess); + if self.root.tables.opt_rpitit_info.get(self, child_index).is_none() { + yield self.get_mod_child(child_index, sess); + } } if let Some(reexports) = self.root.tables.module_reexports.get(self, id) { @@ -1067,8 +1069,11 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { } fn get_associated_item(self, id: DefIndex, sess: &'a Session) -> ty::AssocItem { - let name = self.item_name(id); - + let name = if self.root.tables.opt_rpitit_info.get(self, id).is_some() { + kw::Empty + } else { + self.item_name(id) + }; let (kind, has_self) = match self.def_kind(id) { DefKind::AssocConst => (ty::AssocKind::Const, false), DefKind::AssocFn => (ty::AssocKind::Fn, self.get_fn_has_self_parameter(id, sess)), diff --git a/tests/ui/impl-trait/in-trait/doesnt-satisfy.next.stderr b/tests/ui/impl-trait/in-trait/doesnt-satisfy.next.stderr index bbfa089ceef..f0cd43bcf92 100644 --- a/tests/ui/impl-trait/in-trait/doesnt-satisfy.next.stderr +++ b/tests/ui/impl-trait/in-trait/doesnt-satisfy.next.stderr @@ -10,7 +10,7 @@ note: required by a bound in `Foo::{opaque#0}` --> $DIR/doesnt-satisfy.rs:8:22 | LL | fn bar() -> impl std::fmt::Display; - | ^^^^^^^^^^^^^^^^^ required by this bound in `Foo::` + | ^^^^^^^^^^^^^^^^^ required by this bound in `Foo::{opaque#0}` error: aborting due to previous error From 2ca350c776414fb09ca97311b5e0fee929c90902 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 21 Mar 2023 16:52:15 -0300 Subject: [PATCH 254/346] Bless some extra working tests under -Zlower-impl-trait-in-trait-to-assoc-ty --- tests/ui/impl-trait/in-trait/nested-rpitit.rs | 2 ++ ...052-2.stderr => issue-103052-2.current.stderr} | 4 ++-- .../issue-103052-2.next.stderr | 15 +++++++++++++++ .../rfc-1937-termination-trait/issue-103052-2.rs | 6 +++++- 4 files changed, 24 insertions(+), 3 deletions(-) rename tests/ui/rfc-1937-termination-trait/{issue-103052-2.stderr => issue-103052-2.current.stderr} (88%) create mode 100644 tests/ui/rfc-1937-termination-trait/issue-103052-2.next.stderr diff --git a/tests/ui/impl-trait/in-trait/nested-rpitit.rs b/tests/ui/impl-trait/in-trait/nested-rpitit.rs index 65285e3a3cc..36020753726 100644 --- a/tests/ui/impl-trait/in-trait/nested-rpitit.rs +++ b/tests/ui/impl-trait/in-trait/nested-rpitit.rs @@ -1,4 +1,6 @@ // check-pass +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next #![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] diff --git a/tests/ui/rfc-1937-termination-trait/issue-103052-2.stderr b/tests/ui/rfc-1937-termination-trait/issue-103052-2.current.stderr similarity index 88% rename from tests/ui/rfc-1937-termination-trait/issue-103052-2.stderr rename to tests/ui/rfc-1937-termination-trait/issue-103052-2.current.stderr index a700c72ea68..f72b3ab0234 100644 --- a/tests/ui/rfc-1937-termination-trait/issue-103052-2.stderr +++ b/tests/ui/rfc-1937-termination-trait/issue-103052-2.current.stderr @@ -1,11 +1,11 @@ error[E0277]: the trait bound `Something: Termination` is not satisfied - --> $DIR/issue-103052-2.rs:12:22 + --> $DIR/issue-103052-2.rs:15:22 | LL | fn main() -> Something { | ^^^^^^^^^ the trait `Termination` is not implemented for `Something` | note: required by a bound in `Main::main::{opaque#0}` - --> $DIR/issue-103052-2.rs:6:27 + --> $DIR/issue-103052-2.rs:9:27 | LL | fn main() -> impl std::process::Termination; | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Main::main::{opaque#0}` diff --git a/tests/ui/rfc-1937-termination-trait/issue-103052-2.next.stderr b/tests/ui/rfc-1937-termination-trait/issue-103052-2.next.stderr new file mode 100644 index 00000000000..8b01941b4c6 --- /dev/null +++ b/tests/ui/rfc-1937-termination-trait/issue-103052-2.next.stderr @@ -0,0 +1,15 @@ +error[E0277]: the trait bound `Something: Termination` is not satisfied + --> $DIR/issue-103052-2.rs:15:22 + | +LL | fn main() -> Something { + | ^^^^^^^^^ the trait `Termination` is not implemented for `Something` + | +note: required by a bound in `Main::{opaque#0}` + --> $DIR/issue-103052-2.rs:9:27 + | +LL | fn main() -> impl std::process::Termination; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Main::{opaque#0}` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/rfc-1937-termination-trait/issue-103052-2.rs b/tests/ui/rfc-1937-termination-trait/issue-103052-2.rs index fa9182b6dee..ca5fa6df2a6 100644 --- a/tests/ui/rfc-1937-termination-trait/issue-103052-2.rs +++ b/tests/ui/rfc-1937-termination-trait/issue-103052-2.rs @@ -1,3 +1,6 @@ +// [next] compile-flags: -Zlower-impl-trait-in-trait-to-assoc-ty +// revisions: current next + #![feature(return_position_impl_trait_in_trait)] #![allow(incomplete_features)] @@ -9,7 +12,8 @@ mod child { struct Something; impl Main for () { - fn main() -> Something { //~ ERROR the trait bound `Something: Termination` is not satisfied + fn main() -> Something { + //~^ ERROR the trait bound `Something: Termination` is not satisfied Something } } From cda130fd0319bf1e1bd88825e87763e3186970ff Mon Sep 17 00:00:00 2001 From: Felix S Klock II Date: Wed, 29 Mar 2023 11:29:05 -0400 Subject: [PATCH 255/346] Delete Makefile removing regression test --- tests/run-make/wasm-override-linker/Makefile | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 tests/run-make/wasm-override-linker/Makefile diff --git a/tests/run-make/wasm-override-linker/Makefile b/tests/run-make/wasm-override-linker/Makefile deleted file mode 100644 index d6163b1e04f..00000000000 --- a/tests/run-make/wasm-override-linker/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -include ../../run-make-fulldeps/tools.mk - -ifeq ($(TARGET),wasm32-unknown-unknown) -all: - $(RUSTC) foo.rs --crate-type cdylib --target $(TARGET) -C linker=clang -else ifeq ($(TARGET),wasm64-unknown-unknown) -all: - $(RUSTC) foo.rs --crate-type cdylib --target $(TARGET) -C linker=clang -else -all: -endif From 167623a36ae0b09381d4297886c29dc869c350f6 Mon Sep 17 00:00:00 2001 From: Felix S Klock II Date: Wed, 29 Mar 2023 11:29:21 -0400 Subject: [PATCH 256/346] Delete foo.rs removing regression test --- tests/run-make/wasm-override-linker/foo.rs | 1 - 1 file changed, 1 deletion(-) delete mode 100644 tests/run-make/wasm-override-linker/foo.rs diff --git a/tests/run-make/wasm-override-linker/foo.rs b/tests/run-make/wasm-override-linker/foo.rs deleted file mode 100644 index 4bd8276f349..00000000000 --- a/tests/run-make/wasm-override-linker/foo.rs +++ /dev/null @@ -1 +0,0 @@ -// empty file From d62238d6a8ed57fecddfa9b97fd79cb0ac814791 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 27 Mar 2023 19:41:15 +0000 Subject: [PATCH 257/346] Do not consider elaborated projection predicates for objects in new solver --- .../src/solve/assembly.rs | 19 ++++++++++++++++--- .../dont-elaborate-for-projections.rs | 12 ++++++++++++ .../ui/traits/new-solver/more-object-bound.rs | 2 +- .../new-solver/more-object-bound.stderr | 13 ++++++++----- 4 files changed, 37 insertions(+), 9 deletions(-) create mode 100644 tests/ui/traits/new-solver/dont-elaborate-for-projections.rs diff --git a/compiler/rustc_trait_selection/src/solve/assembly.rs b/compiler/rustc_trait_selection/src/solve/assembly.rs index 0f7a0eb337b..856b1c08b72 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly.rs @@ -6,6 +6,7 @@ use super::trait_goals::structural_traits::*; use super::{EvalCtxt, SolverMode}; use crate::traits::coherence; use itertools::Itertools; +use rustc_data_structures::fx::FxIndexSet; use rustc_hir::def_id::DefId; use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::util::elaborate_predicates; @@ -489,9 +490,21 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { }; let tcx = self.tcx(); - for assumption in - elaborate_predicates(tcx, bounds.iter().map(|bound| bound.with_self_ty(tcx, self_ty))) - { + let own_bounds: FxIndexSet<_> = + bounds.iter().map(|bound| bound.with_self_ty(tcx, self_ty)).collect(); + for assumption in elaborate_predicates(tcx, own_bounds.iter().copied()) { + // FIXME: Predicates are fully elaborated in the object type's existential bounds + // list. We want to only consider these pre-elaborated projections, and not other + // projection predicates that we reach by elaborating the principal trait ref, + // since that'll cause ambiguity. + // + // We can remove this when we have implemented intersections in responses. + if assumption.to_opt_poly_projection_pred().is_some() + && !own_bounds.contains(&assumption) + { + continue; + } + match G::consider_object_bound_candidate(self, goal, assumption) { Ok(result) => { candidates.push(Candidate { source: CandidateSource::BuiltinImpl, result }) diff --git a/tests/ui/traits/new-solver/dont-elaborate-for-projections.rs b/tests/ui/traits/new-solver/dont-elaborate-for-projections.rs new file mode 100644 index 00000000000..e608250063c --- /dev/null +++ b/tests/ui/traits/new-solver/dont-elaborate-for-projections.rs @@ -0,0 +1,12 @@ +// compile-flags: -Ztrait-solver=next +// check-pass + +trait Iter<'a, I: 'a>: Iterator {} + +fn needs_iter<'a, T: Iter<'a, I> + ?Sized, I: 'a>(_: &T) {} + +fn test(x: &dyn Iter<'_, ()>) { + needs_iter(x); +} + +fn main() {} diff --git a/tests/ui/traits/new-solver/more-object-bound.rs b/tests/ui/traits/new-solver/more-object-bound.rs index 712759ef0e6..bb730b18ef7 100644 --- a/tests/ui/traits/new-solver/more-object-bound.rs +++ b/tests/ui/traits/new-solver/more-object-bound.rs @@ -10,7 +10,7 @@ trait Trait: SuperTrait::B> {} fn transmute(x: A) -> B { foo::>(x) - //~^ ERROR type annotations needed: cannot satisfy `dyn Trait: Trait` + //~^ ERROR the trait bound `dyn Trait: Trait` is not satisfied } fn foo(x: T::A) -> B diff --git a/tests/ui/traits/new-solver/more-object-bound.stderr b/tests/ui/traits/new-solver/more-object-bound.stderr index 208fdecb08f..4554b8c7473 100644 --- a/tests/ui/traits/new-solver/more-object-bound.stderr +++ b/tests/ui/traits/new-solver/more-object-bound.stderr @@ -1,10 +1,9 @@ -error[E0283]: type annotations needed: cannot satisfy `dyn Trait: Trait` - --> $DIR/more-object-bound.rs:12:5 +error[E0277]: the trait bound `dyn Trait: Trait` is not satisfied + --> $DIR/more-object-bound.rs:12:17 | LL | foo::>(x) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `dyn Trait` | - = note: cannot satisfy `dyn Trait: Trait` note: required by a bound in `foo` --> $DIR/more-object-bound.rs:18:8 | @@ -13,7 +12,11 @@ LL | fn foo(x: T::A) -> B LL | where LL | T: Trait, | ^^^^^^^^^^^^ required by this bound in `foo` +help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement + | +LL | fn transmute(x: A) -> B where dyn Trait: Trait { + | ++++++++++++++++++++++++++++++++++++ error: aborting due to previous error -For more information about this error, try `rustc --explain E0283`. +For more information about this error, try `rustc --explain E0277`. From a61616a016aadb41cb18cc898f1ce9ff70709607 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 24 Mar 2023 17:27:06 +0000 Subject: [PATCH 258/346] Move canonicalization code around --- .../src/solve/{canonical => }/canonicalize.rs | 0 .../src/solve/eval_ctxt.rs | 61 ++----------------- .../mod.rs => eval_ctxt/canonical.rs} | 53 +++++++++++----- .../rustc_trait_selection/src/solve/mod.rs | 5 +- 4 files changed, 47 insertions(+), 72 deletions(-) rename compiler/rustc_trait_selection/src/solve/{canonical => }/canonicalize.rs (100%) rename compiler/rustc_trait_selection/src/solve/{canonical/mod.rs => eval_ctxt/canonical.rs} (81%) diff --git a/compiler/rustc_trait_selection/src/solve/canonical/canonicalize.rs b/compiler/rustc_trait_selection/src/solve/canonicalize.rs similarity index 100% rename from compiler/rustc_trait_selection/src/solve/canonical/canonicalize.rs rename to compiler/rustc_trait_selection/src/solve/canonicalize.rs diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs index 92aff517fbb..e64b4a7656f 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs @@ -1,7 +1,6 @@ use rustc_hir::def_id::DefId; use rustc_infer::infer::at::ToTrace; -use rustc_infer::infer::canonical::query_response::make_query_region_constraints; -use rustc_infer::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarValues}; +use rustc_infer::infer::canonical::CanonicalVarValues; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::{ DefineOpaqueTypes, InferCtxt, InferOk, LateBoundRegionConversionTime, TyCtxtInferExt, @@ -9,9 +8,7 @@ use rustc_infer::infer::{ use rustc_infer::traits::query::NoSolution; use rustc_infer::traits::ObligationCause; use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; -use rustc_middle::traits::solve::{ - CanonicalGoal, Certainty, ExternalConstraints, ExternalConstraintsData, MaybeCause, QueryResult, -}; +use rustc_middle::traits::solve::{CanonicalGoal, Certainty, MaybeCause, QueryResult}; use rustc_middle::ty::{ self, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, @@ -21,11 +18,12 @@ use std::ops::ControlFlow; use crate::traits::specialization_graph; -use super::canonical::{CanonicalizeMode, Canonicalizer}; use super::search_graph::{self, OverflowHandler}; use super::SolverMode; use super::{search_graph::SearchGraph, Goal}; +mod canonical; + pub struct EvalCtxt<'a, 'tcx> { /// The inference context that backs (mostly) inference and placeholder terms /// instantiated while solving goals. @@ -414,7 +412,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { if let &ty::Infer(ty::TyVar(vid)) = ty.kind() { match self.infcx.probe_ty_var(vid) { Ok(value) => bug!("resolved var in query: {goal:?} {value:?}"), - Err(universe) => universe == self.universe(), + Err(universe) => universe == self.infcx.universe(), } } else { false @@ -424,7 +422,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { if let ty::ConstKind::Infer(ty::InferConst::Var(vid)) = ct.kind() { match self.infcx.probe_const_var(vid) { Ok(value) => bug!("resolved var in query: {goal:?} {value:?}"), - Err(universe) => universe == self.universe(), + Err(universe) => universe == self.infcx.universe(), } } else { false @@ -566,22 +564,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { self.infcx.fresh_substs_for_item(DUMMY_SP, def_id) } - pub(super) fn universe(&self) -> ty::UniverseIndex { - self.infcx.universe() - } - - pub(super) fn create_next_universe(&self) -> ty::UniverseIndex { - self.infcx.create_next_universe() - } - - pub(super) fn instantiate_canonical_var( - &self, - cv_info: CanonicalVarInfo<'tcx>, - universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex, - ) -> ty::GenericArg<'tcx> { - self.infcx.instantiate_canonical_var(DUMMY_SP, cv_info, universe_map) - } - pub(super) fn translate_substs( &self, param_env: ty::ParamEnv<'tcx>, @@ -621,35 +603,4 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { crate::traits::wf::unnormalized_obligations(self.infcx, param_env, arg) .map(|obligations| obligations.into_iter().map(|obligation| obligation.into())) } - - #[instrument(level = "debug", skip(self), ret)] - pub(super) fn compute_external_query_constraints( - &self, - ) -> Result, NoSolution> { - // Cannot use `take_registered_region_obligations` as we may compute the response - // inside of a `probe` whenever we have multiple choices inside of the solver. - let region_obligations = self.infcx.inner.borrow().region_obligations().to_owned(); - let region_constraints = self.infcx.with_region_constraints(|region_constraints| { - make_query_region_constraints( - self.tcx(), - region_obligations - .iter() - .map(|r_o| (r_o.sup_type, r_o.sub_region, r_o.origin.to_constraint_category())), - region_constraints, - ) - }); - let opaque_types = self.infcx.clone_opaque_types_for_query_response(); - Ok(self - .tcx() - .mk_external_constraints(ExternalConstraintsData { region_constraints, opaque_types })) - } - - pub(super) fn canonicalize>>( - &self, - canonicalize_mode: CanonicalizeMode, - variables: &mut Vec>, - value: T, - ) -> Canonical<'tcx, T> { - Canonicalizer::canonicalize(self.infcx, canonicalize_mode, variables, value) - } } diff --git a/compiler/rustc_trait_selection/src/solve/canonical/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs similarity index 81% rename from compiler/rustc_trait_selection/src/solve/canonical/mod.rs rename to compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs index d393ab1ba4a..ee90488730a 100644 --- a/compiler/rustc_trait_selection/src/solve/canonical/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs @@ -8,20 +8,19 @@ /// section of the [rustc-dev-guide][c]. /// /// [c]: https://rustc-dev-guide.rust-lang.org/solve/canonicalization.html -pub use self::canonicalize::{CanonicalizeMode, Canonicalizer}; - use super::{CanonicalGoal, Certainty, EvalCtxt, Goal}; -use super::{CanonicalResponse, QueryResult, Response}; +use crate::solve::canonicalize::{CanonicalizeMode, Canonicalizer}; +use crate::solve::{CanonicalResponse, QueryResult, Response}; +use rustc_infer::infer::canonical::query_response::make_query_region_constraints; use rustc_infer::infer::canonical::CanonicalVarValues; use rustc_infer::infer::canonical::{CanonicalExt, QueryRegionConstraints}; -use rustc_infer::traits::query::NoSolution; -use rustc_infer::traits::solve::ExternalConstraintsData; +use rustc_middle::traits::query::NoSolution; +use rustc_middle::traits::solve::{ExternalConstraints, ExternalConstraintsData}; use rustc_middle::ty::{self, GenericArgKind}; +use rustc_span::DUMMY_SP; use std::iter; use std::ops::Deref; -mod canonicalize; - impl<'tcx> EvalCtxt<'_, 'tcx> { /// Canonicalizes the goal remembering the original values /// for each bound variable. @@ -30,7 +29,12 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { goal: Goal<'tcx, ty::Predicate<'tcx>>, ) -> (Vec>, CanonicalGoal<'tcx>) { let mut orig_values = Default::default(); - let canonical_goal = self.canonicalize(CanonicalizeMode::Input, &mut orig_values, goal); + let canonical_goal = Canonicalizer::canonicalize( + self.infcx, + CanonicalizeMode::Input, + &mut orig_values, + goal, + ); (orig_values, canonical_goal) } @@ -41,7 +45,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { /// - `external_constraints`: additional constraints which aren't expressable /// using simple unification of inference variables. #[instrument(level = "debug", skip(self))] - pub(super) fn evaluate_added_goals_and_make_canonical_response( + pub(in crate::solve) fn evaluate_added_goals_and_make_canonical_response( &mut self, certainty: Certainty, ) -> QueryResult<'tcx> { @@ -51,7 +55,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { let external_constraints = self.compute_external_query_constraints()?; let response = Response { var_values: self.var_values, external_constraints, certainty }; - let canonical = self.canonicalize( + let canonical = Canonicalizer::canonicalize( + self.infcx, CanonicalizeMode::Response { max_input_universe: self.max_input_universe }, &mut Default::default(), response, @@ -59,6 +64,26 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { Ok(canonical) } + #[instrument(level = "debug", skip(self), ret)] + fn compute_external_query_constraints(&self) -> Result, NoSolution> { + // Cannot use `take_registered_region_obligations` as we may compute the response + // inside of a `probe` whenever we have multiple choices inside of the solver. + let region_obligations = self.infcx.inner.borrow().region_obligations().to_owned(); + let region_constraints = self.infcx.with_region_constraints(|region_constraints| { + make_query_region_constraints( + self.tcx(), + region_obligations + .iter() + .map(|r_o| (r_o.sup_type, r_o.sub_region, r_o.origin.to_constraint_category())), + region_constraints, + ) + }); + let opaque_types = self.infcx.clone_opaque_types_for_query_response(); + Ok(self + .tcx() + .mk_external_constraints(ExternalConstraintsData { region_constraints, opaque_types })) + } + /// After calling a canonical query, we apply the constraints returned /// by the query using this function. /// @@ -98,10 +123,10 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { // FIXME: Longterm canonical queries should deal with all placeholders // created inside of the query directly instead of returning them to the // caller. - let prev_universe = self.universe(); + let prev_universe = self.infcx.universe(); let universes_created_in_query = response.max_universe.index() + 1; for _ in 0..universes_created_in_query { - self.create_next_universe(); + self.infcx.create_next_universe(); } let var_values = response.value.var_values; @@ -144,7 +169,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { // A variable from inside a binder of the query. While ideally these shouldn't // exist at all (see the FIXME at the start of this method), we have to deal with // them for now. - self.instantiate_canonical_var(info, |idx| { + self.infcx.instantiate_canonical_var(DUMMY_SP, info, |idx| { ty::UniverseIndex::from(prev_universe.index() + idx.index()) }) } else if info.is_existential() { @@ -158,7 +183,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { if let Some(v) = opt_values[index] { v } else { - self.instantiate_canonical_var(info, |_| prev_universe) + self.infcx.instantiate_canonical_var(DUMMY_SP, info, |_| prev_universe) } } else { // For placeholders which were already part of the input, we simply map this diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs index 7c01d5d2bef..1925043e5fd 100644 --- a/compiler/rustc_trait_selection/src/solve/mod.rs +++ b/compiler/rustc_trait_selection/src/solve/mod.rs @@ -15,8 +15,7 @@ use rustc_hir::def_id::DefId; use rustc_infer::infer::canonical::{Canonical, CanonicalVarValues}; use rustc_infer::traits::query::NoSolution; use rustc_middle::traits::solve::{ - CanonicalGoal, CanonicalResponse, Certainty, ExternalConstraintsData, Goal, QueryResult, - Response, + CanonicalResponse, Certainty, ExternalConstraintsData, Goal, QueryResult, Response, }; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{ @@ -24,7 +23,7 @@ use rustc_middle::ty::{ }; mod assembly; -mod canonical; +mod canonicalize; mod eval_ctxt; mod fulfill; mod project_goals; From 0542b0d04d1af7990d1268046b32a9cf0259728d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 27 Mar 2023 21:16:46 +0000 Subject: [PATCH 259/346] Freshen normalizes-to hack goal RHS in the evaluate loop --- .../src/solve/eval_ctxt.rs | 102 ++++++++++++------ .../src/solve/project_goals.rs | 11 +- 2 files changed, 70 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs index e47b5ae21b5..e8642722476 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs @@ -48,7 +48,20 @@ pub(super) enum IsNormalizesToHack { #[derive(Debug, Clone)] pub(super) struct NestedGoals<'tcx> { + /// This normalizes-to goal that is treated specially during the evaluation + /// loop. In each iteration we take the RHS of the projection, replace it with + /// a fresh inference variable, and only after evaluating that goal do we + /// equate the fresh inference variable with the actual RHS of the predicate. + /// + /// This is both to improve caching, and to avoid using the RHS of the + /// projection predicate to influence the normalizes-to candidate we select. + /// + /// This is not a 'real' nested goal. We must not forget to replace the RHS + /// with a fresh inference variable when we evaluate this goal. That can result + /// in a trait solver cycle. This would currently result in overflow but can be + /// can be unsound with more powerful coinduction in the future. pub(super) normalizes_to_hack_goal: Option>>, + /// The rest of the goals which have not yet processed or remain ambiguous. pub(super) goals: Vec>>, } @@ -163,6 +176,10 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { canonical_response, )?; + if !has_changed && !nested_goals.is_empty() { + bug!("an unchanged goal shouldn't have any side-effects on instantiation"); + } + // Check that rerunning this query with its inference constraints applied // doesn't result in new inference constraints and has the same result. // @@ -180,9 +197,17 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { let canonical_response = EvalCtxt::evaluate_canonical_goal(self.tcx(), self.search_graph, canonical_goal)?; if !canonical_response.value.var_values.is_identity() { - bug!("unstable result: {goal:?} {canonical_goal:?} {canonical_response:?}"); + bug!( + "unstable result: re-canonicalized goal={canonical_goal:#?} \ + response={canonical_response:#?}" + ); + } + if certainty != canonical_response.value.certainty { + bug!( + "unstable certainty: {certainty:#?} re-canonicalized goal={canonical_goal:#?} \ + response={canonical_response:#?}" + ); } - assert_eq!(certainty, canonical_response.value.certainty); } Ok((has_changed, certainty, nested_goals)) @@ -262,15 +287,44 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { let mut has_changed = Err(Certainty::Yes); if let Some(goal) = goals.normalizes_to_hack_goal.take() { - let (_, certainty, nested_goals) = match this.evaluate_goal( - IsNormalizesToHack::Yes, - goal.with(this.tcx(), ty::Binder::dummy(goal.predicate)), + // Replace the goal with an unconstrained infer var, so the + // RHS does not affect projection candidate assembly. + let unconstrained_rhs = this.next_term_infer_of_kind(goal.predicate.term); + let unconstrained_goal = goal.with( + this.tcx(), + ty::Binder::dummy(ty::ProjectionPredicate { + projection_ty: goal.predicate.projection_ty, + term: unconstrained_rhs, + }), + ); + + let (_, certainty, instantiate_goals) = + match this.evaluate_goal(IsNormalizesToHack::Yes, unconstrained_goal) { + Ok(r) => r, + Err(NoSolution) => return Some(Err(NoSolution)), + }; + new_goals.goals.extend(instantiate_goals); + + // Finally, equate the goal's RHS with the unconstrained var. + // We put the nested goals from this into goals instead of + // next_goals to avoid needing to process the loop one extra + // time if this goal returns something -- I don't think this + // matters in practice, though. + match this.eq_and_get_goals( + goal.param_env, + goal.predicate.term, + unconstrained_rhs, ) { - Ok(r) => r, + Ok(eq_goals) => { + goals.goals.extend(eq_goals); + } Err(NoSolution) => return Some(Err(NoSolution)), }; - new_goals.goals.extend(nested_goals); + // We only look at the `projection_ty` part here rather than + // looking at the "has changed" return from evaluate_goal, + // because we expect the `unconstrained_rhs` part of the predicate + // to have changed -- that means we actually normalized successfully! if goal.predicate.projection_ty != this.resolve_vars_if_possible(goal.predicate.projection_ty) { @@ -280,40 +334,22 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { match certainty { Certainty::Yes => {} Certainty::Maybe(_) => { - let goal = this.resolve_vars_if_possible(goal); - - // The rhs of this `normalizes-to` must always be an unconstrained infer var as it is - // the hack used by `normalizes-to` to ensure that every `normalizes-to` behaves the same - // regardless of the rhs. - // - // However it is important not to unconditionally replace the rhs with a new infer var - // as otherwise we may replace the original unconstrained infer var with a new infer var - // and never propagate any constraints on the new var back to the original var. - let term = this - .term_is_fully_unconstrained(goal) - .then_some(goal.predicate.term) - .unwrap_or_else(|| { - this.next_term_infer_of_kind(goal.predicate.term) - }); - let projection_pred = ty::ProjectionPredicate { - term, - projection_ty: goal.predicate.projection_ty, - }; + // We need to resolve vars here so that we correctly + // deal with `has_changed` in the next iteration. new_goals.normalizes_to_hack_goal = - Some(goal.with(this.tcx(), projection_pred)); - + Some(this.resolve_vars_if_possible(goal)); has_changed = has_changed.map_err(|c| c.unify_and(certainty)); } } } - for nested_goal in goals.goals.drain(..) { - let (changed, certainty, nested_goals) = - match this.evaluate_goal(IsNormalizesToHack::No, nested_goal) { + for goal in goals.goals.drain(..) { + let (changed, certainty, instantiate_goals) = + match this.evaluate_goal(IsNormalizesToHack::No, goal) { Ok(result) => result, Err(NoSolution) => return Some(Err(NoSolution)), }; - new_goals.goals.extend(nested_goals); + new_goals.goals.extend(instantiate_goals); if changed { has_changed = Ok(()); @@ -322,7 +358,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { match certainty { Certainty::Yes => {} Certainty::Maybe(_) => { - new_goals.goals.push(nested_goal); + new_goals.goals.push(goal); has_changed = has_changed.map_err(|c| c.unify_and(certainty)); } } diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index 91b56fe3522..32f0db742ad 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -35,16 +35,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { let candidates = self.assemble_and_evaluate_candidates(goal); self.merge_candidates(candidates) } else { - let predicate = goal.predicate; - let unconstrained_rhs = self.next_term_infer_of_kind(predicate.term); - let unconstrained_predicate = ProjectionPredicate { - projection_ty: goal.predicate.projection_ty, - term: unconstrained_rhs, - }; - - self.set_normalizes_to_hack_goal(goal.with(self.tcx(), unconstrained_predicate)); - self.try_evaluate_added_goals()?; - self.eq(goal.param_env, unconstrained_rhs, predicate.term)?; + self.set_normalizes_to_hack_goal(goal); self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) } } From 979c265a5d54a3a267563153859f2921db717b1d Mon Sep 17 00:00:00 2001 From: clubby789 Date: Wed, 29 Mar 2023 16:00:48 +0100 Subject: [PATCH 260/346] Check for escape sequences in Fluent resources --- compiler/rustc_codegen_llvm/messages.ftl | 3 ++- compiler/rustc_const_eval/messages.ftl | 16 +++++++++--- compiler/rustc_incremental/messages.ftl | 2 +- compiler/rustc_lint/messages.ftl | 2 +- .../rustc_macros/src/diagnostics/fluent.rs | 12 +++++++++ .../fluent-messages/invalid-escape.ftl | 1 + tests/ui-fulldeps/fluent-messages/test.rs | 9 +++++++ tests/ui-fulldeps/fluent-messages/test.stderr | 26 ++++++++++++++++++- .../existing_doc_keyword.stderr | 2 +- 9 files changed, 64 insertions(+), 9 deletions(-) create mode 100644 tests/ui-fulldeps/fluent-messages/invalid-escape.ftl diff --git a/compiler/rustc_codegen_llvm/messages.ftl b/compiler/rustc_codegen_llvm/messages.ftl index e5df417370b..b6d7484bcce 100644 --- a/compiler/rustc_codegen_llvm/messages.ftl +++ b/compiler/rustc_codegen_llvm/messages.ftl @@ -27,7 +27,8 @@ codegen_llvm_error_calling_dlltool = Error calling dlltool: {$error} codegen_llvm_dlltool_fail_import_library = - Dlltool could not create import library: {$stdout}\n{$stderr} + Dlltool could not create import library: {$stdout} + {$stderr} codegen_llvm_target_feature_disable_or_enable = the target features {$features} must all be either enabled or disabled together diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl index 33bb116d6fa..f6751df443f 100644 --- a/compiler/rustc_const_eval/messages.ftl +++ b/compiler/rustc_const_eval/messages.ftl @@ -39,17 +39,25 @@ const_eval_unstable_const_fn = `{$def_path}` is not yet stable as a const fn const_eval_unallowed_mutable_refs = mutable references are not allowed in the final value of {$kind}s .teach_note = - References in statics and constants may only refer to immutable values.\n\n + References in statics and constants may only refer to immutable values. + + Statics are shared everywhere, and if they refer to mutable data one might violate memory - safety since holding multiple mutable references to shared data is not allowed.\n\n + safety since holding multiple mutable references to shared data is not allowed. + + If you really want global mutable state, try using static mut or a global UnsafeCell. const_eval_unallowed_mutable_refs_raw = raw mutable references are not allowed in the final value of {$kind}s .teach_note = - References in statics and constants may only refer to immutable values.\n\n + References in statics and constants may only refer to immutable values. + + Statics are shared everywhere, and if they refer to mutable data one might violate memory - safety since holding multiple mutable references to shared data is not allowed.\n\n + safety since holding multiple mutable references to shared data is not allowed. + + If you really want global mutable state, try using static mut or a global UnsafeCell. const_eval_non_const_fmt_macro_call = diff --git a/compiler/rustc_incremental/messages.ftl b/compiler/rustc_incremental/messages.ftl index 4852ee0d959..b760620e3d4 100644 --- a/compiler/rustc_incremental/messages.ftl +++ b/compiler/rustc_incremental/messages.ftl @@ -24,7 +24,7 @@ incremental_field_associated_value_expected = associated value expected for `{$n incremental_no_field = no field `{$name}` incremental_assertion_auto = - `except` specified DepNodes that can not be affected for \"{$name}\": \"{$e}\" + `except` specified DepNodes that can not be affected for "{$name}": "{$e}" incremental_undefined_clean_dirty_assertions_item = clean/dirty auto-assertions not yet defined for Node::Item.node={$kind} diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 68e62c9789a..02af8ca54e4 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -91,7 +91,7 @@ lint_ty_qualified = usage of qualified `ty::{$ty}` lint_lintpass_by_hand = implementing `LintPass` by hand .help = try using `declare_lint_pass!` or `impl_lint_pass!` instead -lint_non_existant_doc_keyword = found non-existing keyword `{$keyword}` used in `#[doc(keyword = \"...\")]` +lint_non_existant_doc_keyword = found non-existing keyword `{$keyword}` used in `#[doc(keyword = "...")]` .help = only existing keywords are allowed in core/std lint_diag_out_of_impl = diff --git a/compiler/rustc_macros/src/diagnostics/fluent.rs b/compiler/rustc_macros/src/diagnostics/fluent.rs index 38c0f4895db..3b2f5cfdc73 100644 --- a/compiler/rustc_macros/src/diagnostics/fluent.rs +++ b/compiler/rustc_macros/src/diagnostics/fluent.rs @@ -111,6 +111,18 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok .emit(); return failed(&crate_name); } + let mut bad = false; + for esc in ["\\n", "\\\"", "\\'"] { + for _ in resource_contents.matches(esc) { + bad = true; + Diagnostic::spanned(resource_span, Level::Error, format!("invalid escape `{esc}` in Fluent resource")) + .note("Fluent does not interpret these escape sequences ()") + .emit(); + } + } + if bad { + return failed(&crate_name); + } let resource = match FluentResource::try_new(resource_contents) { Ok(resource) => resource, diff --git a/tests/ui-fulldeps/fluent-messages/invalid-escape.ftl b/tests/ui-fulldeps/fluent-messages/invalid-escape.ftl new file mode 100644 index 00000000000..e28852ea005 --- /dev/null +++ b/tests/ui-fulldeps/fluent-messages/invalid-escape.ftl @@ -0,0 +1 @@ +no_crate_bad_escape = don't use \n, \', or \" diff --git a/tests/ui-fulldeps/fluent-messages/test.rs b/tests/ui-fulldeps/fluent-messages/test.rs index 66575eb8e30..1ee7227a8e9 100644 --- a/tests/ui-fulldeps/fluent-messages/test.rs +++ b/tests/ui-fulldeps/fluent-messages/test.rs @@ -92,3 +92,12 @@ mod missing_message_ref { fluent_messages! { "./missing-message-ref.ftl" } //~^ ERROR referenced message `message` does not exist } + +mod bad_escape { + use super::fluent_messages; + + fluent_messages! { "./invalid-escape.ftl" } + //~^ ERROR invalid escape `\n` + //~| ERROR invalid escape `\"` + //~| ERROR invalid escape `\'` +} diff --git a/tests/ui-fulldeps/fluent-messages/test.stderr b/tests/ui-fulldeps/fluent-messages/test.stderr index c7961ed22f2..8a6a4a91cc2 100644 --- a/tests/ui-fulldeps/fluent-messages/test.stderr +++ b/tests/ui-fulldeps/fluent-messages/test.stderr @@ -83,5 +83,29 @@ LL | fluent_messages! { "./missing-message-ref.ftl" } | = help: you may have meant to use a variable reference (`{$message}`) -error: aborting due to 10 previous errors +error: invalid escape `\n` in Fluent resource + --> $DIR/test.rs:99:24 + | +LL | fluent_messages! { "./invalid-escape.ftl" } + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: os-specific message + +error: invalid escape `\"` in Fluent resource + --> $DIR/test.rs:99:24 + | +LL | fluent_messages! { "./invalid-escape.ftl" } + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: os-specific message + +error: invalid escape `\'` in Fluent resource + --> $DIR/test.rs:99:24 + | +LL | fluent_messages! { "./invalid-escape.ftl" } + | ^^^^^^^^^^^^^^^^^^^^^^ + | + = note: os-specific message + +error: aborting due to 13 previous errors diff --git a/tests/ui-fulldeps/internal-lints/existing_doc_keyword.stderr b/tests/ui-fulldeps/internal-lints/existing_doc_keyword.stderr index 4e296fff6d0..5110b9be08a 100644 --- a/tests/ui-fulldeps/internal-lints/existing_doc_keyword.stderr +++ b/tests/ui-fulldeps/internal-lints/existing_doc_keyword.stderr @@ -1,4 +1,4 @@ -error: found non-existing keyword `tadam` used in `#[doc(keyword = \"...\")]` +error: found non-existing keyword `tadam` used in `#[doc(keyword = "...")]` --> $DIR/existing_doc_keyword.rs:10:1 | LL | #[doc(keyword = "tadam")] From dc4ba57566acac492df2c2074d2d7144566dc7df Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Mon, 12 Dec 2022 00:42:45 -0500 Subject: [PATCH 261/346] Stabilize a portion of 'once_cell' Move items not part of this stabilization to 'lazy_cell' or 'once_cell_try' --- compiler/rustc_borrowck/src/lib.rs | 2 +- compiler/rustc_codegen_llvm/src/lib.rs | 1 - compiler/rustc_codegen_ssa/src/lib.rs | 1 - compiler/rustc_data_structures/src/lib.rs | 2 +- compiler/rustc_driver_impl/src/lib.rs | 2 +- compiler/rustc_error_messages/src/lib.rs | 2 +- compiler/rustc_feature/src/lib.rs | 2 +- compiler/rustc_hir_analysis/src/lib.rs | 2 +- compiler/rustc_interface/src/lib.rs | 2 +- compiler/rustc_metadata/src/lib.rs | 1 - compiler/rustc_middle/src/lib.rs | 1 - compiler/rustc_mir_build/src/lib.rs | 1 - compiler/rustc_mir_dataflow/src/lib.rs | 1 - compiler/rustc_mir_transform/src/lib.rs | 1 - compiler/rustc_query_impl/src/lib.rs | 1 - compiler/rustc_session/src/lib.rs | 2 +- library/alloc/tests/lib.rs | 1 - library/core/src/cell.rs | 4 +- library/core/src/cell/lazy.rs | 18 +++--- library/core/src/cell/once.rs | 46 ++++++--------- library/core/tests/lib.rs | 2 +- library/std/src/lib.rs | 2 +- library/std/src/sync/lazy_lock.rs | 24 ++++---- library/std/src/sync/mod.rs | 4 +- library/std/src/sync/once_lock.rs | 59 +++++++------------ src/librustdoc/lib.rs | 2 +- src/tools/clippy/clippy_dev/src/lib.rs | 1 - src/tools/clippy/clippy_lints/src/lib.rs | 1 - src/tools/clippy/clippy_utils/src/lib.rs | 1 - src/tools/clippy/src/driver.rs | 2 +- src/tools/clippy/tests/compile-test.rs | 2 +- src/tools/clippy/tests/dogfood.rs | 2 +- .../clippy/tests/lint_message_convention.rs | 2 +- src/tools/clippy/tests/workspace.rs | 2 +- tests/run-make/libtest-thread-limit/test.rs | 2 - .../nested-closure.rs | 2 +- tests/ui/sync/suggest-once-cell.rs | 2 - tests/ui/sync/suggest-once-cell.stderr | 4 +- tests/ui/sync/suggest-ref-cell.rs | 2 - tests/ui/sync/suggest-ref-cell.stderr | 4 +- 40 files changed, 87 insertions(+), 128 deletions(-) diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index b7ce3afce7b..9bd7cff1f33 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -5,7 +5,7 @@ #![feature(let_chains)] #![feature(min_specialization)] #![feature(never_type)] -#![feature(once_cell)] +#![feature(lazy_cell)] #![feature(rustc_attrs)] #![feature(stmt_expr_attributes)] #![feature(trusted_step)] diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index e5bae009ed6..3f77ea77eff 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -10,7 +10,6 @@ #![feature(iter_intersperse)] #![feature(let_chains)] #![feature(never_type)] -#![feature(once_cell)] #![recursion_limit = "256"] #![allow(rustc::potential_query_instability)] #![deny(rustc::untranslatable_diagnostic)] diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs index 81227b04e8a..0ab12314b3c 100644 --- a/compiler/rustc_codegen_ssa/src/lib.rs +++ b/compiler/rustc_codegen_ssa/src/lib.rs @@ -5,7 +5,6 @@ #![feature(int_roundings)] #![feature(let_chains)] #![feature(never_type)] -#![feature(once_cell)] #![feature(strict_provenance)] #![feature(try_blocks)] #![recursion_limit = "256"] diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index 0339fb925d4..9b52638e612 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -20,7 +20,7 @@ #![feature(never_type)] #![feature(type_alias_impl_trait)] #![feature(new_uninit)] -#![feature(once_cell)] +#![feature(lazy_cell)] #![feature(rustc_attrs)] #![feature(negative_impls)] #![feature(test)] diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 1e835f6065a..b96b356f551 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -6,7 +6,7 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(is_terminal)] -#![feature(once_cell)] +#![feature(lazy_cell)] #![feature(decl_macro)] #![recursion_limit = "256"] #![allow(rustc::potential_query_instability)] diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 301dacc2824..6f319b96f2f 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -1,5 +1,5 @@ #![feature(let_chains)] -#![feature(once_cell)] +#![feature(lazy_cell)] #![feature(rustc_attrs)] #![feature(type_alias_impl_trait)] #![deny(rustc::untranslatable_diagnostic)] diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs index 93d16716346..3ce16e15667 100644 --- a/compiler/rustc_feature/src/lib.rs +++ b/compiler/rustc_feature/src/lib.rs @@ -11,7 +11,7 @@ //! even if it is stabilized or removed, *do not remove it*. Instead, move the //! symbol to the `accepted` or `removed` modules respectively. -#![feature(once_cell)] +#![feature(lazy_cell)] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index d43230cb563..2a9025d60ab 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -67,7 +67,7 @@ This API is completely unstable and subject to change. #![feature(let_chains)] #![feature(min_specialization)] #![feature(never_type)] -#![feature(once_cell)] +#![feature(lazy_cell)] #![feature(slice_partition_dedup)] #![feature(try_blocks)] #![feature(is_some_and)] diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs index 15e02671075..9664ba8bd8a 100644 --- a/compiler/rustc_interface/src/lib.rs +++ b/compiler/rustc_interface/src/lib.rs @@ -2,7 +2,7 @@ #![feature(decl_macro)] #![feature(internal_output_capture)] #![feature(thread_spawn_unchecked)] -#![feature(once_cell)] +#![feature(lazy_cell)] #![feature(try_blocks)] #![recursion_limit = "256"] #![allow(rustc::potential_query_instability)] diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs index 98d9ad31fe0..880da5ca593 100644 --- a/compiler/rustc_metadata/src/lib.rs +++ b/compiler/rustc_metadata/src/lib.rs @@ -4,7 +4,6 @@ #![feature(generators)] #![feature(iter_from_generator)] #![feature(let_chains)] -#![feature(once_cell)] #![feature(proc_macro_internals)] #![feature(macro_metavar_expr)] #![feature(min_specialization)] diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 45c4a1057d2..0e883424fd4 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -39,7 +39,6 @@ #![feature(never_type)] #![feature(extern_types)] #![feature(new_uninit)] -#![feature(once_cell)] #![feature(let_chains)] #![feature(min_specialization)] #![feature(trusted_len)] diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index 04709197578..3f9236c9dd9 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -8,7 +8,6 @@ #![feature(if_let_guard)] #![feature(let_chains)] #![feature(min_specialization)] -#![feature(once_cell)] #![feature(try_blocks)] #![recursion_limit = "256"] diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs index 4ed6f7e90ff..43caa2ea973 100644 --- a/compiler/rustc_mir_dataflow/src/lib.rs +++ b/compiler/rustc_mir_dataflow/src/lib.rs @@ -3,7 +3,6 @@ #![feature(exact_size_is_empty)] #![feature(let_chains)] #![feature(min_specialization)] -#![feature(once_cell)] #![feature(stmt_expr_attributes)] #![feature(trusted_step)] #![recursion_limit = "256"] diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 3a515fe8323..6173b446b87 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -5,7 +5,6 @@ #![feature(map_try_insert)] #![feature(min_specialization)] #![feature(never_type)] -#![feature(once_cell)] #![feature(option_get_or_insert_default)] #![feature(trusted_step)] #![feature(try_blocks)] diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs index 4cd94237061..021a67c9513 100644 --- a/compiler/rustc_query_impl/src/lib.rs +++ b/compiler/rustc_query_impl/src/lib.rs @@ -5,7 +5,6 @@ #![feature(const_mut_refs)] #![feature(min_specialization)] #![feature(never_type)] -#![feature(once_cell)] #![feature(rustc_attrs)] #![recursion_limit = "256"] #![allow(rustc::potential_query_instability)] diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index 74aef785163..968728905e7 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -2,7 +2,7 @@ #![feature(let_chains)] #![feature(min_specialization)] #![feature(never_type)] -#![feature(once_cell)] +#![feature(lazy_cell)] #![feature(option_get_or_insert_default)] #![feature(rustc_attrs)] #![feature(map_many_mut)] diff --git a/library/alloc/tests/lib.rs b/library/alloc/tests/lib.rs index 966cf575116..6387279f4c1 100644 --- a/library/alloc/tests/lib.rs +++ b/library/alloc/tests/lib.rs @@ -43,7 +43,6 @@ #![feature(slice_flatten)] #![feature(thin_box)] #![feature(strict_provenance)] -#![feature(once_cell)] #![feature(drain_keep_rest)] #![deny(fuzzy_provenance_casts)] #![deny(unsafe_op_in_unsafe_fn)] diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 9d1720acf36..178927f6385 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -202,9 +202,9 @@ use crate::ptr::{self, NonNull}; mod lazy; mod once; -#[unstable(feature = "once_cell", issue = "74465")] +#[unstable(feature = "lazy_cell", issue = "109736")] pub use lazy::LazyCell; -#[unstable(feature = "once_cell", issue = "74465")] +#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] pub use once::OnceCell; /// A mutable memory location. diff --git a/library/core/src/cell/lazy.rs b/library/core/src/cell/lazy.rs index 65d12c25c51..64a6ce51b2e 100644 --- a/library/core/src/cell/lazy.rs +++ b/library/core/src/cell/lazy.rs @@ -11,7 +11,7 @@ use crate::ops::Deref; /// # Examples /// /// ``` -/// #![feature(once_cell)] +/// #![feature(lazy_cell)] /// /// use std::cell::LazyCell; /// @@ -29,7 +29,7 @@ use crate::ops::Deref; /// // 92 /// // 92 /// ``` -#[unstable(feature = "once_cell", issue = "74465")] +#[unstable(feature = "lazy_cell", issue = "109736")] pub struct LazyCell T> { cell: OnceCell, init: Cell>, @@ -41,7 +41,7 @@ impl T> LazyCell { /// # Examples /// /// ``` - /// #![feature(once_cell)] + /// #![feature(lazy_cell)] /// /// use std::cell::LazyCell; /// @@ -52,7 +52,7 @@ impl T> LazyCell { /// assert_eq!(&*lazy, "HELLO, WORLD!"); /// ``` #[inline] - #[unstable(feature = "once_cell", issue = "74465")] + #[unstable(feature = "lazy_cell", issue = "109736")] pub const fn new(init: F) -> LazyCell { LazyCell { cell: OnceCell::new(), init: Cell::new(Some(init)) } } @@ -65,7 +65,7 @@ impl T> LazyCell { /// # Examples /// /// ``` - /// #![feature(once_cell)] + /// #![feature(lazy_cell)] /// /// use std::cell::LazyCell; /// @@ -75,7 +75,7 @@ impl T> LazyCell { /// assert_eq!(&*lazy, &92); /// ``` #[inline] - #[unstable(feature = "once_cell", issue = "74465")] + #[unstable(feature = "lazy_cell", issue = "109736")] pub fn force(this: &LazyCell) -> &T { this.cell.get_or_init(|| match this.init.take() { Some(f) => f(), @@ -84,7 +84,7 @@ impl T> LazyCell { } } -#[unstable(feature = "once_cell", issue = "74465")] +#[unstable(feature = "lazy_cell", issue = "109736")] impl T> Deref for LazyCell { type Target = T; #[inline] @@ -93,7 +93,7 @@ impl T> Deref for LazyCell { } } -#[unstable(feature = "once_cell", issue = "74465")] +#[unstable(feature = "lazy_cell", issue = "109736")] impl Default for LazyCell { /// Creates a new lazy value using `Default` as the initializing function. #[inline] @@ -102,7 +102,7 @@ impl Default for LazyCell { } } -#[unstable(feature = "once_cell", issue = "74465")] +#[unstable(feature = "lazy_cell", issue = "109736")] impl fmt::Debug for LazyCell { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Lazy").field("cell", &self.cell).field("init", &"..").finish() diff --git a/library/core/src/cell/once.rs b/library/core/src/cell/once.rs index f74e563f1b9..c5bd7a5fa01 100644 --- a/library/core/src/cell/once.rs +++ b/library/core/src/cell/once.rs @@ -16,8 +16,6 @@ use crate::mem; /// # Examples /// /// ``` -/// #![feature(once_cell)] -/// /// use std::cell::OnceCell; /// /// let cell = OnceCell::new(); @@ -29,7 +27,7 @@ use crate::mem; /// assert_eq!(value, "Hello, World!"); /// assert!(cell.get().is_some()); /// ``` -#[unstable(feature = "once_cell", issue = "74465")] +#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] pub struct OnceCell { // Invariant: written to at most once. inner: UnsafeCell>, @@ -39,7 +37,8 @@ impl OnceCell { /// Creates a new empty cell. #[inline] #[must_use] - #[unstable(feature = "once_cell", issue = "74465")] + #[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] pub const fn new() -> OnceCell { OnceCell { inner: UnsafeCell::new(None) } } @@ -48,7 +47,7 @@ impl OnceCell { /// /// Returns `None` if the cell is empty. #[inline] - #[unstable(feature = "once_cell", issue = "74465")] + #[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] pub fn get(&self) -> Option<&T> { // SAFETY: Safe due to `inner`'s invariant unsafe { &*self.inner.get() }.as_ref() @@ -58,7 +57,7 @@ impl OnceCell { /// /// Returns `None` if the cell is empty. #[inline] - #[unstable(feature = "once_cell", issue = "74465")] + #[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] pub fn get_mut(&mut self) -> Option<&mut T> { self.inner.get_mut().as_mut() } @@ -73,8 +72,6 @@ impl OnceCell { /// # Examples /// /// ``` - /// #![feature(once_cell)] - /// /// use std::cell::OnceCell; /// /// let cell = OnceCell::new(); @@ -86,7 +83,7 @@ impl OnceCell { /// assert!(cell.get().is_some()); /// ``` #[inline] - #[unstable(feature = "once_cell", issue = "74465")] + #[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] pub fn set(&self, value: T) -> Result<(), T> { // SAFETY: Safe because we cannot have overlapping mutable borrows let slot = unsafe { &*self.inner.get() }; @@ -117,8 +114,6 @@ impl OnceCell { /// # Examples /// /// ``` - /// #![feature(once_cell)] - /// /// use std::cell::OnceCell; /// /// let cell = OnceCell::new(); @@ -128,7 +123,7 @@ impl OnceCell { /// assert_eq!(value, &92); /// ``` #[inline] - #[unstable(feature = "once_cell", issue = "74465")] + #[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] pub fn get_or_init(&self, f: F) -> &T where F: FnOnce() -> T, @@ -153,7 +148,7 @@ impl OnceCell { /// # Examples /// /// ``` - /// #![feature(once_cell)] + /// #![feature(once_cell_try)] /// /// use std::cell::OnceCell; /// @@ -166,7 +161,7 @@ impl OnceCell { /// assert_eq!(value, Ok(&92)); /// assert_eq!(cell.get(), Some(&92)) /// ``` - #[unstable(feature = "once_cell", issue = "74465")] + #[unstable(feature = "once_cell_try", issue = "109737")] pub fn get_or_try_init(&self, f: F) -> Result<&T, E> where F: FnOnce() -> Result, @@ -199,8 +194,6 @@ impl OnceCell { /// # Examples /// /// ``` - /// #![feature(once_cell)] - /// /// use std::cell::OnceCell; /// /// let cell: OnceCell = OnceCell::new(); @@ -211,7 +204,7 @@ impl OnceCell { /// assert_eq!(cell.into_inner(), Some("hello".to_string())); /// ``` #[inline] - #[unstable(feature = "once_cell", issue = "74465")] + #[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] pub fn into_inner(self) -> Option { // Because `into_inner` takes `self` by value, the compiler statically verifies // that it is not currently borrowed. So it is safe to move out `Option`. @@ -227,8 +220,6 @@ impl OnceCell { /// # Examples /// /// ``` - /// #![feature(once_cell)] - /// /// use std::cell::OnceCell; /// /// let mut cell: OnceCell = OnceCell::new(); @@ -240,13 +231,13 @@ impl OnceCell { /// assert_eq!(cell.get(), None); /// ``` #[inline] - #[unstable(feature = "once_cell", issue = "74465")] + #[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] pub fn take(&mut self) -> Option { mem::take(self).into_inner() } } -#[unstable(feature = "once_cell", issue = "74465")] +#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] impl Default for OnceCell { #[inline] fn default() -> Self { @@ -254,7 +245,7 @@ impl Default for OnceCell { } } -#[unstable(feature = "once_cell", issue = "74465")] +#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] impl fmt::Debug for OnceCell { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.get() { @@ -264,7 +255,7 @@ impl fmt::Debug for OnceCell { } } -#[unstable(feature = "once_cell", issue = "74465")] +#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] impl Clone for OnceCell { #[inline] fn clone(&self) -> OnceCell { @@ -279,7 +270,7 @@ impl Clone for OnceCell { } } -#[unstable(feature = "once_cell", issue = "74465")] +#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] impl PartialEq for OnceCell { #[inline] fn eq(&self, other: &Self) -> bool { @@ -287,10 +278,11 @@ impl PartialEq for OnceCell { } } -#[unstable(feature = "once_cell", issue = "74465")] +#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] impl Eq for OnceCell {} -#[unstable(feature = "once_cell", issue = "74465")] +#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] +#[rustc_const_unstable(feature = "const_convert", issue = "88674")] impl const From for OnceCell { /// Creates a new `OnceCell` which already contains the given `value`. #[inline] @@ -300,5 +292,5 @@ impl const From for OnceCell { } // Just like for `Cell` this isn't needed, but results in nicer error messages. -#[unstable(feature = "once_cell", issue = "74465")] +#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] impl !Sync for OnceCell {} diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs index 108210b6573..344f0b61754 100644 --- a/library/core/tests/lib.rs +++ b/library/core/tests/lib.rs @@ -94,7 +94,7 @@ #![feature(pointer_is_aligned)] #![feature(portable_simd)] #![feature(ptr_metadata)] -#![feature(once_cell)] +#![feature(lazy_cell)] #![feature(unsized_tuple_coercion)] #![feature(const_option)] #![feature(const_option_ext)] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index baad6de707b..8c118b95b0a 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -339,7 +339,7 @@ #![feature(edition_panic)] #![feature(format_args_nl)] #![feature(log_syntax)] -#![feature(once_cell)] +#![feature(lazy_cell)] #![feature(saturating_int_impl)] #![feature(stdsimd)] #![feature(test)] diff --git a/library/std/src/sync/lazy_lock.rs b/library/std/src/sync/lazy_lock.rs index 7e85d6a063a..8e9ea293ce4 100644 --- a/library/std/src/sync/lazy_lock.rs +++ b/library/std/src/sync/lazy_lock.rs @@ -26,7 +26,7 @@ union Data { /// # Examples /// /// ``` -/// #![feature(once_cell)] +/// #![feature(lazy_cell)] /// /// use std::collections::HashMap; /// @@ -54,7 +54,7 @@ union Data { /// // Some("Hoyten") /// } /// ``` -#[unstable(feature = "once_cell", issue = "74465")] +#[unstable(feature = "lazy_cell", issue = "109736")] pub struct LazyLock T> { once: Once, data: UnsafeCell>, @@ -64,7 +64,7 @@ impl T> LazyLock { /// Creates a new lazy value with the given initializing /// function. #[inline] - #[unstable(feature = "once_cell", issue = "74465")] + #[unstable(feature = "lazy_cell", issue = "109736")] pub const fn new(f: F) -> LazyLock { LazyLock { once: Once::new(), data: UnsafeCell::new(Data { f: ManuallyDrop::new(f) }) } } @@ -76,7 +76,7 @@ impl T> LazyLock { /// # Examples /// /// ``` - /// #![feature(once_cell)] + /// #![feature(lazy_cell)] /// /// use std::sync::LazyLock; /// @@ -86,7 +86,7 @@ impl T> LazyLock { /// assert_eq!(&*lazy, &92); /// ``` #[inline] - #[unstable(feature = "once_cell", issue = "74465")] + #[unstable(feature = "lazy_cell", issue = "109736")] pub fn force(this: &LazyLock) -> &T { this.once.call_once(|| { // SAFETY: `call_once` only runs this closure once, ever. @@ -122,7 +122,7 @@ impl LazyLock { } } -#[unstable(feature = "once_cell", issue = "74465")] +#[unstable(feature = "lazy_cell", issue = "109736")] impl Drop for LazyLock { fn drop(&mut self) { match self.once.state() { @@ -135,7 +135,7 @@ impl Drop for LazyLock { } } -#[unstable(feature = "once_cell", issue = "74465")] +#[unstable(feature = "lazy_cell", issue = "109736")] impl T> Deref for LazyLock { type Target = T; @@ -145,7 +145,7 @@ impl T> Deref for LazyLock { } } -#[unstable(feature = "once_cell", issue = "74465")] +#[unstable(feature = "lazy_cell", issue = "109736")] impl Default for LazyLock { /// Creates a new lazy value using `Default` as the initializing function. #[inline] @@ -154,7 +154,7 @@ impl Default for LazyLock { } } -#[unstable(feature = "once_cell", issue = "74465")] +#[unstable(feature = "lazy_cell", issue = "109736")] impl fmt::Debug for LazyLock { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.get() { @@ -166,13 +166,13 @@ impl fmt::Debug for LazyLock { // We never create a `&F` from a `&LazyLock` so it is fine // to not impl `Sync` for `F` -#[unstable(feature = "once_cell", issue = "74465")] +#[unstable(feature = "lazy_cell", issue = "109736")] unsafe impl Sync for LazyLock {} // auto-derived `Send` impl is OK. -#[unstable(feature = "once_cell", issue = "74465")] +#[unstable(feature = "lazy_cell", issue = "109736")] impl RefUnwindSafe for LazyLock {} -#[unstable(feature = "once_cell", issue = "74465")] +#[unstable(feature = "lazy_cell", issue = "109736")] impl UnwindSafe for LazyLock {} #[cfg(test)] diff --git a/library/std/src/sync/mod.rs b/library/std/src/sync/mod.rs index 4edc956173b..5dd585b9b37 100644 --- a/library/std/src/sync/mod.rs +++ b/library/std/src/sync/mod.rs @@ -172,9 +172,9 @@ pub use self::poison::{LockResult, PoisonError, TryLockError, TryLockResult}; #[stable(feature = "rust1", since = "1.0.0")] pub use self::rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard}; -#[unstable(feature = "once_cell", issue = "74465")] +#[unstable(feature = "lazy_cell", issue = "109736")] pub use self::lazy_lock::LazyLock; -#[unstable(feature = "once_cell", issue = "74465")] +#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] pub use self::once_lock::OnceLock; pub(crate) use self::remutex::{ReentrantMutex, ReentrantMutexGuard}; diff --git a/library/std/src/sync/once_lock.rs b/library/std/src/sync/once_lock.rs index ed339ca5df6..8c34375ea07 100644 --- a/library/std/src/sync/once_lock.rs +++ b/library/std/src/sync/once_lock.rs @@ -14,8 +14,6 @@ use crate::sync::Once; /// # Examples /// /// ``` -/// #![feature(once_cell)] -/// /// use std::sync::OnceLock; /// /// static CELL: OnceLock = OnceLock::new(); @@ -32,7 +30,7 @@ use crate::sync::Once; /// assert!(value.is_some()); /// assert_eq!(value.unwrap().as_str(), "Hello, World!"); /// ``` -#[unstable(feature = "once_cell", issue = "74465")] +#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] pub struct OnceLock { once: Once, // Whether or not the value is initialized is tracked by `once.is_completed()`. @@ -40,8 +38,6 @@ pub struct OnceLock { /// `PhantomData` to make sure dropck understands we're dropping T in our Drop impl. /// /// ```compile_fail,E0597 - /// #![feature(once_cell)] - /// /// use std::sync::OnceLock; /// /// struct A<'a>(&'a str); @@ -63,7 +59,8 @@ impl OnceLock { /// Creates a new empty cell. #[inline] #[must_use] - #[unstable(feature = "once_cell", issue = "74465")] + #[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] + #[rustc_const_stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] pub const fn new() -> OnceLock { OnceLock { once: Once::new(), @@ -77,7 +74,7 @@ impl OnceLock { /// Returns `None` if the cell is empty, or being initialized. This /// method never blocks. #[inline] - #[unstable(feature = "once_cell", issue = "74465")] + #[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] pub fn get(&self) -> Option<&T> { if self.is_initialized() { // Safe b/c checked is_initialized @@ -91,7 +88,7 @@ impl OnceLock { /// /// Returns `None` if the cell is empty. This method never blocks. #[inline] - #[unstable(feature = "once_cell", issue = "74465")] + #[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] pub fn get_mut(&mut self) -> Option<&mut T> { if self.is_initialized() { // Safe b/c checked is_initialized and we have a unique access @@ -111,8 +108,6 @@ impl OnceLock { /// # Examples /// /// ``` - /// #![feature(once_cell)] - /// /// use std::sync::OnceLock; /// /// static CELL: OnceLock = OnceLock::new(); @@ -129,7 +124,7 @@ impl OnceLock { /// } /// ``` #[inline] - #[unstable(feature = "once_cell", issue = "74465")] + #[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] pub fn set(&self, value: T) -> Result<(), T> { let mut value = Some(value); self.get_or_init(|| value.take().unwrap()); @@ -158,8 +153,6 @@ impl OnceLock { /// # Examples /// /// ``` - /// #![feature(once_cell)] - /// /// use std::sync::OnceLock; /// /// let cell = OnceLock::new(); @@ -169,7 +162,7 @@ impl OnceLock { /// assert_eq!(value, &92); /// ``` #[inline] - #[unstable(feature = "once_cell", issue = "74465")] + #[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] pub fn get_or_init(&self, f: F) -> &T where F: FnOnce() -> T, @@ -195,7 +188,7 @@ impl OnceLock { /// # Examples /// /// ``` - /// #![feature(once_cell)] + /// #![feature(once_cell_try)] /// /// use std::sync::OnceLock; /// @@ -209,7 +202,7 @@ impl OnceLock { /// assert_eq!(cell.get(), Some(&92)) /// ``` #[inline] - #[unstable(feature = "once_cell", issue = "74465")] + #[unstable(feature = "once_cell_try", issue = "109737")] pub fn get_or_try_init(&self, f: F) -> Result<&T, E> where F: FnOnce() -> Result, @@ -236,8 +229,6 @@ impl OnceLock { /// # Examples /// /// ``` - /// #![feature(once_cell)] - /// /// use std::sync::OnceLock; /// /// let cell: OnceLock = OnceLock::new(); @@ -248,7 +239,7 @@ impl OnceLock { /// assert_eq!(cell.into_inner(), Some("hello".to_string())); /// ``` #[inline] - #[unstable(feature = "once_cell", issue = "74465")] + #[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] pub fn into_inner(mut self) -> Option { self.take() } @@ -262,8 +253,6 @@ impl OnceLock { /// # Examples /// /// ``` - /// #![feature(once_cell)] - /// /// use std::sync::OnceLock; /// /// let mut cell: OnceLock = OnceLock::new(); @@ -275,7 +264,7 @@ impl OnceLock { /// assert_eq!(cell.get(), None); /// ``` #[inline] - #[unstable(feature = "once_cell", issue = "74465")] + #[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] pub fn take(&mut self) -> Option { if self.is_initialized() { self.once = Once::new(); @@ -344,17 +333,17 @@ impl OnceLock { // scoped thread B, which fills the cell, which is // then destroyed by A. That is, destructor observes // a sent value. -#[unstable(feature = "once_cell", issue = "74465")] +#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] unsafe impl Sync for OnceLock {} -#[unstable(feature = "once_cell", issue = "74465")] +#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] unsafe impl Send for OnceLock {} -#[unstable(feature = "once_cell", issue = "74465")] +#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] impl RefUnwindSafe for OnceLock {} -#[unstable(feature = "once_cell", issue = "74465")] +#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] impl UnwindSafe for OnceLock {} -#[unstable(feature = "once_cell", issue = "74465")] +#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_default_impls", issue = "87864")] impl const Default for OnceLock { /// Creates a new empty cell. @@ -362,8 +351,6 @@ impl const Default for OnceLock { /// # Example /// /// ``` - /// #![feature(once_cell)] - /// /// use std::sync::OnceLock; /// /// fn main() { @@ -376,7 +363,7 @@ impl const Default for OnceLock { } } -#[unstable(feature = "once_cell", issue = "74465")] +#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] impl fmt::Debug for OnceLock { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.get() { @@ -386,7 +373,7 @@ impl fmt::Debug for OnceLock { } } -#[unstable(feature = "once_cell", issue = "74465")] +#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] impl Clone for OnceLock { #[inline] fn clone(&self) -> OnceLock { @@ -401,15 +388,13 @@ impl Clone for OnceLock { } } -#[unstable(feature = "once_cell", issue = "74465")] +#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] impl From for OnceLock { /// Create a new cell with its contents set to `value`. /// /// # Example /// /// ``` - /// #![feature(once_cell)] - /// /// use std::sync::OnceLock; /// /// # fn main() -> Result<(), i32> { @@ -430,7 +415,7 @@ impl From for OnceLock { } } -#[unstable(feature = "once_cell", issue = "74465")] +#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] impl PartialEq for OnceLock { #[inline] fn eq(&self, other: &OnceLock) -> bool { @@ -438,10 +423,10 @@ impl PartialEq for OnceLock { } } -#[unstable(feature = "once_cell", issue = "74465")] +#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] impl Eq for OnceLock {} -#[unstable(feature = "once_cell", issue = "74465")] +#[stable(feature = "once_cell", since = "CURRENT_RUSTC_VERSION")] unsafe impl<#[may_dangle] T> Drop for OnceLock { #[inline] fn drop(&mut self) { diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 4fcf0873600..4c4dbc9864f 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -11,7 +11,7 @@ #![feature(let_chains)] #![feature(test)] #![feature(never_type)] -#![feature(once_cell)] +#![feature(lazy_cell)] #![feature(type_ascription)] #![feature(iter_intersperse)] #![feature(type_alias_impl_trait)] diff --git a/src/tools/clippy/clippy_dev/src/lib.rs b/src/tools/clippy/clippy_dev/src/lib.rs index e70488165b9..8871873c661 100644 --- a/src/tools/clippy/clippy_dev/src/lib.rs +++ b/src/tools/clippy/clippy_dev/src/lib.rs @@ -1,5 +1,4 @@ #![feature(let_chains)] -#![feature(once_cell)] #![feature(rustc_private)] #![cfg_attr(feature = "deny-warnings", deny(warnings))] // warn on lints, that are included in `rust-lang/rust`s bootstrap diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs index c9210bf73f8..3da7f95c1b9 100644 --- a/src/tools/clippy/clippy_lints/src/lib.rs +++ b/src/tools/clippy/clippy_lints/src/lib.rs @@ -7,7 +7,6 @@ #![feature(let_chains)] #![feature(lint_reasons)] #![feature(never_type)] -#![feature(once_cell)] #![feature(rustc_private)] #![feature(stmt_expr_attributes)] #![recursion_limit = "512"] diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index fd06c0b8677..619aa9f4bf6 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -3,7 +3,6 @@ #![feature(let_chains)] #![feature(lint_reasons)] #![feature(never_type)] -#![feature(once_cell)] #![feature(rustc_private)] #![recursion_limit = "512"] #![cfg_attr(feature = "deny-warnings", deny(warnings))] diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs index f08393c303e..9e0822404b6 100644 --- a/src/tools/clippy/src/driver.rs +++ b/src/tools/clippy/src/driver.rs @@ -1,6 +1,6 @@ #![feature(rustc_private)] #![feature(let_chains)] -#![feature(once_cell)] +#![feature(lazy_cell)] #![feature(lint_reasons)] #![cfg_attr(feature = "deny-warnings", deny(warnings))] // warn on lints, that are included in `rust-lang/rust`s bootstrap diff --git a/src/tools/clippy/tests/compile-test.rs b/src/tools/clippy/tests/compile-test.rs index c10ee969c01..57890ff3173 100644 --- a/src/tools/clippy/tests/compile-test.rs +++ b/src/tools/clippy/tests/compile-test.rs @@ -1,5 +1,5 @@ #![feature(test)] // compiletest_rs requires this attribute -#![feature(once_cell)] +#![feature(lazy_cell)] #![feature(is_sorted)] #![cfg_attr(feature = "deny-warnings", deny(warnings))] #![warn(rust_2018_idioms, unused_lifetimes)] diff --git a/src/tools/clippy/tests/dogfood.rs b/src/tools/clippy/tests/dogfood.rs index 3a5d478fa31..68a878e9a3d 100644 --- a/src/tools/clippy/tests/dogfood.rs +++ b/src/tools/clippy/tests/dogfood.rs @@ -3,7 +3,7 @@ //! //! See [Eating your own dog food](https://en.wikipedia.org/wiki/Eating_your_own_dog_food) for context -#![feature(once_cell)] +#![feature(lazy_cell)] #![cfg_attr(feature = "deny-warnings", deny(warnings))] #![warn(rust_2018_idioms, unused_lifetimes)] diff --git a/src/tools/clippy/tests/lint_message_convention.rs b/src/tools/clippy/tests/lint_message_convention.rs index abd0d1bc593..8feea800fdb 100644 --- a/src/tools/clippy/tests/lint_message_convention.rs +++ b/src/tools/clippy/tests/lint_message_convention.rs @@ -1,4 +1,4 @@ -#![feature(once_cell)] +#![feature(lazy_cell)] #![cfg_attr(feature = "deny-warnings", deny(warnings))] #![warn(rust_2018_idioms, unused_lifetimes)] diff --git a/src/tools/clippy/tests/workspace.rs b/src/tools/clippy/tests/workspace.rs index 95325e06037..c9cbc50546c 100644 --- a/src/tools/clippy/tests/workspace.rs +++ b/src/tools/clippy/tests/workspace.rs @@ -1,4 +1,4 @@ -#![feature(once_cell)] +#![feature(lazy_cell)] use std::path::PathBuf; use std::process::Command; diff --git a/tests/run-make/libtest-thread-limit/test.rs b/tests/run-make/libtest-thread-limit/test.rs index 26bc29216cf..88e8a498ae9 100644 --- a/tests/run-make/libtest-thread-limit/test.rs +++ b/tests/run-make/libtest-thread-limit/test.rs @@ -1,5 +1,3 @@ -#![feature(once_cell)] - use std::{ io::ErrorKind, sync::OnceLock, diff --git a/tests/ui/rfc-2632-const-trait-impl/nested-closure.rs b/tests/ui/rfc-2632-const-trait-impl/nested-closure.rs index a851136009c..0b423b34022 100644 --- a/tests/ui/rfc-2632-const-trait-impl/nested-closure.rs +++ b/tests/ui/rfc-2632-const-trait-impl/nested-closure.rs @@ -1,6 +1,6 @@ // check-pass -#![feature(const_trait_impl, once_cell)] +#![feature(const_trait_impl, lazy_cell)] use std::sync::LazyLock; diff --git a/tests/ui/sync/suggest-once-cell.rs b/tests/ui/sync/suggest-once-cell.rs index 82fca45b1a4..14f40ad87a3 100644 --- a/tests/ui/sync/suggest-once-cell.rs +++ b/tests/ui/sync/suggest-once-cell.rs @@ -1,5 +1,3 @@ -#![feature(once_cell)] - fn require_sync() {} //~^ NOTE required by this bound in `require_sync` //~| NOTE required by a bound in `require_sync` diff --git a/tests/ui/sync/suggest-once-cell.stderr b/tests/ui/sync/suggest-once-cell.stderr index fadf05374d8..20242f4b61c 100644 --- a/tests/ui/sync/suggest-once-cell.stderr +++ b/tests/ui/sync/suggest-once-cell.stderr @@ -1,5 +1,5 @@ error[E0277]: `OnceCell<()>` cannot be shared between threads safely - --> $DIR/suggest-once-cell.rs:8:20 + --> $DIR/suggest-once-cell.rs:6:20 | LL | require_sync::>(); | ^^^^^^^^^^^^^^^^^^^^^^^ `OnceCell<()>` cannot be shared between threads safely @@ -7,7 +7,7 @@ LL | require_sync::>(); = help: the trait `Sync` is not implemented for `OnceCell<()>` = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::OnceLock` instead note: required by a bound in `require_sync` - --> $DIR/suggest-once-cell.rs:3:20 + --> $DIR/suggest-once-cell.rs:1:20 | LL | fn require_sync() {} | ^^^^ required by this bound in `require_sync` diff --git a/tests/ui/sync/suggest-ref-cell.rs b/tests/ui/sync/suggest-ref-cell.rs index 6b972ae0962..093a4999c65 100644 --- a/tests/ui/sync/suggest-ref-cell.rs +++ b/tests/ui/sync/suggest-ref-cell.rs @@ -1,5 +1,3 @@ -#![feature(once_cell)] - fn require_sync() {} //~^ NOTE required by this bound in `require_sync` //~| NOTE required by a bound in `require_sync` diff --git a/tests/ui/sync/suggest-ref-cell.stderr b/tests/ui/sync/suggest-ref-cell.stderr index 9e8b8fcb42e..ca3ae77b1a0 100644 --- a/tests/ui/sync/suggest-ref-cell.stderr +++ b/tests/ui/sync/suggest-ref-cell.stderr @@ -1,5 +1,5 @@ error[E0277]: `RefCell<()>` cannot be shared between threads safely - --> $DIR/suggest-ref-cell.rs:8:20 + --> $DIR/suggest-ref-cell.rs:6:20 | LL | require_sync::>(); | ^^^^^^^^^^^^^^^^^^^^^^ `RefCell<()>` cannot be shared between threads safely @@ -7,7 +7,7 @@ LL | require_sync::>(); = help: the trait `Sync` is not implemented for `RefCell<()>` = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead note: required by a bound in `require_sync` - --> $DIR/suggest-ref-cell.rs:3:20 + --> $DIR/suggest-ref-cell.rs:1:20 | LL | fn require_sync() {} | ^^^^ required by this bound in `require_sync` From d1b28b75d25d5f4c3d1769822a1b106b95b106f1 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Mon, 12 Dec 2022 04:16:18 -0500 Subject: [PATCH 262/346] Documentation updates to better share the purpose of OnceCell/OnceLock --- library/core/src/cell.rs | 93 +++++++++++++++++++++++++---------- library/core/src/cell/once.rs | 6 ++- library/std/src/sync/mod.rs | 5 +- 3 files changed, 76 insertions(+), 28 deletions(-) diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 178927f6385..d378b0b3b97 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -11,36 +11,77 @@ //! mutate it. //! //! Shareable mutable containers exist to permit mutability in a controlled manner, even in the -//! presence of aliasing. Both [`Cell`] and [`RefCell`] allow doing this in a single-threaded -//! way. However, neither `Cell` nor `RefCell` are thread safe (they do not implement -//! [`Sync`]). If you need to do aliasing and mutation between multiple threads it is possible to -//! use [`Mutex`], [`RwLock`] or [`atomic`] types. +//! presence of aliasing. [`Cell`], [`RefCell`], and [`OnceCell`] allow doing this in +//! a single-threaded way - they do not implement [`Sync`]. (If you need to do aliasing and +//! mutation among multiple threads, [`Mutex`], [`RwLock`], [`OnceLock`] or [`atomic`] +//! types are the correct data structures to do so). //! -//! Values of the `Cell` and `RefCell` types may be mutated through shared references (i.e. -//! the common `&T` type), whereas most Rust types can only be mutated through unique (`&mut T`) -//! references. We say that `Cell` and `RefCell` provide 'interior mutability', in contrast -//! with typical Rust types that exhibit 'inherited mutability'. +//! Values of the `Cell`, `RefCell`, and `OnceCell` types may be mutated through shared +//! references (i.e. the common `&T` type), whereas most Rust types can only be mutated through +//! unique (`&mut T`) references. We say these cell types provide 'interior mutability' +//! (mutable via `&T`), in contrast with typical Rust types that exhibit 'inherited mutability' +//! (mutable only via `&mut T`). //! -//! Cell types come in two flavors: `Cell` and `RefCell`. `Cell` implements interior -//! mutability by moving values in and out of the `Cell`. To use references instead of values, -//! one must use the `RefCell` type, acquiring a write lock before mutating. `Cell` provides -//! methods to retrieve and change the current interior value: +//! Cell types come in three flavors: `Cell`, `RefCell`, and `OnceCell`. Each provides +//! a different way of providing safe interior mutability. +//! +//! ## `Cell` +//! +//! [`Cell`] implements interior mutability by moving values in and out of the cell. That is, an +//! `&mut T` to the inner value can never be obtained, and the value itself cannot be directly +//! obtained without replacing it with something else. Both of these rules ensure that there is +//! never more than one reference pointing to the inner value. This type provides the following +//! methods: //! //! - For types that implement [`Copy`], the [`get`](Cell::get) method retrieves the current -//! interior value. +//! interior value by duplicating it. //! - For types that implement [`Default`], the [`take`](Cell::take) method replaces the current //! interior value with [`Default::default()`] and returns the replaced value. -//! - For all types, the [`replace`](Cell::replace) method replaces the current interior value and -//! returns the replaced value and the [`into_inner`](Cell::into_inner) method consumes the -//! `Cell` and returns the interior value. Additionally, the [`set`](Cell::set) method -//! replaces the interior value, dropping the replaced value. +//! - All types have: +//! - [`replace`](Cell::replace): replaces the current interior value and returns the replaced +//! value. +//! - [`into_inner`](Cell::into_inner): this method consumes the `Cell` and returns the +//! interior value. +//! - [`set`](Cell::set): this method replaces the interior value, dropping the replaced value. //! -//! `RefCell` uses Rust's lifetimes to implement 'dynamic borrowing', a process whereby one can +//! `Cell` is typically used for more simple types where copying or moving values isn't too +//! resource intensive (e.g. numbers), and should usually be preferred over other cell types when +//! possible. For larger and non-copy types, `RefCell` provides some advantages. +//! +//! ## `RefCell` +//! +//! [`RefCell`] uses Rust's lifetimes to implement "dynamic borrowing", a process whereby one can //! claim temporary, exclusive, mutable access to the inner value. Borrows for `RefCell`s are -//! tracked 'at runtime', unlike Rust's native reference types which are entirely tracked -//! statically, at compile time. Because `RefCell` borrows are dynamic it is possible to attempt -//! to borrow a value that is already mutably borrowed; when this happens it results in thread -//! panic. +//! tracked at _runtime_, unlike Rust's native reference types which are entirely tracked +//! statically, at compile time. +//! +//! An immutable reference to a `RefCell`'s inner value (`&T`) can be obtained with +//! [`borrow`](`RefCell::borrow`), and a mutable borrow (`&mut T`) can be obtained with +//! [`borrow_mut`](`RefCell::borrow_mut`). When these functions are called, they first verify that +//! Rust's borrow rules will be satisfied: any number of immutable borrows are allowed or a +//! single immutable borrow is allowed, but never both. If a borrow is attempted that would violate +//! these rules, the thread will panic. +//! +//! The corresponding [`Sync`] version of `RefCell` is [`RwLock`]. +//! +//! ## `OnceCell` +//! +//! [`OnceCell`] is somewhat of a hybrid of `Cell` and `RefCell` that works for values that +//! typically only need to be set once. This means that a reference `&T` can be obtained without +//! moving or copying the inner value (unlike `Cell`) but also without runtime checks (unlike +//! `RefCell`). However, its value can also not be updated once set unless you have a mutable +//! reference to the `OnceCell`. +//! +//! `OnceCell` provides the following methods: +//! +//! - [`get`](OnceCell::get): obtain a reference to the inner value +//! - [`set`](OnceCell::set): set the inner value if it is unset (returns a `Result`) +//! - [`get_or_init`](OnceCell::get_or_init): return the inner value, initializing it if needed +//! - [`get_mut`](OnceCell::get_mut): provide a mutable reference to the inner value, only available +//! if you have a mutable reference to the cell itself. +//! +//! The corresponding [`Sync`] version of `OnceCell` is [`OnceLock`]. +//! //! //! # When to choose interior mutability //! @@ -188,6 +229,8 @@ //! [`Rc`]: ../../std/rc/struct.Rc.html //! [`RwLock`]: ../../std/sync/struct.RwLock.html //! [`Mutex`]: ../../std/sync/struct.Mutex.html +//! [`OnceLock`]: ../../std/sync/struct.OnceLock.html +//! [`Sync`]: ../../std/marker/trait.Sync.html //! [`atomic`]: crate::sync::atomic #![stable(feature = "rust1", since = "1.0.0")] @@ -419,7 +462,7 @@ impl Cell { mem::replace(unsafe { &mut *self.value.get() }, val) } - /// Unwraps the value. + /// Unwraps the value, consuming the cell. /// /// # Examples /// @@ -1969,7 +2012,7 @@ impl UnsafeCell { UnsafeCell { value } } - /// Unwraps the value. + /// Unwraps the value, consuming the cell. /// /// # Examples /// @@ -2133,7 +2176,7 @@ impl SyncUnsafeCell { Self { value: UnsafeCell { value } } } - /// Unwraps the value. + /// Unwraps the value, consuming the cell. #[inline] pub const fn into_inner(self) -> T { self.value.into_inner() diff --git a/library/core/src/cell/once.rs b/library/core/src/cell/once.rs index c5bd7a5fa01..5dc2d523198 100644 --- a/library/core/src/cell/once.rs +++ b/library/core/src/cell/once.rs @@ -4,8 +4,10 @@ use crate::mem; /// A cell which can be written to only once. /// -/// Unlike [`RefCell`], a `OnceCell` only provides shared `&T` references to its value. -/// Unlike [`Cell`], a `OnceCell` doesn't require copying or replacing the value to access it. +/// This allows obtaining a shared `&T` reference to its inner value without copying or replacing +/// it (unlike [`Cell`]), and without runtime borrow checks (unlike [`RefCell`]). However, +/// only immutable references can be obtained unless one has a mutable reference to the cell +/// itself. /// /// For a thread-safe version of this struct, see [`std::sync::OnceLock`]. /// diff --git a/library/std/src/sync/mod.rs b/library/std/src/sync/mod.rs index 5dd585b9b37..19641753ffe 100644 --- a/library/std/src/sync/mod.rs +++ b/library/std/src/sync/mod.rs @@ -133,7 +133,9 @@ //! - [`Mutex`]: Mutual Exclusion mechanism, which ensures that at //! most one thread at a time is able to access some data. //! -//! - [`Once`]: Used for thread-safe, one-time initialization of a +//! - [`Once`]: Used for a thread-safe, one-time global initialization routine +//! +//! - [`OnceLock`]: Used for thread-safe, one-time initialization of a //! global variable. //! //! - [`RwLock`]: Provides a mutual exclusion mechanism which allows @@ -147,6 +149,7 @@ //! [`mpsc`]: crate::sync::mpsc //! [`Mutex`]: crate::sync::Mutex //! [`Once`]: crate::sync::Once +//! [`OnceLock`]: crate::sync::OnceLock //! [`RwLock`]: crate::sync::RwLock #![stable(feature = "rust1", since = "1.0.0")] From 9b5122976e9eb0f2f0b8def82fbcd972837880e4 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Wed, 29 Mar 2023 21:25:27 +0200 Subject: [PATCH 263/346] Em dashes are cooler than hyphens. --- library/core/src/cell.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index d378b0b3b97..63bce5d0ccd 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -12,7 +12,7 @@ //! //! Shareable mutable containers exist to permit mutability in a controlled manner, even in the //! presence of aliasing. [`Cell`], [`RefCell`], and [`OnceCell`] allow doing this in -//! a single-threaded way - they do not implement [`Sync`]. (If you need to do aliasing and +//! a single-threaded way—they do not implement [`Sync`]. (If you need to do aliasing and //! mutation among multiple threads, [`Mutex`], [`RwLock`], [`OnceLock`] or [`atomic`] //! types are the correct data structures to do so). //! From 1ce6e2bd339d0ea4d292d3afde482050c1f34497 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 29 Mar 2023 23:28:27 +0000 Subject: [PATCH 264/346] Don't ICE on placeholder consts in deep reject --- compiler/rustc_middle/src/ty/fast_reject.rs | 6 +++++- .../const-param-placeholder.fail.stderr | 16 ++++++++++++++ .../new-solver/const-param-placeholder.rs | 21 +++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 tests/ui/traits/new-solver/const-param-placeholder.fail.stderr create mode 100644 tests/ui/traits/new-solver/const-param-placeholder.rs diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs index 0a6e94248e6..61cde923e9a 100644 --- a/compiler/rustc_middle/src/ty/fast_reject.rs +++ b/compiler/rustc_middle/src/ty/fast_reject.rs @@ -312,6 +312,7 @@ impl DeepRejectCtxt { // Impls cannot contain these types as these cannot be named directly. ty::FnDef(..) | ty::Closure(..) | ty::Generator(..) => false, + // Placeholder types don't unify with anything on their own ty::Placeholder(..) | ty::Bound(..) => false, // Depending on the value of `treat_obligation_params`, we either @@ -359,6 +360,9 @@ impl DeepRejectCtxt { TreatParams::AsCandidateKey => true, }, + // Placeholder consts don't unify with anything on their own + ty::ConstKind::Placeholder(_) => false, + // As we don't necessarily eagerly evaluate constants, // they might unify with any value. ty::ConstKind::Expr(_) | ty::ConstKind::Unevaluated(_) | ty::ConstKind::Error(_) => { @@ -371,7 +375,7 @@ impl DeepRejectCtxt { ty::ConstKind::Infer(_) => true, - ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) => { + ty::ConstKind::Bound(..) => { bug!("unexpected obl const: {:?}", obligation_ct) } } diff --git a/tests/ui/traits/new-solver/const-param-placeholder.fail.stderr b/tests/ui/traits/new-solver/const-param-placeholder.fail.stderr new file mode 100644 index 00000000000..4db6e22e57f --- /dev/null +++ b/tests/ui/traits/new-solver/const-param-placeholder.fail.stderr @@ -0,0 +1,16 @@ +error[E0277]: the trait bound `[T; N]: Foo` is not satisfied + --> $DIR/const-param-placeholder.rs:17:17 + | +LL | needs_foo::<[T; N]>(); + | ^^^^^^ the trait `Foo` is not implemented for `[T; N]` + | + = help: the trait `Foo` is implemented for `[T; 1]` +note: required by a bound in `needs_foo` + --> $DIR/const-param-placeholder.rs:8:17 + | +LL | fn needs_foo() {} + | ^^^ required by this bound in `needs_foo` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/new-solver/const-param-placeholder.rs b/tests/ui/traits/new-solver/const-param-placeholder.rs new file mode 100644 index 00000000000..a83102a4cdd --- /dev/null +++ b/tests/ui/traits/new-solver/const-param-placeholder.rs @@ -0,0 +1,21 @@ +// compile-flags: -Ztrait-solver=next +// revisions: pass fail +//[pass] check-pass + +struct Wrapper([T; N]); + +trait Foo {} +fn needs_foo() {} + +#[cfg(fail)] +impl Foo for [T; 1] {} + +#[cfg(pass)] +impl Foo for [T; N] {} + +fn test() { + needs_foo::<[T; N]>(); + //[fail]~^ ERROR the trait bound `[T; N]: Foo` is not satisfied +} + +fn main() {} From f5c78c4d3a9ab8d7b8726540715cc2abfbea0eba Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 30 Mar 2023 00:23:11 +0000 Subject: [PATCH 265/346] Don't ICE on DiscriminantKind projection in new solver --- .../src/solve/project_goals.rs | 44 ++++++++++++++++++- .../ui/traits/new-solver/param-discr-kind.rs | 8 ++++ .../new-solver/projection-discr-kind.rs | 18 ++++++++ .../new-solver/projection-discr-kind.stderr | 17 +++++++ 4 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 tests/ui/traits/new-solver/param-discr-kind.rs create mode 100644 tests/ui/traits/new-solver/projection-discr-kind.rs create mode 100644 tests/ui/traits/new-solver/projection-discr-kind.stderr diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index 91b56fe3522..c7ff3a3b0ed 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -485,9 +485,49 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { ecx: &mut EvalCtxt<'_, 'tcx>, goal: Goal<'tcx, Self>, ) -> QueryResult<'tcx> { - let discriminant = goal.predicate.self_ty().discriminant_ty(ecx.tcx()); + let self_ty = goal.predicate.self_ty(); + let discriminant_ty = match *self_ty.kind() { + ty::Bool + | ty::Char + | ty::Int(..) + | ty::Uint(..) + | ty::Float(..) + | ty::Array(..) + | ty::RawPtr(..) + | ty::Ref(..) + | ty::FnDef(..) + | ty::FnPtr(..) + | ty::Closure(..) + | ty::Infer(ty::IntVar(..) | ty::FloatVar(..)) + | ty::Generator(..) + | ty::GeneratorWitness(..) + | ty::GeneratorWitnessMIR(..) + | ty::Never + | ty::Foreign(..) + | ty::Adt(_, _) + | ty::Str + | ty::Slice(_) + | ty::Dynamic(_, _, _) + | ty::Tuple(_) + | ty::Error(_) => self_ty.discriminant_ty(ecx.tcx()), + + // We do not call `Ty::discriminant_ty` on alias, param, or placeholder + // types, which return `::Discriminant` + // (or ICE in the case of placeholders). Projecting a type to itself + // is never really productive. + ty::Alias(_, _) | ty::Param(_) | ty::Placeholder(..) => { + return Err(NoSolution); + } + + ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) + | ty::Bound(..) => bug!( + "unexpected self ty `{:?}` when normalizing `::Discriminant`", + goal.predicate.self_ty() + ), + }; + ecx.probe(|ecx| { - ecx.eq(goal.param_env, goal.predicate.term, discriminant.into())?; + ecx.eq(goal.param_env, goal.predicate.term, discriminant_ty.into())?; ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) }) } diff --git a/tests/ui/traits/new-solver/param-discr-kind.rs b/tests/ui/traits/new-solver/param-discr-kind.rs new file mode 100644 index 00000000000..e319ddea106 --- /dev/null +++ b/tests/ui/traits/new-solver/param-discr-kind.rs @@ -0,0 +1,8 @@ +// compile-flags: -Ztrait-solver=next +// check-pass + +fn foo(x: T) { + std::mem::discriminant(&x); +} + +fn main() {} diff --git a/tests/ui/traits/new-solver/projection-discr-kind.rs b/tests/ui/traits/new-solver/projection-discr-kind.rs new file mode 100644 index 00000000000..20296b287b1 --- /dev/null +++ b/tests/ui/traits/new-solver/projection-discr-kind.rs @@ -0,0 +1,18 @@ +// compile-flags: -Ztrait-solver=next + +// Check that `::Discriminant` doesn't normalize +// to itself and cause overflow/ambiguity. + +trait Foo { + type Assoc; +} + +trait Bar {} +fn needs_bar(_: impl Bar) {} + +fn foo(x: T::Assoc) { + needs_bar(std::mem::discriminant(&x)); + //~^ ERROR the trait bound `Discriminant<::Assoc>: Bar` is not satisfied +} + +fn main() {} diff --git a/tests/ui/traits/new-solver/projection-discr-kind.stderr b/tests/ui/traits/new-solver/projection-discr-kind.stderr new file mode 100644 index 00000000000..03e28f993e2 --- /dev/null +++ b/tests/ui/traits/new-solver/projection-discr-kind.stderr @@ -0,0 +1,17 @@ +error[E0277]: the trait bound `Discriminant<::Assoc>: Bar` is not satisfied + --> $DIR/projection-discr-kind.rs:14:15 + | +LL | needs_bar(std::mem::discriminant(&x)); + | --------- ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `Discriminant<::Assoc>` + | | + | required by a bound introduced by this call + | +note: required by a bound in `needs_bar` + --> $DIR/projection-discr-kind.rs:11:22 + | +LL | fn needs_bar(_: impl Bar) {} + | ^^^ required by this bound in `needs_bar` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. From 321a5dba9ee42e2950bbff14c7dfb38e07d21bc4 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 30 Mar 2023 00:52:58 +0000 Subject: [PATCH 266/346] Check pointee metadata correctly in ui test --- .../src/solve/project_goals.rs | 4 +--- tests/ui/traits/new-solver/pointee.rs | 18 ++++++++---------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index c7ff3a3b0ed..ca9f6055ee0 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -346,10 +346,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { LangItem::Sized, [ty::GenericArg::from(goal.predicate.self_ty())], )); - ecx.add_goal(goal.with(tcx, sized_predicate)); - ecx.eq(goal.param_env, goal.predicate.term, tcx.types.unit.into())?; - return ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes); + tcx.types.unit } ty::Adt(def, substs) if def.is_struct() => { diff --git a/tests/ui/traits/new-solver/pointee.rs b/tests/ui/traits/new-solver/pointee.rs index fa6ee2e2daf..93c0542ace4 100644 --- a/tests/ui/traits/new-solver/pointee.rs +++ b/tests/ui/traits/new-solver/pointee.rs @@ -7,17 +7,15 @@ use std::ptr::{DynMetadata, Pointee}; trait Trait {} struct MyDst(T); -fn works() { - let _: ::Metadata = (); - let _: <[T] as Pointee>::Metadata = 1_usize; - let _: ::Metadata = 1_usize; - let _: as Pointee>::Metadata = give::>>(); - let _: as Pointee>::Metadata = (); - let _: <((((([u8],),),),),) as Pointee>::Metadata = 1_usize; -} +fn meta_is + ?Sized, U>() {} -fn give() -> U { - loop {} +fn works() { + meta_is::(); + meta_is::<[T], usize>(); + meta_is::(); + meta_is::, DynMetadata>>(); + meta_is::, ()>(); + meta_is::<((((([u8],),),),),), usize>(); } fn main() {} From 977694aaec6dce9b03979cbe1b146352502c2e33 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 30 Mar 2023 01:10:48 +0000 Subject: [PATCH 267/346] canonicalize float var as float in new solver --- compiler/rustc_trait_selection/src/solve/canonicalize.rs | 2 +- tests/ui/traits/new-solver/float-canonical.rs | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 tests/ui/traits/new-solver/float-canonical.rs diff --git a/compiler/rustc_trait_selection/src/solve/canonicalize.rs b/compiler/rustc_trait_selection/src/solve/canonicalize.rs index 7ee4f332306..2e5a8b7debc 100644 --- a/compiler/rustc_trait_selection/src/solve/canonicalize.rs +++ b/compiler/rustc_trait_selection/src/solve/canonicalize.rs @@ -291,7 +291,7 @@ impl<'tcx> TypeFolder> for Canonicalizer<'_, 'tcx> { if nt != t { return self.fold_ty(nt); } else { - CanonicalVarKind::Ty(CanonicalTyVarKind::Int) + CanonicalVarKind::Ty(CanonicalTyVarKind::Float) } } ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => { diff --git a/tests/ui/traits/new-solver/float-canonical.rs b/tests/ui/traits/new-solver/float-canonical.rs new file mode 100644 index 00000000000..b8748cd433b --- /dev/null +++ b/tests/ui/traits/new-solver/float-canonical.rs @@ -0,0 +1,8 @@ +// compile-flags: -Ztrait-solver=next +// check-pass + +fn foo(x: f64) { + let y = x + 1.0; +} + +fn main() {} From 1d7192d6ea5a5fdbd90788f41d0e948a4dedeefa Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 30 Mar 2023 02:13:24 +0000 Subject: [PATCH 268/346] deep reject only unify numeric var with concrete numeric --- compiler/rustc_middle/src/ty/fast_reject.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs index 0a6e94248e6..726689d8446 100644 --- a/compiler/rustc_middle/src/ty/fast_reject.rs +++ b/compiler/rustc_middle/src/ty/fast_reject.rs @@ -321,6 +321,10 @@ impl DeepRejectCtxt { TreatParams::AsCandidateKey => true, }, + ty::Infer(ty::IntVar(_)) => impl_ty.is_integral(), + + ty::Infer(ty::FloatVar(_)) => impl_ty.is_floating_point(), + ty::Infer(_) => true, // As we're walking the whole type, it may encounter projections From 01f49b350df806b0fbf9d379bd524f183da7517d Mon Sep 17 00:00:00 2001 From: "William D. Jones" Date: Wed, 29 Mar 2023 22:49:09 -0400 Subject: [PATCH 269/346] Update compiler-builtins to 0.1.91 to bring in msp430 shift primitive fixes. --- Cargo.lock | 4 ++-- library/std/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 561f29abec4..77d3b8cc2a1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -868,9 +868,9 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.89" +version = "0.1.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc9c2080d347a2c316518840ac9194644a9993dfa1e9778ef38979a339f5d8b" +checksum = "571298a3cce7e2afbd3d61abb91a18667d5ab25993ec577a88ee8ac45f00cc3a" dependencies = [ "cc", "rustc-std-workspace-core", diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 6345db24054..96c75f97f6e 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -16,7 +16,7 @@ panic_unwind = { path = "../panic_unwind", optional = true } panic_abort = { path = "../panic_abort" } core = { path = "../core" } libc = { version = "0.2.140", default-features = false, features = ['rustc-dep-of-std'] } -compiler_builtins = { version = "0.1.87" } +compiler_builtins = { version = "0.1.91" } profiler_builtins = { path = "../profiler_builtins", optional = true } unwind = { path = "../unwind" } hashbrown = { version = "0.12", default-features = false, features = ['rustc-dep-of-std'] } From ad60b99835824a75314e06ff1debf3332d483b55 Mon Sep 17 00:00:00 2001 From: pkubaj Date: Thu, 30 Mar 2023 07:05:24 +0000 Subject: [PATCH 270/346] Drop binutils on powerpc-unknown-freebsd FreeBSD 13.1 and 13.2 can build Rust with LLD just fine on powerpc. --- src/bootstrap/llvm.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/bootstrap/llvm.rs b/src/bootstrap/llvm.rs index a22f0f04b2e..cc2b45a9bdb 100644 --- a/src/bootstrap/llvm.rs +++ b/src/bootstrap/llvm.rs @@ -434,11 +434,6 @@ impl Step for Llvm { } } - // Workaround for ppc32 lld limitation - if target == "powerpc-unknown-freebsd" { - ldflags.exe.push(" -fuse-ld=bfd"); - } - // https://llvm.org/docs/HowToCrossCompileLLVM.html if target != builder.config.build { let LlvmResult { llvm_config, .. } = From b0850073133c548a53afee29400d3873fabb7985 Mon Sep 17 00:00:00 2001 From: jofas Date: Thu, 30 Mar 2023 10:20:57 +0200 Subject: [PATCH 271/346] removed deprecated markdown links from documentation --- library/alloc/src/collections/vec_deque/mod.rs | 3 --- library/core/src/slice/mod.rs | 3 --- 2 files changed, 6 deletions(-) diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 1ae72b715cd..53b3405bff1 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -2389,7 +2389,6 @@ impl VecDeque { /// /// See also [`binary_search_by`], [`binary_search_by_key`], and [`partition_point`]. /// - /// [`contains`]: VecDeque::contains /// [`binary_search_by`]: VecDeque::binary_search_by /// [`binary_search_by_key`]: VecDeque::binary_search_by_key /// [`partition_point`]: VecDeque::partition_point @@ -2451,7 +2450,6 @@ impl VecDeque { /// /// See also [`binary_search`], [`binary_search_by_key`], and [`partition_point`]. /// - /// [`contains`]: VecDeque::contains /// [`binary_search`]: VecDeque::binary_search /// [`binary_search_by_key`]: VecDeque::binary_search_by_key /// [`partition_point`]: VecDeque::partition_point @@ -2505,7 +2503,6 @@ impl VecDeque { /// /// See also [`binary_search`], [`binary_search_by`], and [`partition_point`]. /// - /// [`contains`]: VecDeque::contains /// [`make_contiguous().sort_by_key()`]: VecDeque::make_contiguous /// [`binary_search`]: VecDeque::binary_search /// [`binary_search_by`]: VecDeque::binary_search_by diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index eb571824065..b2cd1d567dc 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -2356,7 +2356,6 @@ impl [T] { /// /// See also [`binary_search_by`], [`binary_search_by_key`], and [`partition_point`]. /// - /// [`contains`]: slice::contains /// [`binary_search_by`]: slice::binary_search_by /// [`binary_search_by_key`]: slice::binary_search_by_key /// [`partition_point`]: slice::partition_point @@ -2437,7 +2436,6 @@ impl [T] { /// /// See also [`binary_search`], [`binary_search_by_key`], and [`partition_point`]. /// - /// [`contains`]: slice::contains /// [`binary_search`]: slice::binary_search /// [`binary_search_by_key`]: slice::binary_search_by_key /// [`partition_point`]: slice::partition_point @@ -2522,7 +2520,6 @@ impl [T] { /// /// See also [`binary_search`], [`binary_search_by`], and [`partition_point`]. /// - /// [`contains`]: slice::contains /// [`sort_by_key`]: slice::sort_by_key /// [`binary_search`]: slice::binary_search /// [`binary_search_by`]: slice::binary_search_by From eeb5b782a613b37c13bfd39588a3e3ae6dcf0ff5 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 30 Mar 2023 10:57:44 +1100 Subject: [PATCH 272/346] Improve the `rustc_data_structures::sync` module doc comment. Also, `MTRef<'a, T>` is a typedef for a reference to a `T`, but in practice it's only used (and useful) in combination with `MTLock`, i.e. `MTRef<'a, MTLock>`. So this commit changes it to be a typedef for a reference to an `MTLock`, and renames it as `MTLockRef`. I think this clarifies things, because I found `MTRef` quite puzzling at first. --- compiler/rustc_data_structures/src/sync.rs | 53 ++++++++++++++------ compiler/rustc_monomorphize/src/collector.rs | 10 ++-- 2 files changed, 44 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs index 31323c21df0..09765607cbd 100644 --- a/compiler/rustc_data_structures/src/sync.rs +++ b/compiler/rustc_data_structures/src/sync.rs @@ -1,21 +1,46 @@ -//! This module defines types which are thread safe if cfg!(parallel_compiler) is true. +//! This module defines various operations and types that are implemented in +//! one way for the serial compiler, and another way the parallel compiler. //! -//! `Lrc` is an alias of `Arc` if cfg!(parallel_compiler) is true, `Rc` otherwise. +//! Operations +//! ---------- +//! The parallel versions of operations use Rayon to execute code in parallel, +//! while the serial versions degenerate straightforwardly to serial execution. +//! The operations include `join`, `parallel`, `par_iter`, and `par_for_each`. //! -//! `Lock` is a mutex. -//! It internally uses `parking_lot::Mutex` if cfg!(parallel_compiler) is true, -//! `RefCell` otherwise. +//! `rustc_erase_owner!` erases an `OwningRef` owner into `Erased` for the +//! serial version and `Erased + Send + Sync` for the parallel version. //! -//! `RwLock` is a read-write lock. -//! It internally uses `parking_lot::RwLock` if cfg!(parallel_compiler) is true, -//! `RefCell` otherwise. +//! Types +//! ----- +//! The parallel versions of types provide various kinds of synchronization, +//! while the serial compiler versions do not. //! -//! `MTLock` is a mutex which disappears if cfg!(parallel_compiler) is false. +//! The following table shows how the types are implemented internally. Except +//! where noted otherwise, the type in column one is defined as a +//! newtype around the type from column two or three. //! -//! `MTRef` is an immutable reference if cfg!(parallel_compiler), and a mutable reference otherwise. +//! | Type | Serial version | Parallel version | +//! | ----------------------- | ------------------- | ------------------------------- | +//! | `Lrc` | `rc::Rc` | `sync::Arc` | +//! |` Weak` | `rc::Weak` | `sync::Weak` | +//! | | | | +//! | `AtomicBool` | `Cell` | `atomic::AtomicBool` | +//! | `AtomicU32` | `Cell` | `atomic::AtomicU32` | +//! | `AtomicU64` | `Cell` | `atomic::AtomicU64` | +//! | `AtomicUsize` | `Cell` | `atomic::AtomicUsize` | +//! | | | | +//! | `Lock` | `RefCell` | `parking_lot::Mutex` | +//! | `RwLock` | `RefCell` | `parking_lot::RwLock` | +//! | `MTLock` [^1] | `T` | `Lock` | +//! | `MTLockRef<'a, T>` [^2] | `&'a mut MTLock` | `&'a MTLock` | +//! | | | | +//! | `ParallelIterator` | `Iterator` | `rayon::iter::ParallelIterator` | //! -//! `rustc_erase_owner!` erases an OwningRef owner into Erased or Erased + Send + Sync -//! depending on the value of cfg!(parallel_compiler). +//! [^1] `MTLock` is similar to `Lock`, but the serial version avoids the cost +//! of a `RefCell`. This is appropriate when interior mutability is not +//! required. +//! +//! [^2] `MTLockRef` is a typedef. use crate::owning_ref::{Erased, OwningRef}; use std::collections::HashMap; @@ -209,7 +234,7 @@ cfg_if! { } } - pub type MTRef<'a, T> = &'a mut T; + pub type MTLockRef<'a, T> = &'a mut MTLock; #[derive(Debug, Default)] pub struct MTLock(T); @@ -267,7 +292,7 @@ cfg_if! { pub use std::sync::Arc as Lrc; pub use std::sync::Weak as Weak; - pub type MTRef<'a, T> = &'a T; + pub type MTLockRef<'a, T> = &'a MTLock; #[derive(Debug, Default)] pub struct MTLock(Lock); diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 98265d58a0a..e24d31c43d3 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -174,7 +174,7 @@ //! regardless of whether it is actually needed or not. use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_data_structures::sync::{par_for_each_in, MTLock, MTRef}; +use rustc_data_structures::sync::{par_for_each_in, MTLock, MTLockRef}; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId}; @@ -340,8 +340,8 @@ pub fn collect_crate_mono_items( let recursion_limit = tcx.recursion_limit(); { - let visited: MTRef<'_, _> = &mut visited; - let inlining_map: MTRef<'_, _> = &mut inlining_map; + let visited: MTLockRef<'_, _> = &mut visited; + let inlining_map: MTLockRef<'_, _> = &mut inlining_map; tcx.sess.time("monomorphization_collector_graph_walk", || { par_for_each_in(roots, |root| { @@ -406,10 +406,10 @@ fn collect_roots(tcx: TyCtxt<'_>, mode: MonoItemCollectionMode) -> Vec( tcx: TyCtxt<'tcx>, starting_point: Spanned>, - visited: MTRef<'_, MTLock>>>, + visited: MTLockRef<'_, FxHashSet>>, recursion_depths: &mut DefIdMap, recursion_limit: Limit, - inlining_map: MTRef<'_, MTLock>>, + inlining_map: MTLockRef<'_, InliningMap<'tcx>>, ) { if !visited.lock_mut().insert(starting_point.node) { // We've been here already, no need to search again. From 0ccb60096ac8d166c740ff1180ba33b5f7421c8f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 30 Mar 2023 13:00:28 +1100 Subject: [PATCH 273/346] Remove `RwLock::clone_guard`. It's unused. --- compiler/rustc_data_structures/src/sync.rs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs index 09765607cbd..4e2126fff7b 100644 --- a/compiler/rustc_data_structures/src/sync.rs +++ b/compiler/rustc_data_structures/src/sync.rs @@ -578,18 +578,6 @@ impl RwLock { self.write() } - #[cfg(not(parallel_compiler))] - #[inline(always)] - pub fn clone_guard<'a>(rg: &ReadGuard<'a, T>) -> ReadGuard<'a, T> { - ReadGuard::clone(rg) - } - - #[cfg(parallel_compiler)] - #[inline(always)] - pub fn clone_guard<'a>(rg: &ReadGuard<'a, T>) -> ReadGuard<'a, T> { - ReadGuard::rwlock(&rg).read() - } - #[cfg(not(parallel_compiler))] #[inline(always)] pub fn leak(&self) -> &T { From 44bfb6538e553a8da386270c7399076b3a2f725d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 30 Mar 2023 16:48:03 +1100 Subject: [PATCH 274/346] `CacheAligned` and `Sharded` don't need to derive `Clone`. --- compiler/rustc_data_structures/src/sharded.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_data_structures/src/sharded.rs b/compiler/rustc_data_structures/src/sharded.rs index 01d292dde8d..f88c055a9b5 100644 --- a/compiler/rustc_data_structures/src/sharded.rs +++ b/compiler/rustc_data_structures/src/sharded.rs @@ -5,7 +5,7 @@ use std::collections::hash_map::RawEntryMut; use std::hash::{Hash, Hasher}; use std::mem; -#[derive(Clone, Default)] +#[derive(Default)] #[cfg_attr(parallel_compiler, repr(align(64)))] struct CacheAligned(T); @@ -21,7 +21,6 @@ const SHARD_BITS: usize = 0; pub const SHARDS: usize = 1 << SHARD_BITS; /// An array of cache-line aligned inner locked structures with convenience methods. -#[derive(Clone)] pub struct Sharded { shards: [CacheAligned>; SHARDS], } From 08dec8969fe526c4419d066dc01344031a0ddc1f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 30 Mar 2023 16:53:32 +1100 Subject: [PATCH 275/346] Remove an out-of-date comment on `QueryCache::lookup`. --- compiler/rustc_query_system/src/query/caches.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/compiler/rustc_query_system/src/query/caches.rs b/compiler/rustc_query_system/src/query/caches.rs index 5f554a54dea..d3efc22a194 100644 --- a/compiler/rustc_query_system/src/query/caches.rs +++ b/compiler/rustc_query_system/src/query/caches.rs @@ -21,9 +21,6 @@ pub trait QueryCache: Sized { type Value: Copy + Debug; /// Checks if the query is already computed and in the cache. - /// It returns the shard index and a lock guard to the shard, - /// which will be used if the query is not in the cache and we need - /// to compute it. fn lookup(&self, key: &Self::Key) -> Option<(Self::Value, DepNodeIndex)>; fn complete(&self, key: Self::Key, value: Self::Value, index: DepNodeIndex); From 4b7f14149b7594fc43250e0c1d3889f5d47d9e55 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Thu, 30 Mar 2023 12:06:07 +0100 Subject: [PATCH 276/346] Fix title for openharmony.md --- src/doc/rustc/src/platform-support/openharmony.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc/src/platform-support/openharmony.md b/src/doc/rustc/src/platform-support/openharmony.md index aa4debfd45a..a8dcc644346 100644 --- a/src/doc/rustc/src/platform-support/openharmony.md +++ b/src/doc/rustc/src/platform-support/openharmony.md @@ -1,4 +1,4 @@ -# `*-linux-ohos*` +# `*-unknown-linux-ohos` **Tier: 3** From 433da1fc047bb39a263eefca4bdb2b1972f1d2ce Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 30 Mar 2023 07:34:55 -0500 Subject: [PATCH 277/346] Move almost all run-make-fulldeps to run-make They pass fine. --- .../{run-make-fulldeps => run-make}/a-b-a-linker-guard/Makefile | 0 tests/{run-make-fulldeps => run-make}/a-b-a-linker-guard/a.rs | 0 tests/{run-make-fulldeps => run-make}/a-b-a-linker-guard/b.rs | 0 .../alloc-no-oom-handling/Makefile | 0 tests/{run-make-fulldeps => run-make}/alloc-no-rc/Makefile | 0 tests/{run-make-fulldeps => run-make}/alloc-no-sync/Makefile | 0 .../allow-non-lint-warnings-cmdline/Makefile | 0 .../allow-non-lint-warnings-cmdline/foo.rs | 0 .../allow-warnings-cmdline-stability/Makefile | 0 .../allow-warnings-cmdline-stability/bar.rs | 0 .../allow-warnings-cmdline-stability/foo.rs | 0 .../archive-duplicate-names/Makefile | 0 .../archive-duplicate-names/bar.c | 0 .../archive-duplicate-names/bar.rs | 0 .../archive-duplicate-names/foo.c | 0 .../archive-duplicate-names/foo.rs | 0 .../arguments-non-c-like-enum/Makefile | 0 .../arguments-non-c-like-enum/nonclike.rs | 0 .../arguments-non-c-like-enum/test.c | 0 tests/{run-make-fulldeps => run-make}/atomic-lock-free/Makefile | 0 .../atomic-lock-free/atomic_lock_free.rs | 0 tests/{run-make-fulldeps => run-make}/bare-outfile/Makefile | 0 tests/{run-make-fulldeps => run-make}/bare-outfile/foo.rs | 0 tests/{run-make-fulldeps => run-make}/c-dynamic-dylib/Makefile | 0 tests/{run-make-fulldeps => run-make}/c-dynamic-dylib/bar.rs | 0 tests/{run-make-fulldeps => run-make}/c-dynamic-dylib/cfoo.c | 0 tests/{run-make-fulldeps => run-make}/c-dynamic-dylib/foo.rs | 0 tests/{run-make-fulldeps => run-make}/c-dynamic-rlib/Makefile | 0 tests/{run-make-fulldeps => run-make}/c-dynamic-rlib/bar.rs | 0 tests/{run-make-fulldeps => run-make}/c-dynamic-rlib/cfoo.c | 0 tests/{run-make-fulldeps => run-make}/c-dynamic-rlib/foo.rs | 0 .../c-link-to-rust-dylib/Makefile | 0 .../{run-make-fulldeps => run-make}/c-link-to-rust-dylib/bar.c | 0 .../{run-make-fulldeps => run-make}/c-link-to-rust-dylib/foo.rs | 0 .../c-link-to-rust-staticlib/Makefile | 0 .../c-link-to-rust-staticlib/bar.c | 0 .../c-link-to-rust-staticlib/foo.rs | 0 .../c-link-to-rust-va-list-fn/Makefile | 0 .../c-link-to-rust-va-list-fn/checkrust.rs | 0 .../c-link-to-rust-va-list-fn/test.c | 0 tests/{run-make-fulldeps => run-make}/c-static-dylib/Makefile | 0 tests/{run-make-fulldeps => run-make}/c-static-dylib/bar.rs | 0 tests/{run-make-fulldeps => run-make}/c-static-dylib/cfoo.c | 0 tests/{run-make-fulldeps => run-make}/c-static-dylib/foo.rs | 0 tests/{run-make-fulldeps => run-make}/c-static-rlib/Makefile | 0 tests/{run-make-fulldeps => run-make}/c-static-rlib/bar.rs | 0 tests/{run-make-fulldeps => run-make}/c-static-rlib/cfoo.c | 0 tests/{run-make-fulldeps => run-make}/c-static-rlib/foo.rs | 0 .../c-unwind-abi-catch-lib-panic/Makefile | 0 .../c-unwind-abi-catch-lib-panic/add.c | 0 .../c-unwind-abi-catch-lib-panic/main.rs | 0 .../c-unwind-abi-catch-lib-panic/panic.rs | 0 .../c-unwind-abi-catch-panic/Makefile | 0 .../c-unwind-abi-catch-panic/add.c | 0 .../c-unwind-abi-catch-panic/main.rs | 0 .../cat-and-grep-sanity-check/Makefile | 0 .../cdylib-dylib-linkage/Makefile | 0 .../{run-make-fulldeps => run-make}/cdylib-dylib-linkage/bar.rs | 0 .../{run-make-fulldeps => run-make}/cdylib-dylib-linkage/foo.c | 0 .../{run-make-fulldeps => run-make}/cdylib-dylib-linkage/foo.rs | 0 .../cdylib-fewer-symbols/Makefile | 0 .../{run-make-fulldeps => run-make}/cdylib-fewer-symbols/foo.rs | 0 tests/{run-make-fulldeps => run-make}/cdylib/Makefile | 0 tests/{run-make-fulldeps => run-make}/cdylib/bar.rs | 0 tests/{run-make-fulldeps => run-make}/cdylib/foo.c | 0 tests/{run-make-fulldeps => run-make}/cdylib/foo.rs | 0 .../codegen-options-parsing/Makefile | 0 .../codegen-options-parsing/dummy.rs | 0 tests/{run-make-fulldeps => run-make}/compile-stdin/Makefile | 0 .../compiler-lookup-paths-2/Makefile | 0 .../compiler-lookup-paths-2/a.rs | 0 .../compiler-lookup-paths-2/b.rs | 0 .../compiler-lookup-paths-2/c.rs | 0 .../compiler-lookup-paths/Makefile | 0 .../{run-make-fulldeps => run-make}/compiler-lookup-paths/a.rs | 0 .../{run-make-fulldeps => run-make}/compiler-lookup-paths/b.rs | 0 .../{run-make-fulldeps => run-make}/compiler-lookup-paths/c.rs | 0 .../{run-make-fulldeps => run-make}/compiler-lookup-paths/d.rs | 0 .../{run-make-fulldeps => run-make}/compiler-lookup-paths/e.rs | 0 .../{run-make-fulldeps => run-make}/compiler-lookup-paths/e2.rs | 0 .../{run-make-fulldeps => run-make}/compiler-lookup-paths/f.rs | 0 .../compiler-lookup-paths/native.c | 0 .../compiler-rt-works-on-mingw/Makefile | 0 .../compiler-rt-works-on-mingw/foo.cpp | 0 .../compiler-rt-works-on-mingw/foo.rs | 0 .../core-no-fp-fmt-parse/Makefile | 0 tests/{run-make-fulldeps => run-make}/crate-data-smoke/Makefile | 0 tests/{run-make-fulldeps => run-make}/crate-data-smoke/crate.rs | 0 tests/{run-make-fulldeps => run-make}/crate-data-smoke/lib.rs | 0 tests/{run-make-fulldeps => run-make}/crate-data-smoke/rlib.rs | 0 .../crate-hash-rustc-version/Makefile | 0 .../crate-hash-rustc-version/a.rs | 0 .../crate-hash-rustc-version/b.rs | 0 .../crate-name-priority/Makefile | 0 .../{run-make-fulldeps => run-make}/crate-name-priority/foo.rs | 0 .../{run-make-fulldeps => run-make}/crate-name-priority/foo1.rs | 0 .../cross-lang-lto-clang/Makefile | 0 .../{run-make-fulldeps => run-make}/cross-lang-lto-clang/clib.c | 0 .../cross-lang-lto-clang/cmain.c | 0 .../cross-lang-lto-clang/main.rs | 0 .../cross-lang-lto-clang/rustlib.rs | 0 .../cross-lang-lto-pgo-smoketest/Makefile | 0 .../cross-lang-lto-pgo-smoketest/clib.c | 0 .../cross-lang-lto-pgo-smoketest/cmain.c | 0 .../cross-lang-lto-pgo-smoketest/main.rs | 0 .../cross-lang-lto-pgo-smoketest/rustlib.rs | 0 .../cross-lang-lto-upstream-rlibs/Makefile | 0 .../cross-lang-lto-upstream-rlibs/staticlib.rs | 0 .../cross-lang-lto-upstream-rlibs/upstream.rs | 0 tests/{run-make-fulldeps => run-make}/cross-lang-lto/Makefile | 0 tests/{run-make-fulldeps => run-make}/cross-lang-lto/lib.rs | 0 tests/{run-make-fulldeps => run-make}/cross-lang-lto/main.rs | 0 tests/{run-make-fulldeps => run-make}/debug-assertions/Makefile | 0 tests/{run-make-fulldeps => run-make}/debug-assertions/debug.rs | 0 .../dep-info-doesnt-run-much/Makefile | 0 .../dep-info-doesnt-run-much/foo.rs | 0 tests/{run-make-fulldeps => run-make}/dep-info-spaces/Makefile | 0 .../dep-info-spaces/Makefile.foo | 0 tests/{run-make-fulldeps => run-make}/dep-info-spaces/bar.rs | 0 .../{run-make-fulldeps => run-make}/dep-info-spaces/foo foo.rs | 0 tests/{run-make-fulldeps => run-make}/dep-info-spaces/lib.rs | 0 tests/{run-make-fulldeps => run-make}/dep-info/Makefile | 0 tests/{run-make-fulldeps => run-make}/dep-info/Makefile.foo | 0 tests/{run-make-fulldeps => run-make}/dep-info/bar.rs | 0 tests/{run-make-fulldeps => run-make}/dep-info/foo.rs | 0 tests/{run-make-fulldeps => run-make}/dep-info/lib.rs | 0 tests/{run-make-fulldeps => run-make}/dep-info/lib2.rs | 0 .../doctests-keep-binaries/Makefile | 0 .../{run-make-fulldeps => run-make}/doctests-keep-binaries/t.rs | 0 .../duplicate-output-flavors/Makefile | 0 .../duplicate-output-flavors/foo.rs | 0 tests/{run-make-fulldeps => run-make}/dylib-chain/Makefile | 0 tests/{run-make-fulldeps => run-make}/dylib-chain/m1.rs | 0 tests/{run-make-fulldeps => run-make}/dylib-chain/m2.rs | 0 tests/{run-make-fulldeps => run-make}/dylib-chain/m3.rs | 0 tests/{run-make-fulldeps => run-make}/dylib-chain/m4.rs | 0 tests/{run-make-fulldeps => run-make}/emit-stack-sizes/Makefile | 0 tests/{run-make-fulldeps => run-make}/emit-stack-sizes/foo.rs | 0 tests/{run-make-fulldeps => run-make}/emit/Makefile | 0 tests/{run-make-fulldeps => run-make}/emit/test-24876.rs | 0 tests/{run-make-fulldeps => run-make}/emit/test-26235.rs | 0 .../error-found-staticlib-instead-crate/Makefile | 0 .../error-found-staticlib-instead-crate/bar.rs | 0 .../error-found-staticlib-instead-crate/foo.rs | 0 .../error-writing-dependencies/Makefile | 0 .../error-writing-dependencies/foo.rs | 0 tests/{run-make-fulldeps => run-make}/exit-code/Makefile | 0 .../{run-make-fulldeps => run-make}/exit-code/compile-error.rs | 0 tests/{run-make-fulldeps => run-make}/exit-code/lint-failure.rs | 0 tests/{run-make-fulldeps => run-make}/exit-code/success.rs | 0 .../extern-diff-internal-name/Makefile | 0 .../extern-diff-internal-name/lib.rs | 0 .../extern-diff-internal-name/test.rs | 0 .../extern-flag-disambiguates/Makefile | 0 .../extern-flag-disambiguates/a.rs | 0 .../extern-flag-disambiguates/b.rs | 0 .../extern-flag-disambiguates/c.rs | 0 .../extern-flag-disambiguates/d.rs | 0 tests/{run-make-fulldeps => run-make}/extern-flag-fun/Makefile | 0 .../{run-make-fulldeps => run-make}/extern-flag-fun/bar-alt.rs | 0 tests/{run-make-fulldeps => run-make}/extern-flag-fun/bar.rs | 0 tests/{run-make-fulldeps => run-make}/extern-flag-fun/foo.rs | 0 .../extern-flag-fun/gated_unstable.rs | 0 tests/{run-make-fulldeps => run-make}/extern-flag-fun/rustc.rs | 0 .../extern-flag-pathless/Makefile | 0 .../extern-flag-pathless/bar-dynamic.rs | 0 .../extern-flag-pathless/bar-static.rs | 0 .../{run-make-fulldeps => run-make}/extern-flag-pathless/foo.rs | 0 .../extern-flag-rename-transitive/Makefile | 0 .../extern-flag-rename-transitive/bar.rs | 0 .../extern-flag-rename-transitive/baz.rs | 0 .../extern-flag-rename-transitive/foo.rs | 0 .../{run-make-fulldeps => run-make}/extern-fn-generic/Makefile | 0 tests/{run-make-fulldeps => run-make}/extern-fn-generic/test.c | 0 tests/{run-make-fulldeps => run-make}/extern-fn-generic/test.rs | 0 .../extern-fn-generic/testcrate.rs | 0 tests/{run-make-fulldeps => run-make}/extern-fn-mangle/Makefile | 0 tests/{run-make-fulldeps => run-make}/extern-fn-mangle/test.c | 0 tests/{run-make-fulldeps => run-make}/extern-fn-mangle/test.rs | 0 .../extern-fn-reachable/Makefile | 0 .../extern-fn-reachable/dylib.rs | 0 .../extern-fn-struct-passing-abi/Makefile | 0 .../extern-fn-struct-passing-abi/test.c | 0 .../extern-fn-struct-passing-abi/test.rs | 0 .../extern-fn-with-extern-types/Makefile | 0 .../extern-fn-with-extern-types/ctest.c | 0 .../extern-fn-with-extern-types/test.rs | 0 .../extern-fn-with-packed-struct/Makefile | 0 .../extern-fn-with-packed-struct/test.c | 0 .../extern-fn-with-packed-struct/test.rs | 0 .../extern-fn-with-union/Makefile | 0 .../extern-fn-with-union/ctest.c | 0 .../extern-fn-with-union/test.rs | 0 .../extern-fn-with-union/testcrate.rs | 0 .../extern-multiple-copies/Makefile | 0 .../extern-multiple-copies/bar.rs | 0 .../extern-multiple-copies/foo1.rs | 0 .../extern-multiple-copies/foo2.rs | 0 .../extern-multiple-copies2/Makefile | 0 .../extern-multiple-copies2/bar.rs | 0 .../extern-multiple-copies2/foo1.rs | 0 .../extern-multiple-copies2/foo2.rs | 0 .../extern-overrides-distribution/Makefile | 0 .../extern-overrides-distribution/libc.rs | 0 .../extern-overrides-distribution/main.rs | 0 .../extra-filename-with-temp-outputs/Makefile | 0 .../extra-filename-with-temp-outputs/foo.rs | 0 .../foreign-double-unwind/Makefile | 0 .../foreign-double-unwind/foo.cpp | 0 .../foreign-double-unwind/foo.rs | 0 .../{run-make-fulldeps => run-make}/foreign-exceptions/Makefile | 0 .../{run-make-fulldeps => run-make}/foreign-exceptions/foo.cpp | 0 tests/{run-make-fulldeps => run-make}/foreign-exceptions/foo.rs | 0 .../foreign-rust-exceptions/Makefile | 0 .../foreign-rust-exceptions/bar.rs | 0 .../foreign-rust-exceptions/foo.rs | 0 tests/{run-make-fulldeps => run-make}/fpic/Makefile | 0 tests/{run-make-fulldeps => run-make}/fpic/hello.rs | 0 .../glibc-staticlib-args/Makefile | 0 .../glibc-staticlib-args/library.rs | 0 .../glibc-staticlib-args/program.c | 0 tests/{run-make-fulldeps => run-make}/hir-tree/Makefile | 0 tests/{run-make-fulldeps => run-make}/hir-tree/input.rs | 0 .../hotplug_codegen_backend/Makefile | 0 .../hotplug_codegen_backend/some_crate.rs | 0 .../hotplug_codegen_backend/the_backend.rs | 0 .../{run-make-fulldeps => run-make}/include_bytes_deps/Makefile | 0 .../include_bytes_deps/input.bin | 0 .../{run-make-fulldeps => run-make}/include_bytes_deps/input.md | 0 .../include_bytes_deps/input.txt | 0 .../{run-make-fulldeps => run-make}/include_bytes_deps/main.rs | 0 .../incr-add-rust-src-component/Makefile | 0 .../incr-add-rust-src-component/main.rs | 0 .../inline-always-many-cgu/Makefile | 0 .../inline-always-many-cgu/foo.rs | 0 .../interdependent-c-libraries/Makefile | 0 .../interdependent-c-libraries/bar.c | 0 .../interdependent-c-libraries/bar.rs | 0 .../interdependent-c-libraries/foo.c | 0 .../interdependent-c-libraries/foo.rs | 0 .../interdependent-c-libraries/main.rs | 0 .../intrinsic-unreachable/Makefile | 0 .../intrinsic-unreachable/exit-ret.rs | 0 .../intrinsic-unreachable/exit-unreachable.rs | 0 tests/{run-make-fulldeps => run-make}/invalid-library/Makefile | 0 tests/{run-make-fulldeps => run-make}/invalid-library/foo.rs | 0 .../{run-make-fulldeps => run-make}/invalid-staticlib/Makefile | 0 tests/{run-make-fulldeps => run-make}/issue-11908/Makefile | 0 tests/{run-make-fulldeps => run-make}/issue-11908/bar.rs | 0 tests/{run-make-fulldeps => run-make}/issue-11908/foo.rs | 0 tests/{run-make-fulldeps => run-make}/issue-14500/Makefile | 0 tests/{run-make-fulldeps => run-make}/issue-14500/bar.rs | 0 tests/{run-make-fulldeps => run-make}/issue-14500/foo.c | 0 tests/{run-make-fulldeps => run-make}/issue-14500/foo.rs | 0 tests/{run-make-fulldeps => run-make}/issue-14698/Makefile | 0 tests/{run-make-fulldeps => run-make}/issue-14698/foo.rs | 0 tests/{run-make-fulldeps => run-make}/issue-15460/Makefile | 0 tests/{run-make-fulldeps => run-make}/issue-15460/bar.rs | 0 tests/{run-make-fulldeps => run-make}/issue-15460/foo.c | 0 tests/{run-make-fulldeps => run-make}/issue-15460/foo.rs | 0 tests/{run-make-fulldeps => run-make}/issue-18943/Makefile | 0 tests/{run-make-fulldeps => run-make}/issue-18943/foo.rs | 0 tests/{run-make-fulldeps => run-make}/issue-20626/Makefile | 0 tests/{run-make-fulldeps => run-make}/issue-20626/foo.rs | 0 tests/{run-make-fulldeps => run-make}/issue-22131/Makefile | 0 tests/{run-make-fulldeps => run-make}/issue-22131/foo.rs | 0 tests/{run-make-fulldeps => run-make}/issue-24445/Makefile | 0 tests/{run-make-fulldeps => run-make}/issue-24445/foo.c | 0 tests/{run-make-fulldeps => run-make}/issue-24445/foo.rs | 0 tests/{run-make-fulldeps => run-make}/issue-25581/Makefile | 0 tests/{run-make-fulldeps => run-make}/issue-25581/test.c | 0 tests/{run-make-fulldeps => run-make}/issue-25581/test.rs | 0 tests/{run-make-fulldeps => run-make}/issue-26006/Makefile | 0 .../{run-make-fulldeps => run-make}/issue-26006/in/libc/lib.rs | 0 .../{run-make-fulldeps => run-make}/issue-26006/in/time/lib.rs | 0 tests/{run-make-fulldeps => run-make}/issue-26092/Makefile | 0 tests/{run-make-fulldeps => run-make}/issue-26092/blank.rs | 0 tests/{run-make-fulldeps => run-make}/issue-28595/Makefile | 0 tests/{run-make-fulldeps => run-make}/issue-28595/a.c | 0 tests/{run-make-fulldeps => run-make}/issue-28595/a.rs | 0 tests/{run-make-fulldeps => run-make}/issue-28595/b.c | 0 tests/{run-make-fulldeps => run-make}/issue-28595/b.rs | 0 tests/{run-make-fulldeps => run-make}/issue-28766/Makefile | 0 tests/{run-make-fulldeps => run-make}/issue-28766/foo.rs | 0 tests/{run-make-fulldeps => run-make}/issue-28766/main.rs | 0 tests/{run-make-fulldeps => run-make}/issue-30063/Makefile | 0 tests/{run-make-fulldeps => run-make}/issue-30063/foo.rs | 0 tests/{run-make-fulldeps => run-make}/issue-33329/Makefile | 0 tests/{run-make-fulldeps => run-make}/issue-33329/main.rs | 0 tests/{run-make-fulldeps => run-make}/issue-35164/Makefile | 0 tests/{run-make-fulldeps => run-make}/issue-35164/main.rs | 0 .../issue-35164/submodule/mod.rs | 0 tests/{run-make-fulldeps => run-make}/issue-37839/Makefile | 0 tests/{run-make-fulldeps => run-make}/issue-37839/a.rs | 0 tests/{run-make-fulldeps => run-make}/issue-37839/b.rs | 0 tests/{run-make-fulldeps => run-make}/issue-37839/c.rs | 0 tests/{run-make-fulldeps => run-make}/issue-37893/Makefile | 0 tests/{run-make-fulldeps => run-make}/issue-37893/a.rs | 0 tests/{run-make-fulldeps => run-make}/issue-37893/b.rs | 0 tests/{run-make-fulldeps => run-make}/issue-37893/c.rs | 0 tests/{run-make-fulldeps => run-make}/issue-38237/Makefile | 0 tests/{run-make-fulldeps => run-make}/issue-38237/bar.rs | 0 tests/{run-make-fulldeps => run-make}/issue-38237/baz.rs | 0 tests/{run-make-fulldeps => run-make}/issue-38237/foo.rs | 0 tests/{run-make-fulldeps => run-make}/issue-40535/Makefile | 0 tests/{run-make-fulldeps => run-make}/issue-40535/bar.rs | 0 tests/{run-make-fulldeps => run-make}/issue-40535/baz.rs | 0 tests/{run-make-fulldeps => run-make}/issue-40535/foo.rs | 0 tests/{run-make-fulldeps => run-make}/issue-46239/Makefile | 0 tests/{run-make-fulldeps => run-make}/issue-46239/main.rs | 0 tests/{run-make-fulldeps => run-make}/issue-47551/Makefile | 0 .../issue-47551/eh_frame-terminator.rs | 0 tests/{run-make-fulldeps => run-make}/issue-51671/Makefile | 0 tests/{run-make-fulldeps => run-make}/issue-51671/app.rs | 0 tests/{run-make-fulldeps => run-make}/issue-53964/Makefile | 0 tests/{run-make-fulldeps => run-make}/issue-53964/app.rs | 0 tests/{run-make-fulldeps => run-make}/issue-53964/panic.rs | 0 tests/{run-make-fulldeps => run-make}/issue-64153/Makefile | 0 tests/{run-make-fulldeps => run-make}/issue-64153/downstream.rs | 0 tests/{run-make-fulldeps => run-make}/issue-64153/upstream.rs | 0 .../issue-68794-textrel-on-minimal-lib/Makefile | 0 .../issue-68794-textrel-on-minimal-lib/bar.c | 0 .../issue-68794-textrel-on-minimal-lib/foo.rs | 0 tests/{run-make-fulldeps => run-make}/issue-69368/Makefile | 0 tests/{run-make-fulldeps => run-make}/issue-69368/a.rs | 0 tests/{run-make-fulldeps => run-make}/issue-69368/b.rs | 0 tests/{run-make-fulldeps => run-make}/issue-69368/c.rs | 0 tests/{run-make-fulldeps => run-make}/issue-7349/Makefile | 0 tests/{run-make-fulldeps => run-make}/issue-7349/foo.rs | 0 tests/{run-make-fulldeps => run-make}/issue-83045/Makefile | 0 tests/{run-make-fulldeps => run-make}/issue-83045/a.rs | 0 tests/{run-make-fulldeps => run-make}/issue-83045/b.rs | 0 tests/{run-make-fulldeps => run-make}/issue-83045/c.rs | 0 .../issue-84395-lto-embed-bitcode/Makefile | 0 .../issue-84395-lto-embed-bitcode/test.rs | 0 .../issue-97463-abi-param-passing/Makefile | 0 .../issue-97463-abi-param-passing/bad.c | 0 .../issue-97463-abi-param-passing/param_passing.rs | 0 tests/{run-make-fulldeps => run-make}/issue64319/Makefile | 0 tests/{run-make-fulldeps => run-make}/issue64319/bar.rs | 0 tests/{run-make-fulldeps => run-make}/issue64319/foo.rs | 0 .../libs-through-symlinks/Makefile | 0 .../libs-through-symlinks/bar.rs | 0 .../libs-through-symlinks/foo.rs | 0 tests/{run-make-fulldeps => run-make}/libtest-json/Makefile | 0 tests/{run-make-fulldeps => run-make}/libtest-json/f.rs | 0 .../libtest-json/output-default.json | 0 .../libtest-json/output-stdout-success.json | 0 .../libtest-json/validate_json.py | 0 tests/{run-make-fulldeps => run-make}/link-arg/Makefile | 0 tests/{run-make-fulldeps => run-make}/link-arg/empty.rs | 0 tests/{run-make-fulldeps => run-make}/link-args-order/Makefile | 0 tests/{run-make-fulldeps => run-make}/link-args-order/empty.rs | 0 tests/{run-make-fulldeps => run-make}/link-cfg/Makefile | 0 .../link-cfg/dep-with-staticlib.rs | 0 tests/{run-make-fulldeps => run-make}/link-cfg/dep.rs | 0 tests/{run-make-fulldeps => run-make}/link-cfg/no-deps.rs | 0 tests/{run-make-fulldeps => run-make}/link-cfg/return1.c | 0 tests/{run-make-fulldeps => run-make}/link-cfg/return2.c | 0 tests/{run-make-fulldeps => run-make}/link-cfg/return3.c | 0 tests/{run-make-fulldeps => run-make}/link-cfg/with-deps.rs | 0 .../link-cfg/with-staticlib-deps.rs | 0 tests/{run-make-fulldeps => run-make}/link-dedup/Makefile | 0 tests/{run-make-fulldeps => run-make}/link-dedup/depa.rs | 0 tests/{run-make-fulldeps => run-make}/link-dedup/depb.rs | 0 tests/{run-make-fulldeps => run-make}/link-dedup/depc.rs | 0 tests/{run-make-fulldeps => run-make}/link-dedup/empty.rs | 0 tests/{run-make-fulldeps => run-make}/link-path-order/Makefile | 0 tests/{run-make-fulldeps => run-make}/link-path-order/correct.c | 0 tests/{run-make-fulldeps => run-make}/link-path-order/main.rs | 0 tests/{run-make-fulldeps => run-make}/link-path-order/wrong.c | 0 .../linkage-attr-on-static/Makefile | 0 .../linkage-attr-on-static/bar.rs | 0 .../linkage-attr-on-static/foo.c | 0 .../long-linker-command-lines-cmd-exe/Makefile | 0 .../long-linker-command-lines-cmd-exe/foo.bat | 0 .../long-linker-command-lines-cmd-exe/foo.rs | 0 .../long-linker-command-lines/Makefile | 0 .../long-linker-command-lines/foo.rs | 0 .../longjmp-across-rust/Makefile | 0 tests/{run-make-fulldeps => run-make}/longjmp-across-rust/foo.c | 0 .../{run-make-fulldeps => run-make}/longjmp-across-rust/main.rs | 0 tests/{run-make-fulldeps => run-make}/ls-metadata/Makefile | 0 tests/{run-make-fulldeps => run-make}/ls-metadata/foo.rs | 0 tests/{run-make-fulldeps => run-make}/lto-dylib-dep/Makefile | 0 tests/{run-make-fulldeps => run-make}/lto-dylib-dep/a_dylib.rs | 0 tests/{run-make-fulldeps => run-make}/lto-dylib-dep/main.rs | 0 tests/{run-make-fulldeps => run-make}/lto-empty/Makefile | 0 tests/{run-make-fulldeps => run-make}/lto-empty/lib.rs | 0 .../lto-no-link-whole-rlib/Makefile | 0 .../lto-no-link-whole-rlib/bar.c | 0 .../lto-no-link-whole-rlib/foo.c | 0 .../lto-no-link-whole-rlib/lib1.rs | 0 .../lto-no-link-whole-rlib/lib2.rs | 0 .../lto-no-link-whole-rlib/main.rs | 0 tests/{run-make-fulldeps => run-make}/lto-readonly-lib/Makefile | 0 tests/{run-make-fulldeps => run-make}/lto-readonly-lib/lib.rs | 0 tests/{run-make-fulldeps => run-make}/lto-readonly-lib/main.rs | 0 tests/{run-make-fulldeps => run-make}/lto-smoke-c/Makefile | 0 tests/{run-make-fulldeps => run-make}/lto-smoke-c/bar.c | 0 tests/{run-make-fulldeps => run-make}/lto-smoke-c/foo.rs | 0 tests/{run-make-fulldeps => run-make}/lto-smoke/Makefile | 0 tests/{run-make-fulldeps => run-make}/lto-smoke/lib.rs | 0 tests/{run-make-fulldeps => run-make}/lto-smoke/main.rs | 0 .../{run-make-fulldeps => run-make}/manual-crate-name/Makefile | 0 tests/{run-make-fulldeps => run-make}/manual-crate-name/bar.rs | 0 tests/{run-make-fulldeps => run-make}/manual-link/Makefile | 0 tests/{run-make-fulldeps => run-make}/manual-link/bar.c | 0 tests/{run-make-fulldeps => run-make}/manual-link/foo.c | 0 tests/{run-make-fulldeps => run-make}/manual-link/foo.rs | 0 tests/{run-make-fulldeps => run-make}/manual-link/main.rs | 0 .../many-crates-but-no-match/Makefile | 0 .../many-crates-but-no-match/crateA1.rs | 0 .../many-crates-but-no-match/crateA2.rs | 0 .../many-crates-but-no-match/crateA3.rs | 0 .../many-crates-but-no-match/crateB.rs | 0 .../many-crates-but-no-match/crateC.rs | 0 .../metadata-flag-frobs-symbols/Makefile | 0 .../metadata-flag-frobs-symbols/bar.rs | 0 .../metadata-flag-frobs-symbols/foo.rs | 0 tests/{run-make-fulldeps => run-make}/min-global-align/Makefile | 0 .../min-global-align/min_global_align.rs | 0 .../mingw-export-call-convention/Makefile | 0 .../mingw-export-call-convention/foo.rs | 0 .../mismatching-target-triples/Makefile | 0 .../mismatching-target-triples/bar.rs | 0 .../mismatching-target-triples/foo.rs | 0 .../missing-crate-dependency/Makefile | 0 .../missing-crate-dependency/crateA.rs | 0 .../missing-crate-dependency/crateB.rs | 0 .../missing-crate-dependency/crateC.rs | 0 tests/{run-make-fulldeps => run-make}/mixing-deps/Makefile | 0 tests/{run-make-fulldeps => run-make}/mixing-deps/both.rs | 0 tests/{run-make-fulldeps => run-make}/mixing-deps/dylib.rs | 0 tests/{run-make-fulldeps => run-make}/mixing-deps/prog.rs | 0 tests/{run-make-fulldeps => run-make}/mixing-formats/Makefile | 0 tests/{run-make-fulldeps => run-make}/mixing-formats/bar1.rs | 0 tests/{run-make-fulldeps => run-make}/mixing-formats/bar2.rs | 0 tests/{run-make-fulldeps => run-make}/mixing-formats/baz.rs | 0 tests/{run-make-fulldeps => run-make}/mixing-formats/baz2.rs | 0 tests/{run-make-fulldeps => run-make}/mixing-formats/foo.rs | 0 tests/{run-make-fulldeps => run-make}/mixing-libs/Makefile | 0 tests/{run-make-fulldeps => run-make}/mixing-libs/dylib.rs | 0 tests/{run-make-fulldeps => run-make}/mixing-libs/prog.rs | 0 tests/{run-make-fulldeps => run-make}/mixing-libs/rlib.rs | 0 tests/{run-make-fulldeps => run-make}/msvc-opt-minsize/Makefile | 0 tests/{run-make-fulldeps => run-make}/msvc-opt-minsize/foo.rs | 0 tests/{run-make-fulldeps => run-make}/multiple-emits/Makefile | 0 tests/{run-make-fulldeps => run-make}/multiple-emits/foo.rs | 0 tests/{run-make-fulldeps => run-make}/no-builtins-lto/Makefile | 0 tests/{run-make-fulldeps => run-make}/no-builtins-lto/main.rs | 0 .../no-builtins-lto/no_builtins.rs | 0 .../{run-make-fulldeps => run-make}/no-duplicate-libs/Makefile | 0 tests/{run-make-fulldeps => run-make}/no-duplicate-libs/bar.c | 0 tests/{run-make-fulldeps => run-make}/no-duplicate-libs/foo.c | 0 tests/{run-make-fulldeps => run-make}/no-duplicate-libs/main.rs | 0 .../no-intermediate-extras/Makefile | 0 .../no-intermediate-extras/foo.rs | 0 .../obey-crate-type-flag/Makefile | 0 .../obey-crate-type-flag/test.rs | 0 .../output-filename-conflicts-with-directory/Makefile | 0 .../output-filename-conflicts-with-directory/foo.rs | 0 .../output-filename-overwrites-input/Makefile | 0 .../output-filename-overwrites-input/bar.rs | 0 .../output-filename-overwrites-input/foo.rs | 0 .../output-type-permutations/Makefile | 0 .../output-type-permutations/foo.rs | 0 .../output-with-hyphens/Makefile | 0 .../output-with-hyphens/foo-bar.rs | 0 .../override-aliased-flags/Makefile | 0 .../override-aliased-flags/main.rs | 0 .../panic-impl-transitive/Makefile | 0 .../panic-impl-transitive/panic-impl-consumer.rs | 0 .../panic-impl-transitive/panic-impl-provider.rs | 0 .../pass-non-c-like-enum-to-c/Makefile | 0 .../pass-non-c-like-enum-to-c/nonclike.rs | 0 .../pass-non-c-like-enum-to-c/test.c | 0 .../{run-make-fulldeps => run-make}/pgo-branch-weights/Makefile | 0 .../pgo-branch-weights/filecheck-patterns.txt | 0 .../pgo-branch-weights/interesting.rs | 0 .../{run-make-fulldeps => run-make}/pgo-branch-weights/main.rs | 0 .../pgo-branch-weights/opaque.rs | 0 tests/{run-make-fulldeps => run-make}/pgo-gen-lto/Makefile | 0 tests/{run-make-fulldeps => run-make}/pgo-gen-lto/test.rs | 0 .../pgo-gen-no-imp-symbols/Makefile | 0 .../pgo-gen-no-imp-symbols/test.rs | 0 tests/{run-make-fulldeps => run-make}/pgo-gen/Makefile | 0 tests/{run-make-fulldeps => run-make}/pgo-gen/test.rs | 0 .../pgo-indirect-call-promotion/Makefile | 0 .../pgo-indirect-call-promotion/filecheck-patterns.txt | 0 .../pgo-indirect-call-promotion/interesting.rs | 0 .../pgo-indirect-call-promotion/main.rs | 0 .../pgo-indirect-call-promotion/opaque.rs | 0 tests/{run-make-fulldeps => run-make}/pgo-use/Makefile | 0 .../pgo-use/filecheck-patterns.txt | 0 tests/{run-make-fulldeps => run-make}/pgo-use/main.rs | 0 .../pointer-auth-link-with-c/Makefile | 0 .../pointer-auth-link-with-c/test.c | 0 .../pointer-auth-link-with-c/test.rs | 0 tests/{run-make-fulldeps => run-make}/prefer-dylib/Makefile | 0 tests/{run-make-fulldeps => run-make}/prefer-dylib/bar.rs | 0 tests/{run-make-fulldeps => run-make}/prefer-dylib/foo.rs | 0 tests/{run-make-fulldeps => run-make}/prefer-rlib/Makefile | 0 tests/{run-make-fulldeps => run-make}/prefer-rlib/bar.rs | 0 tests/{run-make-fulldeps => run-make}/prefer-rlib/foo.rs | 0 .../pretty-print-to-file/Makefile | 0 .../pretty-print-to-file/input.pp | 0 .../pretty-print-to-file/input.rs | 0 .../print-calling-conventions/Makefile | 0 tests/{run-make-fulldeps => run-make}/print-cfg/Makefile | 0 .../{run-make-fulldeps => run-make}/print-target-list/Makefile | 0 tests/{run-make-fulldeps => run-make}/profile/Makefile | 0 tests/{run-make-fulldeps => run-make}/profile/test.rs | 0 tests/{run-make-fulldeps => run-make}/prune-link-args/Makefile | 0 tests/{run-make-fulldeps => run-make}/prune-link-args/empty.rs | 0 tests/{run-make-fulldeps => run-make}/redundant-libs/Makefile | 0 tests/{run-make-fulldeps => run-make}/redundant-libs/bar.c | 0 tests/{run-make-fulldeps => run-make}/redundant-libs/baz.c | 0 tests/{run-make-fulldeps => run-make}/redundant-libs/foo.c | 0 tests/{run-make-fulldeps => run-make}/redundant-libs/main.rs | 0 tests/{run-make-fulldeps => run-make}/relocation-model/Makefile | 0 tests/{run-make-fulldeps => run-make}/relocation-model/foo.rs | 0 tests/{run-make-fulldeps => run-make}/relro-levels/Makefile | 0 tests/{run-make-fulldeps => run-make}/relro-levels/hello.rs | 0 .../{run-make-fulldeps => run-make}/remap-path-prefix/Makefile | 0 .../remap-path-prefix/auxiliary/lib.rs | 0 .../reproducible-build-2/Makefile | 0 .../reproducible-build-2/linker.rs | 0 .../reproducible-build-2/reproducible-build-aux.rs | 0 .../reproducible-build-2/reproducible-build.rs | 0 .../{run-make-fulldeps => run-make}/reproducible-build/Makefile | 0 .../reproducible-build/linker.rs | 0 .../reproducible-build/reproducible-build-aux.rs | 0 .../reproducible-build/reproducible-build.rs | 0 tests/{run-make-fulldeps => run-make}/resolve-rename/Makefile | 0 tests/{run-make-fulldeps => run-make}/resolve-rename/bar.rs | 0 tests/{run-make-fulldeps => run-make}/resolve-rename/baz.rs | 0 tests/{run-make-fulldeps => run-make}/resolve-rename/foo.rs | 0 .../return-non-c-like-enum-from-c/Makefile | 0 .../return-non-c-like-enum-from-c/nonclike.rs | 0 .../return-non-c-like-enum-from-c/test.c | 0 .../return-non-c-like-enum/Makefile | 0 .../return-non-c-like-enum/nonclike.rs | 0 .../return-non-c-like-enum/test.c | 0 tests/{run-make-fulldeps => run-make}/rlib-chain/Makefile | 0 tests/{run-make-fulldeps => run-make}/rlib-chain/m1.rs | 0 tests/{run-make-fulldeps => run-make}/rlib-chain/m2.rs | 0 tests/{run-make-fulldeps => run-make}/rlib-chain/m3.rs | 0 tests/{run-make-fulldeps => run-make}/rlib-chain/m4.rs | 0 tests/run-make/rlib-format-packed-bundled-libs/Makefile | 2 +- .../rustdoc-determinism/Makefile | 0 .../{run-make-fulldeps => run-make}/rustdoc-determinism/bar.rs | 0 .../{run-make-fulldeps => run-make}/rustdoc-determinism/foo.rs | 0 .../rustdoc-error-lines/Makefile | 0 .../rustdoc-error-lines/input.rs | 0 tests/{run-make-fulldeps => run-make}/rustdoc-io-error/Makefile | 0 tests/{run-make-fulldeps => run-make}/rustdoc-io-error/foo.rs | 0 tests/{run-make-fulldeps => run-make}/rustdoc-map-file/Makefile | 0 .../rustdoc-map-file/expected.json | 0 tests/{run-make-fulldeps => run-make}/rustdoc-map-file/foo.rs | 0 .../rustdoc-map-file/validate_json.py | 0 .../rustdoc-output-path/Makefile | 0 .../{run-make-fulldeps => run-make}/rustdoc-output-path/foo.rs | 0 .../rustdoc-scrape-examples-macros/Makefile | 2 +- .../rustdoc-scrape-examples-macros/examples/ex.rs | 0 .../rustdoc-scrape-examples-macros/src/lib.rs | 0 .../rustdoc-scrape-examples-macros/src/proc.rs | 0 .../rustdoc-target-spec-json-path/Makefile | 0 .../rustdoc-target-spec-json-path/dummy_core.rs | 0 .../rustdoc-target-spec-json-path/my_crate.rs | 0 .../rustdoc-target-spec-json-path/target.json | 0 tests/{run-make-fulldeps => run-make}/rustdoc-themes/Makefile | 0 tests/{run-make-fulldeps => run-make}/rustdoc-themes/foo.rs | 0 .../sanitizer-cdylib-link/Makefile | 0 .../sanitizer-cdylib-link/library.rs | 0 .../sanitizer-cdylib-link/program.rs | 0 .../sanitizer-dylib-link/Makefile | 0 .../sanitizer-dylib-link/library.rs | 0 .../sanitizer-dylib-link/program.rs | 0 .../sanitizer-staticlib-link/Makefile | 0 .../sanitizer-staticlib-link/library.rs | 0 .../sanitizer-staticlib-link/program.c | 0 .../sanitizer-staticlib-link/program.rs | 0 .../{run-make-fulldeps => run-make}/separate-link-fail/Makefile | 0 tests/{run-make-fulldeps => run-make}/separate-link/Makefile | 0 .../{run-make-fulldeps => run-make}/sepcomp-cci-copies/Makefile | 0 .../sepcomp-cci-copies/cci_lib.rs | 0 tests/{run-make-fulldeps => run-make}/sepcomp-cci-copies/foo.rs | 0 tests/{run-make-fulldeps => run-make}/sepcomp-inlining/Makefile | 0 tests/{run-make-fulldeps => run-make}/sepcomp-inlining/foo.rs | 0 tests/{run-make-fulldeps => run-make}/sepcomp-separate/Makefile | 0 tests/{run-make-fulldeps => run-make}/sepcomp-separate/foo.rs | 0 .../share-generics-dylib/Makefile | 0 .../share-generics-dylib/instance_provider_a.rs | 0 .../share-generics-dylib/instance_provider_b.rs | 0 .../share-generics-dylib/instance_user_a_rlib.rs | 0 .../share-generics-dylib/instance_user_b_rlib.rs | 0 .../share-generics-dylib/instance_user_dylib.rs | 0 .../share-generics-dylib/linked_leaf.rs | 0 tests/{run-make-fulldeps => run-make}/simd-ffi/Makefile | 0 tests/{run-make-fulldeps => run-make}/simd-ffi/simd.rs | 0 tests/{run-make-fulldeps => run-make}/simple-dylib/Makefile | 0 tests/{run-make-fulldeps => run-make}/simple-dylib/bar.rs | 0 tests/{run-make-fulldeps => run-make}/simple-dylib/foo.rs | 0 tests/{run-make-fulldeps => run-make}/simple-rlib/Makefile | 0 tests/{run-make-fulldeps => run-make}/simple-rlib/bar.rs | 0 tests/{run-make-fulldeps => run-make}/simple-rlib/foo.rs | 0 tests/{run-make-fulldeps => run-make}/split-debuginfo/Makefile | 0 tests/{run-make-fulldeps => run-make}/split-debuginfo/bar.rs | 0 tests/{run-make-fulldeps => run-make}/split-debuginfo/baz.rs | 0 tests/{run-make-fulldeps => run-make}/split-debuginfo/foo.rs | 0 tests/{run-make-fulldeps => run-make}/split-debuginfo/main.rs | 0 .../stable-symbol-names/Makefile | 0 .../stable-symbol-names/stable-symbol-names1.rs | 0 .../stable-symbol-names/stable-symbol-names2.rs | 0 .../static-dylib-by-default/Makefile | 0 .../static-dylib-by-default/bar.rs | 0 .../static-dylib-by-default/foo.rs | 0 .../static-dylib-by-default/main.c | 0 .../{run-make-fulldeps => run-make}/static-extern-type/Makefile | 0 .../static-extern-type/define-foo.c | 0 .../static-extern-type/use-foo.rs | 0 tests/{run-make-fulldeps => run-make}/static-unwinding/Makefile | 0 tests/{run-make-fulldeps => run-make}/static-unwinding/lib.rs | 0 tests/{run-make-fulldeps => run-make}/static-unwinding/main.rs | 0 .../staticlib-blank-lib/Makefile | 0 .../{run-make-fulldeps => run-make}/staticlib-blank-lib/foo.rs | 0 tests/{run-make-fulldeps => run-make}/std-core-cycle/Makefile | 0 tests/{run-make-fulldeps => run-make}/std-core-cycle/bar.rs | 0 tests/{run-make-fulldeps => run-make}/std-core-cycle/foo.rs | 0 tests/{run-make-fulldeps => run-make}/stdin-non-utf8/Makefile | 0 tests/{run-make-fulldeps => run-make}/stdin-non-utf8/non-utf8 | 0 .../{run-make-fulldeps => run-make}/suspicious-library/Makefile | 0 tests/{run-make-fulldeps => run-make}/suspicious-library/bar.rs | 0 tests/{run-make-fulldeps => run-make}/suspicious-library/foo.rs | 0 .../{run-make-fulldeps => run-make}/symbol-visibility/Makefile | 0 .../symbol-visibility/a_cdylib.rs | 0 .../symbol-visibility/a_proc_macro.rs | 0 .../symbol-visibility/a_rust_dylib.rs | 0 .../symbol-visibility/an_executable.rs | 0 .../symbol-visibility/an_rlib.rs | 0 .../symbols-include-type-name/Makefile | 0 .../symbols-include-type-name/lib.rs | 0 tests/{run-make-fulldeps => run-make}/symlinked-extern/Makefile | 0 tests/{run-make-fulldeps => run-make}/symlinked-extern/bar.rs | 0 tests/{run-make-fulldeps => run-make}/symlinked-extern/baz.rs | 0 tests/{run-make-fulldeps => run-make}/symlinked-extern/foo.rs | 0 .../symlinked-libraries/Makefile | 0 .../{run-make-fulldeps => run-make}/symlinked-libraries/bar.rs | 0 .../{run-make-fulldeps => run-make}/symlinked-libraries/foo.rs | 0 tests/{run-make-fulldeps => run-make}/symlinked-rlib/Makefile | 0 tests/{run-make-fulldeps => run-make}/symlinked-rlib/bar.rs | 0 tests/{run-make-fulldeps => run-make}/symlinked-rlib/foo.rs | 0 .../sysroot-crates-are-unstable/Makefile | 0 .../sysroot-crates-are-unstable/test.py | 0 .../{run-make-fulldeps => run-make}/target-cpu-native/Makefile | 0 tests/{run-make-fulldeps => run-make}/target-cpu-native/foo.rs | 0 tests/{run-make-fulldeps => run-make}/target-specs/Makefile | 0 .../target-specs/definitely-not-builtin-target.json | 0 tests/{run-make-fulldeps => run-make}/target-specs/foo.rs | 0 .../target-specs/mismatching-data-layout.json | 0 .../target-specs/my-awesome-platform.json | 0 .../target-specs/my-incomplete-platform.json | 0 .../target-specs/my-invalid-platform.json | 0 .../target-specs/my-x86_64-unknown-linux-gnu-platform.json | 0 .../target-without-atomic-cas/Makefile | 0 tests/{run-make-fulldeps => run-make}/test-harness/Makefile | 0 .../test-harness/test-ignore-cfg.rs | 0 .../type-mismatch-same-crate-name/Makefile | 0 .../type-mismatch-same-crate-name/crateA.rs | 0 .../type-mismatch-same-crate-name/crateB.rs | 0 .../type-mismatch-same-crate-name/crateC.rs | 0 .../use-extern-for-plugins/Makefile | 0 .../use-extern-for-plugins/bar.rs | 0 .../use-extern-for-plugins/baz.rs | 0 .../use-extern-for-plugins/foo.rs | 0 .../use-suggestions-rust-2018/Makefile | 0 .../use-suggestions-rust-2018/ep-nested-lib.rs | 0 .../use-suggestions-rust-2018/use-suggestions.rs | 0 .../{run-make-fulldeps => run-make}/used-cdylib-macos/Makefile | 0 .../used-cdylib-macos/dylib_used.rs | 0 tests/{run-make-fulldeps => run-make}/used/Makefile | 0 tests/{run-make-fulldeps => run-make}/used/used.rs | 0 tests/{run-make-fulldeps => run-make}/version/Makefile | 0 .../volatile-intrinsics/Makefile | 0 .../{run-make-fulldeps => run-make}/volatile-intrinsics/main.rs | 0 .../weird-output-filenames/Makefile | 0 .../weird-output-filenames/foo.rs | 0 .../windows-binary-no-external-deps/Makefile | 0 .../windows-binary-no-external-deps/hello.rs | 0 tests/{run-make-fulldeps => run-make}/windows-spawn/Makefile | 0 tests/{run-make-fulldeps => run-make}/windows-spawn/hello.rs | 0 tests/{run-make-fulldeps => run-make}/windows-spawn/spawn.rs | 0 .../{run-make-fulldeps => run-make}/windows-subsystem/Makefile | 0 .../windows-subsystem/console.rs | 0 .../windows-subsystem/windows.rs | 0 696 files changed, 2 insertions(+), 2 deletions(-) rename tests/{run-make-fulldeps => run-make}/a-b-a-linker-guard/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/a-b-a-linker-guard/a.rs (100%) rename tests/{run-make-fulldeps => run-make}/a-b-a-linker-guard/b.rs (100%) rename tests/{run-make-fulldeps => run-make}/alloc-no-oom-handling/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/alloc-no-rc/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/alloc-no-sync/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/allow-non-lint-warnings-cmdline/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/allow-non-lint-warnings-cmdline/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/allow-warnings-cmdline-stability/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/allow-warnings-cmdline-stability/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/allow-warnings-cmdline-stability/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/archive-duplicate-names/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/archive-duplicate-names/bar.c (100%) rename tests/{run-make-fulldeps => run-make}/archive-duplicate-names/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/archive-duplicate-names/foo.c (100%) rename tests/{run-make-fulldeps => run-make}/archive-duplicate-names/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/arguments-non-c-like-enum/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/arguments-non-c-like-enum/nonclike.rs (100%) rename tests/{run-make-fulldeps => run-make}/arguments-non-c-like-enum/test.c (100%) rename tests/{run-make-fulldeps => run-make}/atomic-lock-free/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/atomic-lock-free/atomic_lock_free.rs (100%) rename tests/{run-make-fulldeps => run-make}/bare-outfile/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/bare-outfile/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/c-dynamic-dylib/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/c-dynamic-dylib/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/c-dynamic-dylib/cfoo.c (100%) rename tests/{run-make-fulldeps => run-make}/c-dynamic-dylib/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/c-dynamic-rlib/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/c-dynamic-rlib/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/c-dynamic-rlib/cfoo.c (100%) rename tests/{run-make-fulldeps => run-make}/c-dynamic-rlib/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/c-link-to-rust-dylib/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/c-link-to-rust-dylib/bar.c (100%) rename tests/{run-make-fulldeps => run-make}/c-link-to-rust-dylib/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/c-link-to-rust-staticlib/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/c-link-to-rust-staticlib/bar.c (100%) rename tests/{run-make-fulldeps => run-make}/c-link-to-rust-staticlib/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/c-link-to-rust-va-list-fn/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/c-link-to-rust-va-list-fn/checkrust.rs (100%) rename tests/{run-make-fulldeps => run-make}/c-link-to-rust-va-list-fn/test.c (100%) rename tests/{run-make-fulldeps => run-make}/c-static-dylib/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/c-static-dylib/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/c-static-dylib/cfoo.c (100%) rename tests/{run-make-fulldeps => run-make}/c-static-dylib/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/c-static-rlib/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/c-static-rlib/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/c-static-rlib/cfoo.c (100%) rename tests/{run-make-fulldeps => run-make}/c-static-rlib/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/c-unwind-abi-catch-lib-panic/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/c-unwind-abi-catch-lib-panic/add.c (100%) rename tests/{run-make-fulldeps => run-make}/c-unwind-abi-catch-lib-panic/main.rs (100%) rename tests/{run-make-fulldeps => run-make}/c-unwind-abi-catch-lib-panic/panic.rs (100%) rename tests/{run-make-fulldeps => run-make}/c-unwind-abi-catch-panic/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/c-unwind-abi-catch-panic/add.c (100%) rename tests/{run-make-fulldeps => run-make}/c-unwind-abi-catch-panic/main.rs (100%) rename tests/{run-make-fulldeps => run-make}/cat-and-grep-sanity-check/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/cdylib-dylib-linkage/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/cdylib-dylib-linkage/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/cdylib-dylib-linkage/foo.c (100%) rename tests/{run-make-fulldeps => run-make}/cdylib-dylib-linkage/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/cdylib-fewer-symbols/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/cdylib-fewer-symbols/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/cdylib/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/cdylib/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/cdylib/foo.c (100%) rename tests/{run-make-fulldeps => run-make}/cdylib/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/codegen-options-parsing/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/codegen-options-parsing/dummy.rs (100%) rename tests/{run-make-fulldeps => run-make}/compile-stdin/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/compiler-lookup-paths-2/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/compiler-lookup-paths-2/a.rs (100%) rename tests/{run-make-fulldeps => run-make}/compiler-lookup-paths-2/b.rs (100%) rename tests/{run-make-fulldeps => run-make}/compiler-lookup-paths-2/c.rs (100%) rename tests/{run-make-fulldeps => run-make}/compiler-lookup-paths/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/compiler-lookup-paths/a.rs (100%) rename tests/{run-make-fulldeps => run-make}/compiler-lookup-paths/b.rs (100%) rename tests/{run-make-fulldeps => run-make}/compiler-lookup-paths/c.rs (100%) rename tests/{run-make-fulldeps => run-make}/compiler-lookup-paths/d.rs (100%) rename tests/{run-make-fulldeps => run-make}/compiler-lookup-paths/e.rs (100%) rename tests/{run-make-fulldeps => run-make}/compiler-lookup-paths/e2.rs (100%) rename tests/{run-make-fulldeps => run-make}/compiler-lookup-paths/f.rs (100%) rename tests/{run-make-fulldeps => run-make}/compiler-lookup-paths/native.c (100%) rename tests/{run-make-fulldeps => run-make}/compiler-rt-works-on-mingw/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/compiler-rt-works-on-mingw/foo.cpp (100%) rename tests/{run-make-fulldeps => run-make}/compiler-rt-works-on-mingw/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/core-no-fp-fmt-parse/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/crate-data-smoke/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/crate-data-smoke/crate.rs (100%) rename tests/{run-make-fulldeps => run-make}/crate-data-smoke/lib.rs (100%) rename tests/{run-make-fulldeps => run-make}/crate-data-smoke/rlib.rs (100%) rename tests/{run-make-fulldeps => run-make}/crate-hash-rustc-version/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/crate-hash-rustc-version/a.rs (100%) rename tests/{run-make-fulldeps => run-make}/crate-hash-rustc-version/b.rs (100%) rename tests/{run-make-fulldeps => run-make}/crate-name-priority/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/crate-name-priority/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/crate-name-priority/foo1.rs (100%) rename tests/{run-make-fulldeps => run-make}/cross-lang-lto-clang/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/cross-lang-lto-clang/clib.c (100%) rename tests/{run-make-fulldeps => run-make}/cross-lang-lto-clang/cmain.c (100%) rename tests/{run-make-fulldeps => run-make}/cross-lang-lto-clang/main.rs (100%) rename tests/{run-make-fulldeps => run-make}/cross-lang-lto-clang/rustlib.rs (100%) rename tests/{run-make-fulldeps => run-make}/cross-lang-lto-pgo-smoketest/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/cross-lang-lto-pgo-smoketest/clib.c (100%) rename tests/{run-make-fulldeps => run-make}/cross-lang-lto-pgo-smoketest/cmain.c (100%) rename tests/{run-make-fulldeps => run-make}/cross-lang-lto-pgo-smoketest/main.rs (100%) rename tests/{run-make-fulldeps => run-make}/cross-lang-lto-pgo-smoketest/rustlib.rs (100%) rename tests/{run-make-fulldeps => run-make}/cross-lang-lto-upstream-rlibs/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/cross-lang-lto-upstream-rlibs/staticlib.rs (100%) rename tests/{run-make-fulldeps => run-make}/cross-lang-lto-upstream-rlibs/upstream.rs (100%) rename tests/{run-make-fulldeps => run-make}/cross-lang-lto/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/cross-lang-lto/lib.rs (100%) rename tests/{run-make-fulldeps => run-make}/cross-lang-lto/main.rs (100%) rename tests/{run-make-fulldeps => run-make}/debug-assertions/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/debug-assertions/debug.rs (100%) rename tests/{run-make-fulldeps => run-make}/dep-info-doesnt-run-much/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/dep-info-doesnt-run-much/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/dep-info-spaces/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/dep-info-spaces/Makefile.foo (100%) rename tests/{run-make-fulldeps => run-make}/dep-info-spaces/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/dep-info-spaces/foo foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/dep-info-spaces/lib.rs (100%) rename tests/{run-make-fulldeps => run-make}/dep-info/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/dep-info/Makefile.foo (100%) rename tests/{run-make-fulldeps => run-make}/dep-info/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/dep-info/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/dep-info/lib.rs (100%) rename tests/{run-make-fulldeps => run-make}/dep-info/lib2.rs (100%) rename tests/{run-make-fulldeps => run-make}/doctests-keep-binaries/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/doctests-keep-binaries/t.rs (100%) rename tests/{run-make-fulldeps => run-make}/duplicate-output-flavors/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/duplicate-output-flavors/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/dylib-chain/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/dylib-chain/m1.rs (100%) rename tests/{run-make-fulldeps => run-make}/dylib-chain/m2.rs (100%) rename tests/{run-make-fulldeps => run-make}/dylib-chain/m3.rs (100%) rename tests/{run-make-fulldeps => run-make}/dylib-chain/m4.rs (100%) rename tests/{run-make-fulldeps => run-make}/emit-stack-sizes/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/emit-stack-sizes/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/emit/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/emit/test-24876.rs (100%) rename tests/{run-make-fulldeps => run-make}/emit/test-26235.rs (100%) rename tests/{run-make-fulldeps => run-make}/error-found-staticlib-instead-crate/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/error-found-staticlib-instead-crate/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/error-found-staticlib-instead-crate/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/error-writing-dependencies/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/error-writing-dependencies/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/exit-code/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/exit-code/compile-error.rs (100%) rename tests/{run-make-fulldeps => run-make}/exit-code/lint-failure.rs (100%) rename tests/{run-make-fulldeps => run-make}/exit-code/success.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-diff-internal-name/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/extern-diff-internal-name/lib.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-diff-internal-name/test.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-flag-disambiguates/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/extern-flag-disambiguates/a.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-flag-disambiguates/b.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-flag-disambiguates/c.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-flag-disambiguates/d.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-flag-fun/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/extern-flag-fun/bar-alt.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-flag-fun/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-flag-fun/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-flag-fun/gated_unstable.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-flag-fun/rustc.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-flag-pathless/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/extern-flag-pathless/bar-dynamic.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-flag-pathless/bar-static.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-flag-pathless/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-flag-rename-transitive/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/extern-flag-rename-transitive/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-flag-rename-transitive/baz.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-flag-rename-transitive/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-fn-generic/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/extern-fn-generic/test.c (100%) rename tests/{run-make-fulldeps => run-make}/extern-fn-generic/test.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-fn-generic/testcrate.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-fn-mangle/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/extern-fn-mangle/test.c (100%) rename tests/{run-make-fulldeps => run-make}/extern-fn-mangle/test.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-fn-reachable/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/extern-fn-reachable/dylib.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-fn-struct-passing-abi/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/extern-fn-struct-passing-abi/test.c (100%) rename tests/{run-make-fulldeps => run-make}/extern-fn-struct-passing-abi/test.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-fn-with-extern-types/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/extern-fn-with-extern-types/ctest.c (100%) rename tests/{run-make-fulldeps => run-make}/extern-fn-with-extern-types/test.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-fn-with-packed-struct/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/extern-fn-with-packed-struct/test.c (100%) rename tests/{run-make-fulldeps => run-make}/extern-fn-with-packed-struct/test.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-fn-with-union/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/extern-fn-with-union/ctest.c (100%) rename tests/{run-make-fulldeps => run-make}/extern-fn-with-union/test.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-fn-with-union/testcrate.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-multiple-copies/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/extern-multiple-copies/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-multiple-copies/foo1.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-multiple-copies/foo2.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-multiple-copies2/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/extern-multiple-copies2/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-multiple-copies2/foo1.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-multiple-copies2/foo2.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-overrides-distribution/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/extern-overrides-distribution/libc.rs (100%) rename tests/{run-make-fulldeps => run-make}/extern-overrides-distribution/main.rs (100%) rename tests/{run-make-fulldeps => run-make}/extra-filename-with-temp-outputs/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/extra-filename-with-temp-outputs/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/foreign-double-unwind/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/foreign-double-unwind/foo.cpp (100%) rename tests/{run-make-fulldeps => run-make}/foreign-double-unwind/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/foreign-exceptions/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/foreign-exceptions/foo.cpp (100%) rename tests/{run-make-fulldeps => run-make}/foreign-exceptions/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/foreign-rust-exceptions/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/foreign-rust-exceptions/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/foreign-rust-exceptions/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/fpic/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/fpic/hello.rs (100%) rename tests/{run-make-fulldeps => run-make}/glibc-staticlib-args/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/glibc-staticlib-args/library.rs (100%) rename tests/{run-make-fulldeps => run-make}/glibc-staticlib-args/program.c (100%) rename tests/{run-make-fulldeps => run-make}/hir-tree/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/hir-tree/input.rs (100%) rename tests/{run-make-fulldeps => run-make}/hotplug_codegen_backend/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/hotplug_codegen_backend/some_crate.rs (100%) rename tests/{run-make-fulldeps => run-make}/hotplug_codegen_backend/the_backend.rs (100%) rename tests/{run-make-fulldeps => run-make}/include_bytes_deps/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/include_bytes_deps/input.bin (100%) rename tests/{run-make-fulldeps => run-make}/include_bytes_deps/input.md (100%) rename tests/{run-make-fulldeps => run-make}/include_bytes_deps/input.txt (100%) rename tests/{run-make-fulldeps => run-make}/include_bytes_deps/main.rs (100%) rename tests/{run-make-fulldeps => run-make}/incr-add-rust-src-component/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/incr-add-rust-src-component/main.rs (100%) rename tests/{run-make-fulldeps => run-make}/inline-always-many-cgu/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/inline-always-many-cgu/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/interdependent-c-libraries/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/interdependent-c-libraries/bar.c (100%) rename tests/{run-make-fulldeps => run-make}/interdependent-c-libraries/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/interdependent-c-libraries/foo.c (100%) rename tests/{run-make-fulldeps => run-make}/interdependent-c-libraries/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/interdependent-c-libraries/main.rs (100%) rename tests/{run-make-fulldeps => run-make}/intrinsic-unreachable/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/intrinsic-unreachable/exit-ret.rs (100%) rename tests/{run-make-fulldeps => run-make}/intrinsic-unreachable/exit-unreachable.rs (100%) rename tests/{run-make-fulldeps => run-make}/invalid-library/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/invalid-library/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/invalid-staticlib/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue-11908/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue-11908/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-11908/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-14500/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue-14500/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-14500/foo.c (100%) rename tests/{run-make-fulldeps => run-make}/issue-14500/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-14698/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue-14698/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-15460/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue-15460/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-15460/foo.c (100%) rename tests/{run-make-fulldeps => run-make}/issue-15460/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-18943/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue-18943/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-20626/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue-20626/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-22131/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue-22131/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-24445/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue-24445/foo.c (100%) rename tests/{run-make-fulldeps => run-make}/issue-24445/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-25581/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue-25581/test.c (100%) rename tests/{run-make-fulldeps => run-make}/issue-25581/test.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-26006/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue-26006/in/libc/lib.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-26006/in/time/lib.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-26092/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue-26092/blank.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-28595/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue-28595/a.c (100%) rename tests/{run-make-fulldeps => run-make}/issue-28595/a.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-28595/b.c (100%) rename tests/{run-make-fulldeps => run-make}/issue-28595/b.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-28766/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue-28766/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-28766/main.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-30063/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue-30063/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-33329/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue-33329/main.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-35164/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue-35164/main.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-35164/submodule/mod.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-37839/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue-37839/a.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-37839/b.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-37839/c.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-37893/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue-37893/a.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-37893/b.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-37893/c.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-38237/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue-38237/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-38237/baz.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-38237/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-40535/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue-40535/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-40535/baz.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-40535/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-46239/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue-46239/main.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-47551/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue-47551/eh_frame-terminator.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-51671/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue-51671/app.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-53964/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue-53964/app.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-53964/panic.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-64153/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue-64153/downstream.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-64153/upstream.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-68794-textrel-on-minimal-lib/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue-68794-textrel-on-minimal-lib/bar.c (100%) rename tests/{run-make-fulldeps => run-make}/issue-68794-textrel-on-minimal-lib/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-69368/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue-69368/a.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-69368/b.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-69368/c.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-7349/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue-7349/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-83045/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue-83045/a.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-83045/b.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-83045/c.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-84395-lto-embed-bitcode/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue-84395-lto-embed-bitcode/test.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue-97463-abi-param-passing/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue-97463-abi-param-passing/bad.c (100%) rename tests/{run-make-fulldeps => run-make}/issue-97463-abi-param-passing/param_passing.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue64319/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/issue64319/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/issue64319/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/libs-through-symlinks/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/libs-through-symlinks/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/libs-through-symlinks/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/libtest-json/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/libtest-json/f.rs (100%) rename tests/{run-make-fulldeps => run-make}/libtest-json/output-default.json (100%) rename tests/{run-make-fulldeps => run-make}/libtest-json/output-stdout-success.json (100%) rename tests/{run-make-fulldeps => run-make}/libtest-json/validate_json.py (100%) rename tests/{run-make-fulldeps => run-make}/link-arg/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/link-arg/empty.rs (100%) rename tests/{run-make-fulldeps => run-make}/link-args-order/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/link-args-order/empty.rs (100%) rename tests/{run-make-fulldeps => run-make}/link-cfg/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/link-cfg/dep-with-staticlib.rs (100%) rename tests/{run-make-fulldeps => run-make}/link-cfg/dep.rs (100%) rename tests/{run-make-fulldeps => run-make}/link-cfg/no-deps.rs (100%) rename tests/{run-make-fulldeps => run-make}/link-cfg/return1.c (100%) rename tests/{run-make-fulldeps => run-make}/link-cfg/return2.c (100%) rename tests/{run-make-fulldeps => run-make}/link-cfg/return3.c (100%) rename tests/{run-make-fulldeps => run-make}/link-cfg/with-deps.rs (100%) rename tests/{run-make-fulldeps => run-make}/link-cfg/with-staticlib-deps.rs (100%) rename tests/{run-make-fulldeps => run-make}/link-dedup/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/link-dedup/depa.rs (100%) rename tests/{run-make-fulldeps => run-make}/link-dedup/depb.rs (100%) rename tests/{run-make-fulldeps => run-make}/link-dedup/depc.rs (100%) rename tests/{run-make-fulldeps => run-make}/link-dedup/empty.rs (100%) rename tests/{run-make-fulldeps => run-make}/link-path-order/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/link-path-order/correct.c (100%) rename tests/{run-make-fulldeps => run-make}/link-path-order/main.rs (100%) rename tests/{run-make-fulldeps => run-make}/link-path-order/wrong.c (100%) rename tests/{run-make-fulldeps => run-make}/linkage-attr-on-static/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/linkage-attr-on-static/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/linkage-attr-on-static/foo.c (100%) rename tests/{run-make-fulldeps => run-make}/long-linker-command-lines-cmd-exe/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/long-linker-command-lines-cmd-exe/foo.bat (100%) rename tests/{run-make-fulldeps => run-make}/long-linker-command-lines-cmd-exe/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/long-linker-command-lines/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/long-linker-command-lines/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/longjmp-across-rust/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/longjmp-across-rust/foo.c (100%) rename tests/{run-make-fulldeps => run-make}/longjmp-across-rust/main.rs (100%) rename tests/{run-make-fulldeps => run-make}/ls-metadata/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/ls-metadata/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/lto-dylib-dep/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/lto-dylib-dep/a_dylib.rs (100%) rename tests/{run-make-fulldeps => run-make}/lto-dylib-dep/main.rs (100%) rename tests/{run-make-fulldeps => run-make}/lto-empty/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/lto-empty/lib.rs (100%) rename tests/{run-make-fulldeps => run-make}/lto-no-link-whole-rlib/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/lto-no-link-whole-rlib/bar.c (100%) rename tests/{run-make-fulldeps => run-make}/lto-no-link-whole-rlib/foo.c (100%) rename tests/{run-make-fulldeps => run-make}/lto-no-link-whole-rlib/lib1.rs (100%) rename tests/{run-make-fulldeps => run-make}/lto-no-link-whole-rlib/lib2.rs (100%) rename tests/{run-make-fulldeps => run-make}/lto-no-link-whole-rlib/main.rs (100%) rename tests/{run-make-fulldeps => run-make}/lto-readonly-lib/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/lto-readonly-lib/lib.rs (100%) rename tests/{run-make-fulldeps => run-make}/lto-readonly-lib/main.rs (100%) rename tests/{run-make-fulldeps => run-make}/lto-smoke-c/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/lto-smoke-c/bar.c (100%) rename tests/{run-make-fulldeps => run-make}/lto-smoke-c/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/lto-smoke/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/lto-smoke/lib.rs (100%) rename tests/{run-make-fulldeps => run-make}/lto-smoke/main.rs (100%) rename tests/{run-make-fulldeps => run-make}/manual-crate-name/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/manual-crate-name/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/manual-link/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/manual-link/bar.c (100%) rename tests/{run-make-fulldeps => run-make}/manual-link/foo.c (100%) rename tests/{run-make-fulldeps => run-make}/manual-link/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/manual-link/main.rs (100%) rename tests/{run-make-fulldeps => run-make}/many-crates-but-no-match/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/many-crates-but-no-match/crateA1.rs (100%) rename tests/{run-make-fulldeps => run-make}/many-crates-but-no-match/crateA2.rs (100%) rename tests/{run-make-fulldeps => run-make}/many-crates-but-no-match/crateA3.rs (100%) rename tests/{run-make-fulldeps => run-make}/many-crates-but-no-match/crateB.rs (100%) rename tests/{run-make-fulldeps => run-make}/many-crates-but-no-match/crateC.rs (100%) rename tests/{run-make-fulldeps => run-make}/metadata-flag-frobs-symbols/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/metadata-flag-frobs-symbols/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/metadata-flag-frobs-symbols/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/min-global-align/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/min-global-align/min_global_align.rs (100%) rename tests/{run-make-fulldeps => run-make}/mingw-export-call-convention/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/mingw-export-call-convention/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/mismatching-target-triples/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/mismatching-target-triples/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/mismatching-target-triples/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/missing-crate-dependency/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/missing-crate-dependency/crateA.rs (100%) rename tests/{run-make-fulldeps => run-make}/missing-crate-dependency/crateB.rs (100%) rename tests/{run-make-fulldeps => run-make}/missing-crate-dependency/crateC.rs (100%) rename tests/{run-make-fulldeps => run-make}/mixing-deps/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/mixing-deps/both.rs (100%) rename tests/{run-make-fulldeps => run-make}/mixing-deps/dylib.rs (100%) rename tests/{run-make-fulldeps => run-make}/mixing-deps/prog.rs (100%) rename tests/{run-make-fulldeps => run-make}/mixing-formats/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/mixing-formats/bar1.rs (100%) rename tests/{run-make-fulldeps => run-make}/mixing-formats/bar2.rs (100%) rename tests/{run-make-fulldeps => run-make}/mixing-formats/baz.rs (100%) rename tests/{run-make-fulldeps => run-make}/mixing-formats/baz2.rs (100%) rename tests/{run-make-fulldeps => run-make}/mixing-formats/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/mixing-libs/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/mixing-libs/dylib.rs (100%) rename tests/{run-make-fulldeps => run-make}/mixing-libs/prog.rs (100%) rename tests/{run-make-fulldeps => run-make}/mixing-libs/rlib.rs (100%) rename tests/{run-make-fulldeps => run-make}/msvc-opt-minsize/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/msvc-opt-minsize/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/multiple-emits/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/multiple-emits/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/no-builtins-lto/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/no-builtins-lto/main.rs (100%) rename tests/{run-make-fulldeps => run-make}/no-builtins-lto/no_builtins.rs (100%) rename tests/{run-make-fulldeps => run-make}/no-duplicate-libs/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/no-duplicate-libs/bar.c (100%) rename tests/{run-make-fulldeps => run-make}/no-duplicate-libs/foo.c (100%) rename tests/{run-make-fulldeps => run-make}/no-duplicate-libs/main.rs (100%) rename tests/{run-make-fulldeps => run-make}/no-intermediate-extras/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/no-intermediate-extras/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/obey-crate-type-flag/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/obey-crate-type-flag/test.rs (100%) rename tests/{run-make-fulldeps => run-make}/output-filename-conflicts-with-directory/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/output-filename-conflicts-with-directory/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/output-filename-overwrites-input/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/output-filename-overwrites-input/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/output-filename-overwrites-input/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/output-type-permutations/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/output-type-permutations/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/output-with-hyphens/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/output-with-hyphens/foo-bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/override-aliased-flags/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/override-aliased-flags/main.rs (100%) rename tests/{run-make-fulldeps => run-make}/panic-impl-transitive/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/panic-impl-transitive/panic-impl-consumer.rs (100%) rename tests/{run-make-fulldeps => run-make}/panic-impl-transitive/panic-impl-provider.rs (100%) rename tests/{run-make-fulldeps => run-make}/pass-non-c-like-enum-to-c/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/pass-non-c-like-enum-to-c/nonclike.rs (100%) rename tests/{run-make-fulldeps => run-make}/pass-non-c-like-enum-to-c/test.c (100%) rename tests/{run-make-fulldeps => run-make}/pgo-branch-weights/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/pgo-branch-weights/filecheck-patterns.txt (100%) rename tests/{run-make-fulldeps => run-make}/pgo-branch-weights/interesting.rs (100%) rename tests/{run-make-fulldeps => run-make}/pgo-branch-weights/main.rs (100%) rename tests/{run-make-fulldeps => run-make}/pgo-branch-weights/opaque.rs (100%) rename tests/{run-make-fulldeps => run-make}/pgo-gen-lto/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/pgo-gen-lto/test.rs (100%) rename tests/{run-make-fulldeps => run-make}/pgo-gen-no-imp-symbols/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/pgo-gen-no-imp-symbols/test.rs (100%) rename tests/{run-make-fulldeps => run-make}/pgo-gen/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/pgo-gen/test.rs (100%) rename tests/{run-make-fulldeps => run-make}/pgo-indirect-call-promotion/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/pgo-indirect-call-promotion/filecheck-patterns.txt (100%) rename tests/{run-make-fulldeps => run-make}/pgo-indirect-call-promotion/interesting.rs (100%) rename tests/{run-make-fulldeps => run-make}/pgo-indirect-call-promotion/main.rs (100%) rename tests/{run-make-fulldeps => run-make}/pgo-indirect-call-promotion/opaque.rs (100%) rename tests/{run-make-fulldeps => run-make}/pgo-use/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/pgo-use/filecheck-patterns.txt (100%) rename tests/{run-make-fulldeps => run-make}/pgo-use/main.rs (100%) rename tests/{run-make-fulldeps => run-make}/pointer-auth-link-with-c/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/pointer-auth-link-with-c/test.c (100%) rename tests/{run-make-fulldeps => run-make}/pointer-auth-link-with-c/test.rs (100%) rename tests/{run-make-fulldeps => run-make}/prefer-dylib/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/prefer-dylib/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/prefer-dylib/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/prefer-rlib/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/prefer-rlib/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/prefer-rlib/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/pretty-print-to-file/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/pretty-print-to-file/input.pp (100%) rename tests/{run-make-fulldeps => run-make}/pretty-print-to-file/input.rs (100%) rename tests/{run-make-fulldeps => run-make}/print-calling-conventions/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/print-cfg/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/print-target-list/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/profile/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/profile/test.rs (100%) rename tests/{run-make-fulldeps => run-make}/prune-link-args/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/prune-link-args/empty.rs (100%) rename tests/{run-make-fulldeps => run-make}/redundant-libs/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/redundant-libs/bar.c (100%) rename tests/{run-make-fulldeps => run-make}/redundant-libs/baz.c (100%) rename tests/{run-make-fulldeps => run-make}/redundant-libs/foo.c (100%) rename tests/{run-make-fulldeps => run-make}/redundant-libs/main.rs (100%) rename tests/{run-make-fulldeps => run-make}/relocation-model/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/relocation-model/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/relro-levels/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/relro-levels/hello.rs (100%) rename tests/{run-make-fulldeps => run-make}/remap-path-prefix/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/remap-path-prefix/auxiliary/lib.rs (100%) rename tests/{run-make-fulldeps => run-make}/reproducible-build-2/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/reproducible-build-2/linker.rs (100%) rename tests/{run-make-fulldeps => run-make}/reproducible-build-2/reproducible-build-aux.rs (100%) rename tests/{run-make-fulldeps => run-make}/reproducible-build-2/reproducible-build.rs (100%) rename tests/{run-make-fulldeps => run-make}/reproducible-build/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/reproducible-build/linker.rs (100%) rename tests/{run-make-fulldeps => run-make}/reproducible-build/reproducible-build-aux.rs (100%) rename tests/{run-make-fulldeps => run-make}/reproducible-build/reproducible-build.rs (100%) rename tests/{run-make-fulldeps => run-make}/resolve-rename/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/resolve-rename/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/resolve-rename/baz.rs (100%) rename tests/{run-make-fulldeps => run-make}/resolve-rename/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/return-non-c-like-enum-from-c/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/return-non-c-like-enum-from-c/nonclike.rs (100%) rename tests/{run-make-fulldeps => run-make}/return-non-c-like-enum-from-c/test.c (100%) rename tests/{run-make-fulldeps => run-make}/return-non-c-like-enum/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/return-non-c-like-enum/nonclike.rs (100%) rename tests/{run-make-fulldeps => run-make}/return-non-c-like-enum/test.c (100%) rename tests/{run-make-fulldeps => run-make}/rlib-chain/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/rlib-chain/m1.rs (100%) rename tests/{run-make-fulldeps => run-make}/rlib-chain/m2.rs (100%) rename tests/{run-make-fulldeps => run-make}/rlib-chain/m3.rs (100%) rename tests/{run-make-fulldeps => run-make}/rlib-chain/m4.rs (100%) rename tests/{run-make-fulldeps => run-make}/rustdoc-determinism/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/rustdoc-determinism/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/rustdoc-determinism/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/rustdoc-error-lines/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/rustdoc-error-lines/input.rs (100%) rename tests/{run-make-fulldeps => run-make}/rustdoc-io-error/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/rustdoc-io-error/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/rustdoc-map-file/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/rustdoc-map-file/expected.json (100%) rename tests/{run-make-fulldeps => run-make}/rustdoc-map-file/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/rustdoc-map-file/validate_json.py (100%) rename tests/{run-make-fulldeps => run-make}/rustdoc-output-path/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/rustdoc-output-path/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/rustdoc-scrape-examples-macros/Makefile (95%) rename tests/{run-make-fulldeps => run-make}/rustdoc-scrape-examples-macros/examples/ex.rs (100%) rename tests/{run-make-fulldeps => run-make}/rustdoc-scrape-examples-macros/src/lib.rs (100%) rename tests/{run-make-fulldeps => run-make}/rustdoc-scrape-examples-macros/src/proc.rs (100%) rename tests/{run-make-fulldeps => run-make}/rustdoc-target-spec-json-path/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/rustdoc-target-spec-json-path/dummy_core.rs (100%) rename tests/{run-make-fulldeps => run-make}/rustdoc-target-spec-json-path/my_crate.rs (100%) rename tests/{run-make-fulldeps => run-make}/rustdoc-target-spec-json-path/target.json (100%) rename tests/{run-make-fulldeps => run-make}/rustdoc-themes/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/rustdoc-themes/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/sanitizer-cdylib-link/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/sanitizer-cdylib-link/library.rs (100%) rename tests/{run-make-fulldeps => run-make}/sanitizer-cdylib-link/program.rs (100%) rename tests/{run-make-fulldeps => run-make}/sanitizer-dylib-link/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/sanitizer-dylib-link/library.rs (100%) rename tests/{run-make-fulldeps => run-make}/sanitizer-dylib-link/program.rs (100%) rename tests/{run-make-fulldeps => run-make}/sanitizer-staticlib-link/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/sanitizer-staticlib-link/library.rs (100%) rename tests/{run-make-fulldeps => run-make}/sanitizer-staticlib-link/program.c (100%) rename tests/{run-make-fulldeps => run-make}/sanitizer-staticlib-link/program.rs (100%) rename tests/{run-make-fulldeps => run-make}/separate-link-fail/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/separate-link/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/sepcomp-cci-copies/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/sepcomp-cci-copies/cci_lib.rs (100%) rename tests/{run-make-fulldeps => run-make}/sepcomp-cci-copies/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/sepcomp-inlining/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/sepcomp-inlining/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/sepcomp-separate/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/sepcomp-separate/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/share-generics-dylib/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/share-generics-dylib/instance_provider_a.rs (100%) rename tests/{run-make-fulldeps => run-make}/share-generics-dylib/instance_provider_b.rs (100%) rename tests/{run-make-fulldeps => run-make}/share-generics-dylib/instance_user_a_rlib.rs (100%) rename tests/{run-make-fulldeps => run-make}/share-generics-dylib/instance_user_b_rlib.rs (100%) rename tests/{run-make-fulldeps => run-make}/share-generics-dylib/instance_user_dylib.rs (100%) rename tests/{run-make-fulldeps => run-make}/share-generics-dylib/linked_leaf.rs (100%) rename tests/{run-make-fulldeps => run-make}/simd-ffi/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/simd-ffi/simd.rs (100%) rename tests/{run-make-fulldeps => run-make}/simple-dylib/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/simple-dylib/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/simple-dylib/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/simple-rlib/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/simple-rlib/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/simple-rlib/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/split-debuginfo/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/split-debuginfo/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/split-debuginfo/baz.rs (100%) rename tests/{run-make-fulldeps => run-make}/split-debuginfo/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/split-debuginfo/main.rs (100%) rename tests/{run-make-fulldeps => run-make}/stable-symbol-names/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/stable-symbol-names/stable-symbol-names1.rs (100%) rename tests/{run-make-fulldeps => run-make}/stable-symbol-names/stable-symbol-names2.rs (100%) rename tests/{run-make-fulldeps => run-make}/static-dylib-by-default/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/static-dylib-by-default/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/static-dylib-by-default/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/static-dylib-by-default/main.c (100%) rename tests/{run-make-fulldeps => run-make}/static-extern-type/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/static-extern-type/define-foo.c (100%) rename tests/{run-make-fulldeps => run-make}/static-extern-type/use-foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/static-unwinding/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/static-unwinding/lib.rs (100%) rename tests/{run-make-fulldeps => run-make}/static-unwinding/main.rs (100%) rename tests/{run-make-fulldeps => run-make}/staticlib-blank-lib/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/staticlib-blank-lib/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/std-core-cycle/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/std-core-cycle/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/std-core-cycle/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/stdin-non-utf8/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/stdin-non-utf8/non-utf8 (100%) rename tests/{run-make-fulldeps => run-make}/suspicious-library/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/suspicious-library/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/suspicious-library/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/symbol-visibility/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/symbol-visibility/a_cdylib.rs (100%) rename tests/{run-make-fulldeps => run-make}/symbol-visibility/a_proc_macro.rs (100%) rename tests/{run-make-fulldeps => run-make}/symbol-visibility/a_rust_dylib.rs (100%) rename tests/{run-make-fulldeps => run-make}/symbol-visibility/an_executable.rs (100%) rename tests/{run-make-fulldeps => run-make}/symbol-visibility/an_rlib.rs (100%) rename tests/{run-make-fulldeps => run-make}/symbols-include-type-name/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/symbols-include-type-name/lib.rs (100%) rename tests/{run-make-fulldeps => run-make}/symlinked-extern/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/symlinked-extern/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/symlinked-extern/baz.rs (100%) rename tests/{run-make-fulldeps => run-make}/symlinked-extern/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/symlinked-libraries/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/symlinked-libraries/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/symlinked-libraries/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/symlinked-rlib/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/symlinked-rlib/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/symlinked-rlib/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/sysroot-crates-are-unstable/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/sysroot-crates-are-unstable/test.py (100%) rename tests/{run-make-fulldeps => run-make}/target-cpu-native/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/target-cpu-native/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/target-specs/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/target-specs/definitely-not-builtin-target.json (100%) rename tests/{run-make-fulldeps => run-make}/target-specs/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/target-specs/mismatching-data-layout.json (100%) rename tests/{run-make-fulldeps => run-make}/target-specs/my-awesome-platform.json (100%) rename tests/{run-make-fulldeps => run-make}/target-specs/my-incomplete-platform.json (100%) rename tests/{run-make-fulldeps => run-make}/target-specs/my-invalid-platform.json (100%) rename tests/{run-make-fulldeps => run-make}/target-specs/my-x86_64-unknown-linux-gnu-platform.json (100%) rename tests/{run-make-fulldeps => run-make}/target-without-atomic-cas/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/test-harness/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/test-harness/test-ignore-cfg.rs (100%) rename tests/{run-make-fulldeps => run-make}/type-mismatch-same-crate-name/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/type-mismatch-same-crate-name/crateA.rs (100%) rename tests/{run-make-fulldeps => run-make}/type-mismatch-same-crate-name/crateB.rs (100%) rename tests/{run-make-fulldeps => run-make}/type-mismatch-same-crate-name/crateC.rs (100%) rename tests/{run-make-fulldeps => run-make}/use-extern-for-plugins/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/use-extern-for-plugins/bar.rs (100%) rename tests/{run-make-fulldeps => run-make}/use-extern-for-plugins/baz.rs (100%) rename tests/{run-make-fulldeps => run-make}/use-extern-for-plugins/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/use-suggestions-rust-2018/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/use-suggestions-rust-2018/ep-nested-lib.rs (100%) rename tests/{run-make-fulldeps => run-make}/use-suggestions-rust-2018/use-suggestions.rs (100%) rename tests/{run-make-fulldeps => run-make}/used-cdylib-macos/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/used-cdylib-macos/dylib_used.rs (100%) rename tests/{run-make-fulldeps => run-make}/used/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/used/used.rs (100%) rename tests/{run-make-fulldeps => run-make}/version/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/volatile-intrinsics/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/volatile-intrinsics/main.rs (100%) rename tests/{run-make-fulldeps => run-make}/weird-output-filenames/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/weird-output-filenames/foo.rs (100%) rename tests/{run-make-fulldeps => run-make}/windows-binary-no-external-deps/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/windows-binary-no-external-deps/hello.rs (100%) rename tests/{run-make-fulldeps => run-make}/windows-spawn/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/windows-spawn/hello.rs (100%) rename tests/{run-make-fulldeps => run-make}/windows-spawn/spawn.rs (100%) rename tests/{run-make-fulldeps => run-make}/windows-subsystem/Makefile (100%) rename tests/{run-make-fulldeps => run-make}/windows-subsystem/console.rs (100%) rename tests/{run-make-fulldeps => run-make}/windows-subsystem/windows.rs (100%) diff --git a/tests/run-make-fulldeps/a-b-a-linker-guard/Makefile b/tests/run-make/a-b-a-linker-guard/Makefile similarity index 100% rename from tests/run-make-fulldeps/a-b-a-linker-guard/Makefile rename to tests/run-make/a-b-a-linker-guard/Makefile diff --git a/tests/run-make-fulldeps/a-b-a-linker-guard/a.rs b/tests/run-make/a-b-a-linker-guard/a.rs similarity index 100% rename from tests/run-make-fulldeps/a-b-a-linker-guard/a.rs rename to tests/run-make/a-b-a-linker-guard/a.rs diff --git a/tests/run-make-fulldeps/a-b-a-linker-guard/b.rs b/tests/run-make/a-b-a-linker-guard/b.rs similarity index 100% rename from tests/run-make-fulldeps/a-b-a-linker-guard/b.rs rename to tests/run-make/a-b-a-linker-guard/b.rs diff --git a/tests/run-make-fulldeps/alloc-no-oom-handling/Makefile b/tests/run-make/alloc-no-oom-handling/Makefile similarity index 100% rename from tests/run-make-fulldeps/alloc-no-oom-handling/Makefile rename to tests/run-make/alloc-no-oom-handling/Makefile diff --git a/tests/run-make-fulldeps/alloc-no-rc/Makefile b/tests/run-make/alloc-no-rc/Makefile similarity index 100% rename from tests/run-make-fulldeps/alloc-no-rc/Makefile rename to tests/run-make/alloc-no-rc/Makefile diff --git a/tests/run-make-fulldeps/alloc-no-sync/Makefile b/tests/run-make/alloc-no-sync/Makefile similarity index 100% rename from tests/run-make-fulldeps/alloc-no-sync/Makefile rename to tests/run-make/alloc-no-sync/Makefile diff --git a/tests/run-make-fulldeps/allow-non-lint-warnings-cmdline/Makefile b/tests/run-make/allow-non-lint-warnings-cmdline/Makefile similarity index 100% rename from tests/run-make-fulldeps/allow-non-lint-warnings-cmdline/Makefile rename to tests/run-make/allow-non-lint-warnings-cmdline/Makefile diff --git a/tests/run-make-fulldeps/allow-non-lint-warnings-cmdline/foo.rs b/tests/run-make/allow-non-lint-warnings-cmdline/foo.rs similarity index 100% rename from tests/run-make-fulldeps/allow-non-lint-warnings-cmdline/foo.rs rename to tests/run-make/allow-non-lint-warnings-cmdline/foo.rs diff --git a/tests/run-make-fulldeps/allow-warnings-cmdline-stability/Makefile b/tests/run-make/allow-warnings-cmdline-stability/Makefile similarity index 100% rename from tests/run-make-fulldeps/allow-warnings-cmdline-stability/Makefile rename to tests/run-make/allow-warnings-cmdline-stability/Makefile diff --git a/tests/run-make-fulldeps/allow-warnings-cmdline-stability/bar.rs b/tests/run-make/allow-warnings-cmdline-stability/bar.rs similarity index 100% rename from tests/run-make-fulldeps/allow-warnings-cmdline-stability/bar.rs rename to tests/run-make/allow-warnings-cmdline-stability/bar.rs diff --git a/tests/run-make-fulldeps/allow-warnings-cmdline-stability/foo.rs b/tests/run-make/allow-warnings-cmdline-stability/foo.rs similarity index 100% rename from tests/run-make-fulldeps/allow-warnings-cmdline-stability/foo.rs rename to tests/run-make/allow-warnings-cmdline-stability/foo.rs diff --git a/tests/run-make-fulldeps/archive-duplicate-names/Makefile b/tests/run-make/archive-duplicate-names/Makefile similarity index 100% rename from tests/run-make-fulldeps/archive-duplicate-names/Makefile rename to tests/run-make/archive-duplicate-names/Makefile diff --git a/tests/run-make-fulldeps/archive-duplicate-names/bar.c b/tests/run-make/archive-duplicate-names/bar.c similarity index 100% rename from tests/run-make-fulldeps/archive-duplicate-names/bar.c rename to tests/run-make/archive-duplicate-names/bar.c diff --git a/tests/run-make-fulldeps/archive-duplicate-names/bar.rs b/tests/run-make/archive-duplicate-names/bar.rs similarity index 100% rename from tests/run-make-fulldeps/archive-duplicate-names/bar.rs rename to tests/run-make/archive-duplicate-names/bar.rs diff --git a/tests/run-make-fulldeps/archive-duplicate-names/foo.c b/tests/run-make/archive-duplicate-names/foo.c similarity index 100% rename from tests/run-make-fulldeps/archive-duplicate-names/foo.c rename to tests/run-make/archive-duplicate-names/foo.c diff --git a/tests/run-make-fulldeps/archive-duplicate-names/foo.rs b/tests/run-make/archive-duplicate-names/foo.rs similarity index 100% rename from tests/run-make-fulldeps/archive-duplicate-names/foo.rs rename to tests/run-make/archive-duplicate-names/foo.rs diff --git a/tests/run-make-fulldeps/arguments-non-c-like-enum/Makefile b/tests/run-make/arguments-non-c-like-enum/Makefile similarity index 100% rename from tests/run-make-fulldeps/arguments-non-c-like-enum/Makefile rename to tests/run-make/arguments-non-c-like-enum/Makefile diff --git a/tests/run-make-fulldeps/arguments-non-c-like-enum/nonclike.rs b/tests/run-make/arguments-non-c-like-enum/nonclike.rs similarity index 100% rename from tests/run-make-fulldeps/arguments-non-c-like-enum/nonclike.rs rename to tests/run-make/arguments-non-c-like-enum/nonclike.rs diff --git a/tests/run-make-fulldeps/arguments-non-c-like-enum/test.c b/tests/run-make/arguments-non-c-like-enum/test.c similarity index 100% rename from tests/run-make-fulldeps/arguments-non-c-like-enum/test.c rename to tests/run-make/arguments-non-c-like-enum/test.c diff --git a/tests/run-make-fulldeps/atomic-lock-free/Makefile b/tests/run-make/atomic-lock-free/Makefile similarity index 100% rename from tests/run-make-fulldeps/atomic-lock-free/Makefile rename to tests/run-make/atomic-lock-free/Makefile diff --git a/tests/run-make-fulldeps/atomic-lock-free/atomic_lock_free.rs b/tests/run-make/atomic-lock-free/atomic_lock_free.rs similarity index 100% rename from tests/run-make-fulldeps/atomic-lock-free/atomic_lock_free.rs rename to tests/run-make/atomic-lock-free/atomic_lock_free.rs diff --git a/tests/run-make-fulldeps/bare-outfile/Makefile b/tests/run-make/bare-outfile/Makefile similarity index 100% rename from tests/run-make-fulldeps/bare-outfile/Makefile rename to tests/run-make/bare-outfile/Makefile diff --git a/tests/run-make-fulldeps/bare-outfile/foo.rs b/tests/run-make/bare-outfile/foo.rs similarity index 100% rename from tests/run-make-fulldeps/bare-outfile/foo.rs rename to tests/run-make/bare-outfile/foo.rs diff --git a/tests/run-make-fulldeps/c-dynamic-dylib/Makefile b/tests/run-make/c-dynamic-dylib/Makefile similarity index 100% rename from tests/run-make-fulldeps/c-dynamic-dylib/Makefile rename to tests/run-make/c-dynamic-dylib/Makefile diff --git a/tests/run-make-fulldeps/c-dynamic-dylib/bar.rs b/tests/run-make/c-dynamic-dylib/bar.rs similarity index 100% rename from tests/run-make-fulldeps/c-dynamic-dylib/bar.rs rename to tests/run-make/c-dynamic-dylib/bar.rs diff --git a/tests/run-make-fulldeps/c-dynamic-dylib/cfoo.c b/tests/run-make/c-dynamic-dylib/cfoo.c similarity index 100% rename from tests/run-make-fulldeps/c-dynamic-dylib/cfoo.c rename to tests/run-make/c-dynamic-dylib/cfoo.c diff --git a/tests/run-make-fulldeps/c-dynamic-dylib/foo.rs b/tests/run-make/c-dynamic-dylib/foo.rs similarity index 100% rename from tests/run-make-fulldeps/c-dynamic-dylib/foo.rs rename to tests/run-make/c-dynamic-dylib/foo.rs diff --git a/tests/run-make-fulldeps/c-dynamic-rlib/Makefile b/tests/run-make/c-dynamic-rlib/Makefile similarity index 100% rename from tests/run-make-fulldeps/c-dynamic-rlib/Makefile rename to tests/run-make/c-dynamic-rlib/Makefile diff --git a/tests/run-make-fulldeps/c-dynamic-rlib/bar.rs b/tests/run-make/c-dynamic-rlib/bar.rs similarity index 100% rename from tests/run-make-fulldeps/c-dynamic-rlib/bar.rs rename to tests/run-make/c-dynamic-rlib/bar.rs diff --git a/tests/run-make-fulldeps/c-dynamic-rlib/cfoo.c b/tests/run-make/c-dynamic-rlib/cfoo.c similarity index 100% rename from tests/run-make-fulldeps/c-dynamic-rlib/cfoo.c rename to tests/run-make/c-dynamic-rlib/cfoo.c diff --git a/tests/run-make-fulldeps/c-dynamic-rlib/foo.rs b/tests/run-make/c-dynamic-rlib/foo.rs similarity index 100% rename from tests/run-make-fulldeps/c-dynamic-rlib/foo.rs rename to tests/run-make/c-dynamic-rlib/foo.rs diff --git a/tests/run-make-fulldeps/c-link-to-rust-dylib/Makefile b/tests/run-make/c-link-to-rust-dylib/Makefile similarity index 100% rename from tests/run-make-fulldeps/c-link-to-rust-dylib/Makefile rename to tests/run-make/c-link-to-rust-dylib/Makefile diff --git a/tests/run-make-fulldeps/c-link-to-rust-dylib/bar.c b/tests/run-make/c-link-to-rust-dylib/bar.c similarity index 100% rename from tests/run-make-fulldeps/c-link-to-rust-dylib/bar.c rename to tests/run-make/c-link-to-rust-dylib/bar.c diff --git a/tests/run-make-fulldeps/c-link-to-rust-dylib/foo.rs b/tests/run-make/c-link-to-rust-dylib/foo.rs similarity index 100% rename from tests/run-make-fulldeps/c-link-to-rust-dylib/foo.rs rename to tests/run-make/c-link-to-rust-dylib/foo.rs diff --git a/tests/run-make-fulldeps/c-link-to-rust-staticlib/Makefile b/tests/run-make/c-link-to-rust-staticlib/Makefile similarity index 100% rename from tests/run-make-fulldeps/c-link-to-rust-staticlib/Makefile rename to tests/run-make/c-link-to-rust-staticlib/Makefile diff --git a/tests/run-make-fulldeps/c-link-to-rust-staticlib/bar.c b/tests/run-make/c-link-to-rust-staticlib/bar.c similarity index 100% rename from tests/run-make-fulldeps/c-link-to-rust-staticlib/bar.c rename to tests/run-make/c-link-to-rust-staticlib/bar.c diff --git a/tests/run-make-fulldeps/c-link-to-rust-staticlib/foo.rs b/tests/run-make/c-link-to-rust-staticlib/foo.rs similarity index 100% rename from tests/run-make-fulldeps/c-link-to-rust-staticlib/foo.rs rename to tests/run-make/c-link-to-rust-staticlib/foo.rs diff --git a/tests/run-make-fulldeps/c-link-to-rust-va-list-fn/Makefile b/tests/run-make/c-link-to-rust-va-list-fn/Makefile similarity index 100% rename from tests/run-make-fulldeps/c-link-to-rust-va-list-fn/Makefile rename to tests/run-make/c-link-to-rust-va-list-fn/Makefile diff --git a/tests/run-make-fulldeps/c-link-to-rust-va-list-fn/checkrust.rs b/tests/run-make/c-link-to-rust-va-list-fn/checkrust.rs similarity index 100% rename from tests/run-make-fulldeps/c-link-to-rust-va-list-fn/checkrust.rs rename to tests/run-make/c-link-to-rust-va-list-fn/checkrust.rs diff --git a/tests/run-make-fulldeps/c-link-to-rust-va-list-fn/test.c b/tests/run-make/c-link-to-rust-va-list-fn/test.c similarity index 100% rename from tests/run-make-fulldeps/c-link-to-rust-va-list-fn/test.c rename to tests/run-make/c-link-to-rust-va-list-fn/test.c diff --git a/tests/run-make-fulldeps/c-static-dylib/Makefile b/tests/run-make/c-static-dylib/Makefile similarity index 100% rename from tests/run-make-fulldeps/c-static-dylib/Makefile rename to tests/run-make/c-static-dylib/Makefile diff --git a/tests/run-make-fulldeps/c-static-dylib/bar.rs b/tests/run-make/c-static-dylib/bar.rs similarity index 100% rename from tests/run-make-fulldeps/c-static-dylib/bar.rs rename to tests/run-make/c-static-dylib/bar.rs diff --git a/tests/run-make-fulldeps/c-static-dylib/cfoo.c b/tests/run-make/c-static-dylib/cfoo.c similarity index 100% rename from tests/run-make-fulldeps/c-static-dylib/cfoo.c rename to tests/run-make/c-static-dylib/cfoo.c diff --git a/tests/run-make-fulldeps/c-static-dylib/foo.rs b/tests/run-make/c-static-dylib/foo.rs similarity index 100% rename from tests/run-make-fulldeps/c-static-dylib/foo.rs rename to tests/run-make/c-static-dylib/foo.rs diff --git a/tests/run-make-fulldeps/c-static-rlib/Makefile b/tests/run-make/c-static-rlib/Makefile similarity index 100% rename from tests/run-make-fulldeps/c-static-rlib/Makefile rename to tests/run-make/c-static-rlib/Makefile diff --git a/tests/run-make-fulldeps/c-static-rlib/bar.rs b/tests/run-make/c-static-rlib/bar.rs similarity index 100% rename from tests/run-make-fulldeps/c-static-rlib/bar.rs rename to tests/run-make/c-static-rlib/bar.rs diff --git a/tests/run-make-fulldeps/c-static-rlib/cfoo.c b/tests/run-make/c-static-rlib/cfoo.c similarity index 100% rename from tests/run-make-fulldeps/c-static-rlib/cfoo.c rename to tests/run-make/c-static-rlib/cfoo.c diff --git a/tests/run-make-fulldeps/c-static-rlib/foo.rs b/tests/run-make/c-static-rlib/foo.rs similarity index 100% rename from tests/run-make-fulldeps/c-static-rlib/foo.rs rename to tests/run-make/c-static-rlib/foo.rs diff --git a/tests/run-make-fulldeps/c-unwind-abi-catch-lib-panic/Makefile b/tests/run-make/c-unwind-abi-catch-lib-panic/Makefile similarity index 100% rename from tests/run-make-fulldeps/c-unwind-abi-catch-lib-panic/Makefile rename to tests/run-make/c-unwind-abi-catch-lib-panic/Makefile diff --git a/tests/run-make-fulldeps/c-unwind-abi-catch-lib-panic/add.c b/tests/run-make/c-unwind-abi-catch-lib-panic/add.c similarity index 100% rename from tests/run-make-fulldeps/c-unwind-abi-catch-lib-panic/add.c rename to tests/run-make/c-unwind-abi-catch-lib-panic/add.c diff --git a/tests/run-make-fulldeps/c-unwind-abi-catch-lib-panic/main.rs b/tests/run-make/c-unwind-abi-catch-lib-panic/main.rs similarity index 100% rename from tests/run-make-fulldeps/c-unwind-abi-catch-lib-panic/main.rs rename to tests/run-make/c-unwind-abi-catch-lib-panic/main.rs diff --git a/tests/run-make-fulldeps/c-unwind-abi-catch-lib-panic/panic.rs b/tests/run-make/c-unwind-abi-catch-lib-panic/panic.rs similarity index 100% rename from tests/run-make-fulldeps/c-unwind-abi-catch-lib-panic/panic.rs rename to tests/run-make/c-unwind-abi-catch-lib-panic/panic.rs diff --git a/tests/run-make-fulldeps/c-unwind-abi-catch-panic/Makefile b/tests/run-make/c-unwind-abi-catch-panic/Makefile similarity index 100% rename from tests/run-make-fulldeps/c-unwind-abi-catch-panic/Makefile rename to tests/run-make/c-unwind-abi-catch-panic/Makefile diff --git a/tests/run-make-fulldeps/c-unwind-abi-catch-panic/add.c b/tests/run-make/c-unwind-abi-catch-panic/add.c similarity index 100% rename from tests/run-make-fulldeps/c-unwind-abi-catch-panic/add.c rename to tests/run-make/c-unwind-abi-catch-panic/add.c diff --git a/tests/run-make-fulldeps/c-unwind-abi-catch-panic/main.rs b/tests/run-make/c-unwind-abi-catch-panic/main.rs similarity index 100% rename from tests/run-make-fulldeps/c-unwind-abi-catch-panic/main.rs rename to tests/run-make/c-unwind-abi-catch-panic/main.rs diff --git a/tests/run-make-fulldeps/cat-and-grep-sanity-check/Makefile b/tests/run-make/cat-and-grep-sanity-check/Makefile similarity index 100% rename from tests/run-make-fulldeps/cat-and-grep-sanity-check/Makefile rename to tests/run-make/cat-and-grep-sanity-check/Makefile diff --git a/tests/run-make-fulldeps/cdylib-dylib-linkage/Makefile b/tests/run-make/cdylib-dylib-linkage/Makefile similarity index 100% rename from tests/run-make-fulldeps/cdylib-dylib-linkage/Makefile rename to tests/run-make/cdylib-dylib-linkage/Makefile diff --git a/tests/run-make-fulldeps/cdylib-dylib-linkage/bar.rs b/tests/run-make/cdylib-dylib-linkage/bar.rs similarity index 100% rename from tests/run-make-fulldeps/cdylib-dylib-linkage/bar.rs rename to tests/run-make/cdylib-dylib-linkage/bar.rs diff --git a/tests/run-make-fulldeps/cdylib-dylib-linkage/foo.c b/tests/run-make/cdylib-dylib-linkage/foo.c similarity index 100% rename from tests/run-make-fulldeps/cdylib-dylib-linkage/foo.c rename to tests/run-make/cdylib-dylib-linkage/foo.c diff --git a/tests/run-make-fulldeps/cdylib-dylib-linkage/foo.rs b/tests/run-make/cdylib-dylib-linkage/foo.rs similarity index 100% rename from tests/run-make-fulldeps/cdylib-dylib-linkage/foo.rs rename to tests/run-make/cdylib-dylib-linkage/foo.rs diff --git a/tests/run-make-fulldeps/cdylib-fewer-symbols/Makefile b/tests/run-make/cdylib-fewer-symbols/Makefile similarity index 100% rename from tests/run-make-fulldeps/cdylib-fewer-symbols/Makefile rename to tests/run-make/cdylib-fewer-symbols/Makefile diff --git a/tests/run-make-fulldeps/cdylib-fewer-symbols/foo.rs b/tests/run-make/cdylib-fewer-symbols/foo.rs similarity index 100% rename from tests/run-make-fulldeps/cdylib-fewer-symbols/foo.rs rename to tests/run-make/cdylib-fewer-symbols/foo.rs diff --git a/tests/run-make-fulldeps/cdylib/Makefile b/tests/run-make/cdylib/Makefile similarity index 100% rename from tests/run-make-fulldeps/cdylib/Makefile rename to tests/run-make/cdylib/Makefile diff --git a/tests/run-make-fulldeps/cdylib/bar.rs b/tests/run-make/cdylib/bar.rs similarity index 100% rename from tests/run-make-fulldeps/cdylib/bar.rs rename to tests/run-make/cdylib/bar.rs diff --git a/tests/run-make-fulldeps/cdylib/foo.c b/tests/run-make/cdylib/foo.c similarity index 100% rename from tests/run-make-fulldeps/cdylib/foo.c rename to tests/run-make/cdylib/foo.c diff --git a/tests/run-make-fulldeps/cdylib/foo.rs b/tests/run-make/cdylib/foo.rs similarity index 100% rename from tests/run-make-fulldeps/cdylib/foo.rs rename to tests/run-make/cdylib/foo.rs diff --git a/tests/run-make-fulldeps/codegen-options-parsing/Makefile b/tests/run-make/codegen-options-parsing/Makefile similarity index 100% rename from tests/run-make-fulldeps/codegen-options-parsing/Makefile rename to tests/run-make/codegen-options-parsing/Makefile diff --git a/tests/run-make-fulldeps/codegen-options-parsing/dummy.rs b/tests/run-make/codegen-options-parsing/dummy.rs similarity index 100% rename from tests/run-make-fulldeps/codegen-options-parsing/dummy.rs rename to tests/run-make/codegen-options-parsing/dummy.rs diff --git a/tests/run-make-fulldeps/compile-stdin/Makefile b/tests/run-make/compile-stdin/Makefile similarity index 100% rename from tests/run-make-fulldeps/compile-stdin/Makefile rename to tests/run-make/compile-stdin/Makefile diff --git a/tests/run-make-fulldeps/compiler-lookup-paths-2/Makefile b/tests/run-make/compiler-lookup-paths-2/Makefile similarity index 100% rename from tests/run-make-fulldeps/compiler-lookup-paths-2/Makefile rename to tests/run-make/compiler-lookup-paths-2/Makefile diff --git a/tests/run-make-fulldeps/compiler-lookup-paths-2/a.rs b/tests/run-make/compiler-lookup-paths-2/a.rs similarity index 100% rename from tests/run-make-fulldeps/compiler-lookup-paths-2/a.rs rename to tests/run-make/compiler-lookup-paths-2/a.rs diff --git a/tests/run-make-fulldeps/compiler-lookup-paths-2/b.rs b/tests/run-make/compiler-lookup-paths-2/b.rs similarity index 100% rename from tests/run-make-fulldeps/compiler-lookup-paths-2/b.rs rename to tests/run-make/compiler-lookup-paths-2/b.rs diff --git a/tests/run-make-fulldeps/compiler-lookup-paths-2/c.rs b/tests/run-make/compiler-lookup-paths-2/c.rs similarity index 100% rename from tests/run-make-fulldeps/compiler-lookup-paths-2/c.rs rename to tests/run-make/compiler-lookup-paths-2/c.rs diff --git a/tests/run-make-fulldeps/compiler-lookup-paths/Makefile b/tests/run-make/compiler-lookup-paths/Makefile similarity index 100% rename from tests/run-make-fulldeps/compiler-lookup-paths/Makefile rename to tests/run-make/compiler-lookup-paths/Makefile diff --git a/tests/run-make-fulldeps/compiler-lookup-paths/a.rs b/tests/run-make/compiler-lookup-paths/a.rs similarity index 100% rename from tests/run-make-fulldeps/compiler-lookup-paths/a.rs rename to tests/run-make/compiler-lookup-paths/a.rs diff --git a/tests/run-make-fulldeps/compiler-lookup-paths/b.rs b/tests/run-make/compiler-lookup-paths/b.rs similarity index 100% rename from tests/run-make-fulldeps/compiler-lookup-paths/b.rs rename to tests/run-make/compiler-lookup-paths/b.rs diff --git a/tests/run-make-fulldeps/compiler-lookup-paths/c.rs b/tests/run-make/compiler-lookup-paths/c.rs similarity index 100% rename from tests/run-make-fulldeps/compiler-lookup-paths/c.rs rename to tests/run-make/compiler-lookup-paths/c.rs diff --git a/tests/run-make-fulldeps/compiler-lookup-paths/d.rs b/tests/run-make/compiler-lookup-paths/d.rs similarity index 100% rename from tests/run-make-fulldeps/compiler-lookup-paths/d.rs rename to tests/run-make/compiler-lookup-paths/d.rs diff --git a/tests/run-make-fulldeps/compiler-lookup-paths/e.rs b/tests/run-make/compiler-lookup-paths/e.rs similarity index 100% rename from tests/run-make-fulldeps/compiler-lookup-paths/e.rs rename to tests/run-make/compiler-lookup-paths/e.rs diff --git a/tests/run-make-fulldeps/compiler-lookup-paths/e2.rs b/tests/run-make/compiler-lookup-paths/e2.rs similarity index 100% rename from tests/run-make-fulldeps/compiler-lookup-paths/e2.rs rename to tests/run-make/compiler-lookup-paths/e2.rs diff --git a/tests/run-make-fulldeps/compiler-lookup-paths/f.rs b/tests/run-make/compiler-lookup-paths/f.rs similarity index 100% rename from tests/run-make-fulldeps/compiler-lookup-paths/f.rs rename to tests/run-make/compiler-lookup-paths/f.rs diff --git a/tests/run-make-fulldeps/compiler-lookup-paths/native.c b/tests/run-make/compiler-lookup-paths/native.c similarity index 100% rename from tests/run-make-fulldeps/compiler-lookup-paths/native.c rename to tests/run-make/compiler-lookup-paths/native.c diff --git a/tests/run-make-fulldeps/compiler-rt-works-on-mingw/Makefile b/tests/run-make/compiler-rt-works-on-mingw/Makefile similarity index 100% rename from tests/run-make-fulldeps/compiler-rt-works-on-mingw/Makefile rename to tests/run-make/compiler-rt-works-on-mingw/Makefile diff --git a/tests/run-make-fulldeps/compiler-rt-works-on-mingw/foo.cpp b/tests/run-make/compiler-rt-works-on-mingw/foo.cpp similarity index 100% rename from tests/run-make-fulldeps/compiler-rt-works-on-mingw/foo.cpp rename to tests/run-make/compiler-rt-works-on-mingw/foo.cpp diff --git a/tests/run-make-fulldeps/compiler-rt-works-on-mingw/foo.rs b/tests/run-make/compiler-rt-works-on-mingw/foo.rs similarity index 100% rename from tests/run-make-fulldeps/compiler-rt-works-on-mingw/foo.rs rename to tests/run-make/compiler-rt-works-on-mingw/foo.rs diff --git a/tests/run-make-fulldeps/core-no-fp-fmt-parse/Makefile b/tests/run-make/core-no-fp-fmt-parse/Makefile similarity index 100% rename from tests/run-make-fulldeps/core-no-fp-fmt-parse/Makefile rename to tests/run-make/core-no-fp-fmt-parse/Makefile diff --git a/tests/run-make-fulldeps/crate-data-smoke/Makefile b/tests/run-make/crate-data-smoke/Makefile similarity index 100% rename from tests/run-make-fulldeps/crate-data-smoke/Makefile rename to tests/run-make/crate-data-smoke/Makefile diff --git a/tests/run-make-fulldeps/crate-data-smoke/crate.rs b/tests/run-make/crate-data-smoke/crate.rs similarity index 100% rename from tests/run-make-fulldeps/crate-data-smoke/crate.rs rename to tests/run-make/crate-data-smoke/crate.rs diff --git a/tests/run-make-fulldeps/crate-data-smoke/lib.rs b/tests/run-make/crate-data-smoke/lib.rs similarity index 100% rename from tests/run-make-fulldeps/crate-data-smoke/lib.rs rename to tests/run-make/crate-data-smoke/lib.rs diff --git a/tests/run-make-fulldeps/crate-data-smoke/rlib.rs b/tests/run-make/crate-data-smoke/rlib.rs similarity index 100% rename from tests/run-make-fulldeps/crate-data-smoke/rlib.rs rename to tests/run-make/crate-data-smoke/rlib.rs diff --git a/tests/run-make-fulldeps/crate-hash-rustc-version/Makefile b/tests/run-make/crate-hash-rustc-version/Makefile similarity index 100% rename from tests/run-make-fulldeps/crate-hash-rustc-version/Makefile rename to tests/run-make/crate-hash-rustc-version/Makefile diff --git a/tests/run-make-fulldeps/crate-hash-rustc-version/a.rs b/tests/run-make/crate-hash-rustc-version/a.rs similarity index 100% rename from tests/run-make-fulldeps/crate-hash-rustc-version/a.rs rename to tests/run-make/crate-hash-rustc-version/a.rs diff --git a/tests/run-make-fulldeps/crate-hash-rustc-version/b.rs b/tests/run-make/crate-hash-rustc-version/b.rs similarity index 100% rename from tests/run-make-fulldeps/crate-hash-rustc-version/b.rs rename to tests/run-make/crate-hash-rustc-version/b.rs diff --git a/tests/run-make-fulldeps/crate-name-priority/Makefile b/tests/run-make/crate-name-priority/Makefile similarity index 100% rename from tests/run-make-fulldeps/crate-name-priority/Makefile rename to tests/run-make/crate-name-priority/Makefile diff --git a/tests/run-make-fulldeps/crate-name-priority/foo.rs b/tests/run-make/crate-name-priority/foo.rs similarity index 100% rename from tests/run-make-fulldeps/crate-name-priority/foo.rs rename to tests/run-make/crate-name-priority/foo.rs diff --git a/tests/run-make-fulldeps/crate-name-priority/foo1.rs b/tests/run-make/crate-name-priority/foo1.rs similarity index 100% rename from tests/run-make-fulldeps/crate-name-priority/foo1.rs rename to tests/run-make/crate-name-priority/foo1.rs diff --git a/tests/run-make-fulldeps/cross-lang-lto-clang/Makefile b/tests/run-make/cross-lang-lto-clang/Makefile similarity index 100% rename from tests/run-make-fulldeps/cross-lang-lto-clang/Makefile rename to tests/run-make/cross-lang-lto-clang/Makefile diff --git a/tests/run-make-fulldeps/cross-lang-lto-clang/clib.c b/tests/run-make/cross-lang-lto-clang/clib.c similarity index 100% rename from tests/run-make-fulldeps/cross-lang-lto-clang/clib.c rename to tests/run-make/cross-lang-lto-clang/clib.c diff --git a/tests/run-make-fulldeps/cross-lang-lto-clang/cmain.c b/tests/run-make/cross-lang-lto-clang/cmain.c similarity index 100% rename from tests/run-make-fulldeps/cross-lang-lto-clang/cmain.c rename to tests/run-make/cross-lang-lto-clang/cmain.c diff --git a/tests/run-make-fulldeps/cross-lang-lto-clang/main.rs b/tests/run-make/cross-lang-lto-clang/main.rs similarity index 100% rename from tests/run-make-fulldeps/cross-lang-lto-clang/main.rs rename to tests/run-make/cross-lang-lto-clang/main.rs diff --git a/tests/run-make-fulldeps/cross-lang-lto-clang/rustlib.rs b/tests/run-make/cross-lang-lto-clang/rustlib.rs similarity index 100% rename from tests/run-make-fulldeps/cross-lang-lto-clang/rustlib.rs rename to tests/run-make/cross-lang-lto-clang/rustlib.rs diff --git a/tests/run-make-fulldeps/cross-lang-lto-pgo-smoketest/Makefile b/tests/run-make/cross-lang-lto-pgo-smoketest/Makefile similarity index 100% rename from tests/run-make-fulldeps/cross-lang-lto-pgo-smoketest/Makefile rename to tests/run-make/cross-lang-lto-pgo-smoketest/Makefile diff --git a/tests/run-make-fulldeps/cross-lang-lto-pgo-smoketest/clib.c b/tests/run-make/cross-lang-lto-pgo-smoketest/clib.c similarity index 100% rename from tests/run-make-fulldeps/cross-lang-lto-pgo-smoketest/clib.c rename to tests/run-make/cross-lang-lto-pgo-smoketest/clib.c diff --git a/tests/run-make-fulldeps/cross-lang-lto-pgo-smoketest/cmain.c b/tests/run-make/cross-lang-lto-pgo-smoketest/cmain.c similarity index 100% rename from tests/run-make-fulldeps/cross-lang-lto-pgo-smoketest/cmain.c rename to tests/run-make/cross-lang-lto-pgo-smoketest/cmain.c diff --git a/tests/run-make-fulldeps/cross-lang-lto-pgo-smoketest/main.rs b/tests/run-make/cross-lang-lto-pgo-smoketest/main.rs similarity index 100% rename from tests/run-make-fulldeps/cross-lang-lto-pgo-smoketest/main.rs rename to tests/run-make/cross-lang-lto-pgo-smoketest/main.rs diff --git a/tests/run-make-fulldeps/cross-lang-lto-pgo-smoketest/rustlib.rs b/tests/run-make/cross-lang-lto-pgo-smoketest/rustlib.rs similarity index 100% rename from tests/run-make-fulldeps/cross-lang-lto-pgo-smoketest/rustlib.rs rename to tests/run-make/cross-lang-lto-pgo-smoketest/rustlib.rs diff --git a/tests/run-make-fulldeps/cross-lang-lto-upstream-rlibs/Makefile b/tests/run-make/cross-lang-lto-upstream-rlibs/Makefile similarity index 100% rename from tests/run-make-fulldeps/cross-lang-lto-upstream-rlibs/Makefile rename to tests/run-make/cross-lang-lto-upstream-rlibs/Makefile diff --git a/tests/run-make-fulldeps/cross-lang-lto-upstream-rlibs/staticlib.rs b/tests/run-make/cross-lang-lto-upstream-rlibs/staticlib.rs similarity index 100% rename from tests/run-make-fulldeps/cross-lang-lto-upstream-rlibs/staticlib.rs rename to tests/run-make/cross-lang-lto-upstream-rlibs/staticlib.rs diff --git a/tests/run-make-fulldeps/cross-lang-lto-upstream-rlibs/upstream.rs b/tests/run-make/cross-lang-lto-upstream-rlibs/upstream.rs similarity index 100% rename from tests/run-make-fulldeps/cross-lang-lto-upstream-rlibs/upstream.rs rename to tests/run-make/cross-lang-lto-upstream-rlibs/upstream.rs diff --git a/tests/run-make-fulldeps/cross-lang-lto/Makefile b/tests/run-make/cross-lang-lto/Makefile similarity index 100% rename from tests/run-make-fulldeps/cross-lang-lto/Makefile rename to tests/run-make/cross-lang-lto/Makefile diff --git a/tests/run-make-fulldeps/cross-lang-lto/lib.rs b/tests/run-make/cross-lang-lto/lib.rs similarity index 100% rename from tests/run-make-fulldeps/cross-lang-lto/lib.rs rename to tests/run-make/cross-lang-lto/lib.rs diff --git a/tests/run-make-fulldeps/cross-lang-lto/main.rs b/tests/run-make/cross-lang-lto/main.rs similarity index 100% rename from tests/run-make-fulldeps/cross-lang-lto/main.rs rename to tests/run-make/cross-lang-lto/main.rs diff --git a/tests/run-make-fulldeps/debug-assertions/Makefile b/tests/run-make/debug-assertions/Makefile similarity index 100% rename from tests/run-make-fulldeps/debug-assertions/Makefile rename to tests/run-make/debug-assertions/Makefile diff --git a/tests/run-make-fulldeps/debug-assertions/debug.rs b/tests/run-make/debug-assertions/debug.rs similarity index 100% rename from tests/run-make-fulldeps/debug-assertions/debug.rs rename to tests/run-make/debug-assertions/debug.rs diff --git a/tests/run-make-fulldeps/dep-info-doesnt-run-much/Makefile b/tests/run-make/dep-info-doesnt-run-much/Makefile similarity index 100% rename from tests/run-make-fulldeps/dep-info-doesnt-run-much/Makefile rename to tests/run-make/dep-info-doesnt-run-much/Makefile diff --git a/tests/run-make-fulldeps/dep-info-doesnt-run-much/foo.rs b/tests/run-make/dep-info-doesnt-run-much/foo.rs similarity index 100% rename from tests/run-make-fulldeps/dep-info-doesnt-run-much/foo.rs rename to tests/run-make/dep-info-doesnt-run-much/foo.rs diff --git a/tests/run-make-fulldeps/dep-info-spaces/Makefile b/tests/run-make/dep-info-spaces/Makefile similarity index 100% rename from tests/run-make-fulldeps/dep-info-spaces/Makefile rename to tests/run-make/dep-info-spaces/Makefile diff --git a/tests/run-make-fulldeps/dep-info-spaces/Makefile.foo b/tests/run-make/dep-info-spaces/Makefile.foo similarity index 100% rename from tests/run-make-fulldeps/dep-info-spaces/Makefile.foo rename to tests/run-make/dep-info-spaces/Makefile.foo diff --git a/tests/run-make-fulldeps/dep-info-spaces/bar.rs b/tests/run-make/dep-info-spaces/bar.rs similarity index 100% rename from tests/run-make-fulldeps/dep-info-spaces/bar.rs rename to tests/run-make/dep-info-spaces/bar.rs diff --git a/tests/run-make-fulldeps/dep-info-spaces/foo foo.rs b/tests/run-make/dep-info-spaces/foo foo.rs similarity index 100% rename from tests/run-make-fulldeps/dep-info-spaces/foo foo.rs rename to tests/run-make/dep-info-spaces/foo foo.rs diff --git a/tests/run-make-fulldeps/dep-info-spaces/lib.rs b/tests/run-make/dep-info-spaces/lib.rs similarity index 100% rename from tests/run-make-fulldeps/dep-info-spaces/lib.rs rename to tests/run-make/dep-info-spaces/lib.rs diff --git a/tests/run-make-fulldeps/dep-info/Makefile b/tests/run-make/dep-info/Makefile similarity index 100% rename from tests/run-make-fulldeps/dep-info/Makefile rename to tests/run-make/dep-info/Makefile diff --git a/tests/run-make-fulldeps/dep-info/Makefile.foo b/tests/run-make/dep-info/Makefile.foo similarity index 100% rename from tests/run-make-fulldeps/dep-info/Makefile.foo rename to tests/run-make/dep-info/Makefile.foo diff --git a/tests/run-make-fulldeps/dep-info/bar.rs b/tests/run-make/dep-info/bar.rs similarity index 100% rename from tests/run-make-fulldeps/dep-info/bar.rs rename to tests/run-make/dep-info/bar.rs diff --git a/tests/run-make-fulldeps/dep-info/foo.rs b/tests/run-make/dep-info/foo.rs similarity index 100% rename from tests/run-make-fulldeps/dep-info/foo.rs rename to tests/run-make/dep-info/foo.rs diff --git a/tests/run-make-fulldeps/dep-info/lib.rs b/tests/run-make/dep-info/lib.rs similarity index 100% rename from tests/run-make-fulldeps/dep-info/lib.rs rename to tests/run-make/dep-info/lib.rs diff --git a/tests/run-make-fulldeps/dep-info/lib2.rs b/tests/run-make/dep-info/lib2.rs similarity index 100% rename from tests/run-make-fulldeps/dep-info/lib2.rs rename to tests/run-make/dep-info/lib2.rs diff --git a/tests/run-make-fulldeps/doctests-keep-binaries/Makefile b/tests/run-make/doctests-keep-binaries/Makefile similarity index 100% rename from tests/run-make-fulldeps/doctests-keep-binaries/Makefile rename to tests/run-make/doctests-keep-binaries/Makefile diff --git a/tests/run-make-fulldeps/doctests-keep-binaries/t.rs b/tests/run-make/doctests-keep-binaries/t.rs similarity index 100% rename from tests/run-make-fulldeps/doctests-keep-binaries/t.rs rename to tests/run-make/doctests-keep-binaries/t.rs diff --git a/tests/run-make-fulldeps/duplicate-output-flavors/Makefile b/tests/run-make/duplicate-output-flavors/Makefile similarity index 100% rename from tests/run-make-fulldeps/duplicate-output-flavors/Makefile rename to tests/run-make/duplicate-output-flavors/Makefile diff --git a/tests/run-make-fulldeps/duplicate-output-flavors/foo.rs b/tests/run-make/duplicate-output-flavors/foo.rs similarity index 100% rename from tests/run-make-fulldeps/duplicate-output-flavors/foo.rs rename to tests/run-make/duplicate-output-flavors/foo.rs diff --git a/tests/run-make-fulldeps/dylib-chain/Makefile b/tests/run-make/dylib-chain/Makefile similarity index 100% rename from tests/run-make-fulldeps/dylib-chain/Makefile rename to tests/run-make/dylib-chain/Makefile diff --git a/tests/run-make-fulldeps/dylib-chain/m1.rs b/tests/run-make/dylib-chain/m1.rs similarity index 100% rename from tests/run-make-fulldeps/dylib-chain/m1.rs rename to tests/run-make/dylib-chain/m1.rs diff --git a/tests/run-make-fulldeps/dylib-chain/m2.rs b/tests/run-make/dylib-chain/m2.rs similarity index 100% rename from tests/run-make-fulldeps/dylib-chain/m2.rs rename to tests/run-make/dylib-chain/m2.rs diff --git a/tests/run-make-fulldeps/dylib-chain/m3.rs b/tests/run-make/dylib-chain/m3.rs similarity index 100% rename from tests/run-make-fulldeps/dylib-chain/m3.rs rename to tests/run-make/dylib-chain/m3.rs diff --git a/tests/run-make-fulldeps/dylib-chain/m4.rs b/tests/run-make/dylib-chain/m4.rs similarity index 100% rename from tests/run-make-fulldeps/dylib-chain/m4.rs rename to tests/run-make/dylib-chain/m4.rs diff --git a/tests/run-make-fulldeps/emit-stack-sizes/Makefile b/tests/run-make/emit-stack-sizes/Makefile similarity index 100% rename from tests/run-make-fulldeps/emit-stack-sizes/Makefile rename to tests/run-make/emit-stack-sizes/Makefile diff --git a/tests/run-make-fulldeps/emit-stack-sizes/foo.rs b/tests/run-make/emit-stack-sizes/foo.rs similarity index 100% rename from tests/run-make-fulldeps/emit-stack-sizes/foo.rs rename to tests/run-make/emit-stack-sizes/foo.rs diff --git a/tests/run-make-fulldeps/emit/Makefile b/tests/run-make/emit/Makefile similarity index 100% rename from tests/run-make-fulldeps/emit/Makefile rename to tests/run-make/emit/Makefile diff --git a/tests/run-make-fulldeps/emit/test-24876.rs b/tests/run-make/emit/test-24876.rs similarity index 100% rename from tests/run-make-fulldeps/emit/test-24876.rs rename to tests/run-make/emit/test-24876.rs diff --git a/tests/run-make-fulldeps/emit/test-26235.rs b/tests/run-make/emit/test-26235.rs similarity index 100% rename from tests/run-make-fulldeps/emit/test-26235.rs rename to tests/run-make/emit/test-26235.rs diff --git a/tests/run-make-fulldeps/error-found-staticlib-instead-crate/Makefile b/tests/run-make/error-found-staticlib-instead-crate/Makefile similarity index 100% rename from tests/run-make-fulldeps/error-found-staticlib-instead-crate/Makefile rename to tests/run-make/error-found-staticlib-instead-crate/Makefile diff --git a/tests/run-make-fulldeps/error-found-staticlib-instead-crate/bar.rs b/tests/run-make/error-found-staticlib-instead-crate/bar.rs similarity index 100% rename from tests/run-make-fulldeps/error-found-staticlib-instead-crate/bar.rs rename to tests/run-make/error-found-staticlib-instead-crate/bar.rs diff --git a/tests/run-make-fulldeps/error-found-staticlib-instead-crate/foo.rs b/tests/run-make/error-found-staticlib-instead-crate/foo.rs similarity index 100% rename from tests/run-make-fulldeps/error-found-staticlib-instead-crate/foo.rs rename to tests/run-make/error-found-staticlib-instead-crate/foo.rs diff --git a/tests/run-make-fulldeps/error-writing-dependencies/Makefile b/tests/run-make/error-writing-dependencies/Makefile similarity index 100% rename from tests/run-make-fulldeps/error-writing-dependencies/Makefile rename to tests/run-make/error-writing-dependencies/Makefile diff --git a/tests/run-make-fulldeps/error-writing-dependencies/foo.rs b/tests/run-make/error-writing-dependencies/foo.rs similarity index 100% rename from tests/run-make-fulldeps/error-writing-dependencies/foo.rs rename to tests/run-make/error-writing-dependencies/foo.rs diff --git a/tests/run-make-fulldeps/exit-code/Makefile b/tests/run-make/exit-code/Makefile similarity index 100% rename from tests/run-make-fulldeps/exit-code/Makefile rename to tests/run-make/exit-code/Makefile diff --git a/tests/run-make-fulldeps/exit-code/compile-error.rs b/tests/run-make/exit-code/compile-error.rs similarity index 100% rename from tests/run-make-fulldeps/exit-code/compile-error.rs rename to tests/run-make/exit-code/compile-error.rs diff --git a/tests/run-make-fulldeps/exit-code/lint-failure.rs b/tests/run-make/exit-code/lint-failure.rs similarity index 100% rename from tests/run-make-fulldeps/exit-code/lint-failure.rs rename to tests/run-make/exit-code/lint-failure.rs diff --git a/tests/run-make-fulldeps/exit-code/success.rs b/tests/run-make/exit-code/success.rs similarity index 100% rename from tests/run-make-fulldeps/exit-code/success.rs rename to tests/run-make/exit-code/success.rs diff --git a/tests/run-make-fulldeps/extern-diff-internal-name/Makefile b/tests/run-make/extern-diff-internal-name/Makefile similarity index 100% rename from tests/run-make-fulldeps/extern-diff-internal-name/Makefile rename to tests/run-make/extern-diff-internal-name/Makefile diff --git a/tests/run-make-fulldeps/extern-diff-internal-name/lib.rs b/tests/run-make/extern-diff-internal-name/lib.rs similarity index 100% rename from tests/run-make-fulldeps/extern-diff-internal-name/lib.rs rename to tests/run-make/extern-diff-internal-name/lib.rs diff --git a/tests/run-make-fulldeps/extern-diff-internal-name/test.rs b/tests/run-make/extern-diff-internal-name/test.rs similarity index 100% rename from tests/run-make-fulldeps/extern-diff-internal-name/test.rs rename to tests/run-make/extern-diff-internal-name/test.rs diff --git a/tests/run-make-fulldeps/extern-flag-disambiguates/Makefile b/tests/run-make/extern-flag-disambiguates/Makefile similarity index 100% rename from tests/run-make-fulldeps/extern-flag-disambiguates/Makefile rename to tests/run-make/extern-flag-disambiguates/Makefile diff --git a/tests/run-make-fulldeps/extern-flag-disambiguates/a.rs b/tests/run-make/extern-flag-disambiguates/a.rs similarity index 100% rename from tests/run-make-fulldeps/extern-flag-disambiguates/a.rs rename to tests/run-make/extern-flag-disambiguates/a.rs diff --git a/tests/run-make-fulldeps/extern-flag-disambiguates/b.rs b/tests/run-make/extern-flag-disambiguates/b.rs similarity index 100% rename from tests/run-make-fulldeps/extern-flag-disambiguates/b.rs rename to tests/run-make/extern-flag-disambiguates/b.rs diff --git a/tests/run-make-fulldeps/extern-flag-disambiguates/c.rs b/tests/run-make/extern-flag-disambiguates/c.rs similarity index 100% rename from tests/run-make-fulldeps/extern-flag-disambiguates/c.rs rename to tests/run-make/extern-flag-disambiguates/c.rs diff --git a/tests/run-make-fulldeps/extern-flag-disambiguates/d.rs b/tests/run-make/extern-flag-disambiguates/d.rs similarity index 100% rename from tests/run-make-fulldeps/extern-flag-disambiguates/d.rs rename to tests/run-make/extern-flag-disambiguates/d.rs diff --git a/tests/run-make-fulldeps/extern-flag-fun/Makefile b/tests/run-make/extern-flag-fun/Makefile similarity index 100% rename from tests/run-make-fulldeps/extern-flag-fun/Makefile rename to tests/run-make/extern-flag-fun/Makefile diff --git a/tests/run-make-fulldeps/extern-flag-fun/bar-alt.rs b/tests/run-make/extern-flag-fun/bar-alt.rs similarity index 100% rename from tests/run-make-fulldeps/extern-flag-fun/bar-alt.rs rename to tests/run-make/extern-flag-fun/bar-alt.rs diff --git a/tests/run-make-fulldeps/extern-flag-fun/bar.rs b/tests/run-make/extern-flag-fun/bar.rs similarity index 100% rename from tests/run-make-fulldeps/extern-flag-fun/bar.rs rename to tests/run-make/extern-flag-fun/bar.rs diff --git a/tests/run-make-fulldeps/extern-flag-fun/foo.rs b/tests/run-make/extern-flag-fun/foo.rs similarity index 100% rename from tests/run-make-fulldeps/extern-flag-fun/foo.rs rename to tests/run-make/extern-flag-fun/foo.rs diff --git a/tests/run-make-fulldeps/extern-flag-fun/gated_unstable.rs b/tests/run-make/extern-flag-fun/gated_unstable.rs similarity index 100% rename from tests/run-make-fulldeps/extern-flag-fun/gated_unstable.rs rename to tests/run-make/extern-flag-fun/gated_unstable.rs diff --git a/tests/run-make-fulldeps/extern-flag-fun/rustc.rs b/tests/run-make/extern-flag-fun/rustc.rs similarity index 100% rename from tests/run-make-fulldeps/extern-flag-fun/rustc.rs rename to tests/run-make/extern-flag-fun/rustc.rs diff --git a/tests/run-make-fulldeps/extern-flag-pathless/Makefile b/tests/run-make/extern-flag-pathless/Makefile similarity index 100% rename from tests/run-make-fulldeps/extern-flag-pathless/Makefile rename to tests/run-make/extern-flag-pathless/Makefile diff --git a/tests/run-make-fulldeps/extern-flag-pathless/bar-dynamic.rs b/tests/run-make/extern-flag-pathless/bar-dynamic.rs similarity index 100% rename from tests/run-make-fulldeps/extern-flag-pathless/bar-dynamic.rs rename to tests/run-make/extern-flag-pathless/bar-dynamic.rs diff --git a/tests/run-make-fulldeps/extern-flag-pathless/bar-static.rs b/tests/run-make/extern-flag-pathless/bar-static.rs similarity index 100% rename from tests/run-make-fulldeps/extern-flag-pathless/bar-static.rs rename to tests/run-make/extern-flag-pathless/bar-static.rs diff --git a/tests/run-make-fulldeps/extern-flag-pathless/foo.rs b/tests/run-make/extern-flag-pathless/foo.rs similarity index 100% rename from tests/run-make-fulldeps/extern-flag-pathless/foo.rs rename to tests/run-make/extern-flag-pathless/foo.rs diff --git a/tests/run-make-fulldeps/extern-flag-rename-transitive/Makefile b/tests/run-make/extern-flag-rename-transitive/Makefile similarity index 100% rename from tests/run-make-fulldeps/extern-flag-rename-transitive/Makefile rename to tests/run-make/extern-flag-rename-transitive/Makefile diff --git a/tests/run-make-fulldeps/extern-flag-rename-transitive/bar.rs b/tests/run-make/extern-flag-rename-transitive/bar.rs similarity index 100% rename from tests/run-make-fulldeps/extern-flag-rename-transitive/bar.rs rename to tests/run-make/extern-flag-rename-transitive/bar.rs diff --git a/tests/run-make-fulldeps/extern-flag-rename-transitive/baz.rs b/tests/run-make/extern-flag-rename-transitive/baz.rs similarity index 100% rename from tests/run-make-fulldeps/extern-flag-rename-transitive/baz.rs rename to tests/run-make/extern-flag-rename-transitive/baz.rs diff --git a/tests/run-make-fulldeps/extern-flag-rename-transitive/foo.rs b/tests/run-make/extern-flag-rename-transitive/foo.rs similarity index 100% rename from tests/run-make-fulldeps/extern-flag-rename-transitive/foo.rs rename to tests/run-make/extern-flag-rename-transitive/foo.rs diff --git a/tests/run-make-fulldeps/extern-fn-generic/Makefile b/tests/run-make/extern-fn-generic/Makefile similarity index 100% rename from tests/run-make-fulldeps/extern-fn-generic/Makefile rename to tests/run-make/extern-fn-generic/Makefile diff --git a/tests/run-make-fulldeps/extern-fn-generic/test.c b/tests/run-make/extern-fn-generic/test.c similarity index 100% rename from tests/run-make-fulldeps/extern-fn-generic/test.c rename to tests/run-make/extern-fn-generic/test.c diff --git a/tests/run-make-fulldeps/extern-fn-generic/test.rs b/tests/run-make/extern-fn-generic/test.rs similarity index 100% rename from tests/run-make-fulldeps/extern-fn-generic/test.rs rename to tests/run-make/extern-fn-generic/test.rs diff --git a/tests/run-make-fulldeps/extern-fn-generic/testcrate.rs b/tests/run-make/extern-fn-generic/testcrate.rs similarity index 100% rename from tests/run-make-fulldeps/extern-fn-generic/testcrate.rs rename to tests/run-make/extern-fn-generic/testcrate.rs diff --git a/tests/run-make-fulldeps/extern-fn-mangle/Makefile b/tests/run-make/extern-fn-mangle/Makefile similarity index 100% rename from tests/run-make-fulldeps/extern-fn-mangle/Makefile rename to tests/run-make/extern-fn-mangle/Makefile diff --git a/tests/run-make-fulldeps/extern-fn-mangle/test.c b/tests/run-make/extern-fn-mangle/test.c similarity index 100% rename from tests/run-make-fulldeps/extern-fn-mangle/test.c rename to tests/run-make/extern-fn-mangle/test.c diff --git a/tests/run-make-fulldeps/extern-fn-mangle/test.rs b/tests/run-make/extern-fn-mangle/test.rs similarity index 100% rename from tests/run-make-fulldeps/extern-fn-mangle/test.rs rename to tests/run-make/extern-fn-mangle/test.rs diff --git a/tests/run-make-fulldeps/extern-fn-reachable/Makefile b/tests/run-make/extern-fn-reachable/Makefile similarity index 100% rename from tests/run-make-fulldeps/extern-fn-reachable/Makefile rename to tests/run-make/extern-fn-reachable/Makefile diff --git a/tests/run-make-fulldeps/extern-fn-reachable/dylib.rs b/tests/run-make/extern-fn-reachable/dylib.rs similarity index 100% rename from tests/run-make-fulldeps/extern-fn-reachable/dylib.rs rename to tests/run-make/extern-fn-reachable/dylib.rs diff --git a/tests/run-make-fulldeps/extern-fn-struct-passing-abi/Makefile b/tests/run-make/extern-fn-struct-passing-abi/Makefile similarity index 100% rename from tests/run-make-fulldeps/extern-fn-struct-passing-abi/Makefile rename to tests/run-make/extern-fn-struct-passing-abi/Makefile diff --git a/tests/run-make-fulldeps/extern-fn-struct-passing-abi/test.c b/tests/run-make/extern-fn-struct-passing-abi/test.c similarity index 100% rename from tests/run-make-fulldeps/extern-fn-struct-passing-abi/test.c rename to tests/run-make/extern-fn-struct-passing-abi/test.c diff --git a/tests/run-make-fulldeps/extern-fn-struct-passing-abi/test.rs b/tests/run-make/extern-fn-struct-passing-abi/test.rs similarity index 100% rename from tests/run-make-fulldeps/extern-fn-struct-passing-abi/test.rs rename to tests/run-make/extern-fn-struct-passing-abi/test.rs diff --git a/tests/run-make-fulldeps/extern-fn-with-extern-types/Makefile b/tests/run-make/extern-fn-with-extern-types/Makefile similarity index 100% rename from tests/run-make-fulldeps/extern-fn-with-extern-types/Makefile rename to tests/run-make/extern-fn-with-extern-types/Makefile diff --git a/tests/run-make-fulldeps/extern-fn-with-extern-types/ctest.c b/tests/run-make/extern-fn-with-extern-types/ctest.c similarity index 100% rename from tests/run-make-fulldeps/extern-fn-with-extern-types/ctest.c rename to tests/run-make/extern-fn-with-extern-types/ctest.c diff --git a/tests/run-make-fulldeps/extern-fn-with-extern-types/test.rs b/tests/run-make/extern-fn-with-extern-types/test.rs similarity index 100% rename from tests/run-make-fulldeps/extern-fn-with-extern-types/test.rs rename to tests/run-make/extern-fn-with-extern-types/test.rs diff --git a/tests/run-make-fulldeps/extern-fn-with-packed-struct/Makefile b/tests/run-make/extern-fn-with-packed-struct/Makefile similarity index 100% rename from tests/run-make-fulldeps/extern-fn-with-packed-struct/Makefile rename to tests/run-make/extern-fn-with-packed-struct/Makefile diff --git a/tests/run-make-fulldeps/extern-fn-with-packed-struct/test.c b/tests/run-make/extern-fn-with-packed-struct/test.c similarity index 100% rename from tests/run-make-fulldeps/extern-fn-with-packed-struct/test.c rename to tests/run-make/extern-fn-with-packed-struct/test.c diff --git a/tests/run-make-fulldeps/extern-fn-with-packed-struct/test.rs b/tests/run-make/extern-fn-with-packed-struct/test.rs similarity index 100% rename from tests/run-make-fulldeps/extern-fn-with-packed-struct/test.rs rename to tests/run-make/extern-fn-with-packed-struct/test.rs diff --git a/tests/run-make-fulldeps/extern-fn-with-union/Makefile b/tests/run-make/extern-fn-with-union/Makefile similarity index 100% rename from tests/run-make-fulldeps/extern-fn-with-union/Makefile rename to tests/run-make/extern-fn-with-union/Makefile diff --git a/tests/run-make-fulldeps/extern-fn-with-union/ctest.c b/tests/run-make/extern-fn-with-union/ctest.c similarity index 100% rename from tests/run-make-fulldeps/extern-fn-with-union/ctest.c rename to tests/run-make/extern-fn-with-union/ctest.c diff --git a/tests/run-make-fulldeps/extern-fn-with-union/test.rs b/tests/run-make/extern-fn-with-union/test.rs similarity index 100% rename from tests/run-make-fulldeps/extern-fn-with-union/test.rs rename to tests/run-make/extern-fn-with-union/test.rs diff --git a/tests/run-make-fulldeps/extern-fn-with-union/testcrate.rs b/tests/run-make/extern-fn-with-union/testcrate.rs similarity index 100% rename from tests/run-make-fulldeps/extern-fn-with-union/testcrate.rs rename to tests/run-make/extern-fn-with-union/testcrate.rs diff --git a/tests/run-make-fulldeps/extern-multiple-copies/Makefile b/tests/run-make/extern-multiple-copies/Makefile similarity index 100% rename from tests/run-make-fulldeps/extern-multiple-copies/Makefile rename to tests/run-make/extern-multiple-copies/Makefile diff --git a/tests/run-make-fulldeps/extern-multiple-copies/bar.rs b/tests/run-make/extern-multiple-copies/bar.rs similarity index 100% rename from tests/run-make-fulldeps/extern-multiple-copies/bar.rs rename to tests/run-make/extern-multiple-copies/bar.rs diff --git a/tests/run-make-fulldeps/extern-multiple-copies/foo1.rs b/tests/run-make/extern-multiple-copies/foo1.rs similarity index 100% rename from tests/run-make-fulldeps/extern-multiple-copies/foo1.rs rename to tests/run-make/extern-multiple-copies/foo1.rs diff --git a/tests/run-make-fulldeps/extern-multiple-copies/foo2.rs b/tests/run-make/extern-multiple-copies/foo2.rs similarity index 100% rename from tests/run-make-fulldeps/extern-multiple-copies/foo2.rs rename to tests/run-make/extern-multiple-copies/foo2.rs diff --git a/tests/run-make-fulldeps/extern-multiple-copies2/Makefile b/tests/run-make/extern-multiple-copies2/Makefile similarity index 100% rename from tests/run-make-fulldeps/extern-multiple-copies2/Makefile rename to tests/run-make/extern-multiple-copies2/Makefile diff --git a/tests/run-make-fulldeps/extern-multiple-copies2/bar.rs b/tests/run-make/extern-multiple-copies2/bar.rs similarity index 100% rename from tests/run-make-fulldeps/extern-multiple-copies2/bar.rs rename to tests/run-make/extern-multiple-copies2/bar.rs diff --git a/tests/run-make-fulldeps/extern-multiple-copies2/foo1.rs b/tests/run-make/extern-multiple-copies2/foo1.rs similarity index 100% rename from tests/run-make-fulldeps/extern-multiple-copies2/foo1.rs rename to tests/run-make/extern-multiple-copies2/foo1.rs diff --git a/tests/run-make-fulldeps/extern-multiple-copies2/foo2.rs b/tests/run-make/extern-multiple-copies2/foo2.rs similarity index 100% rename from tests/run-make-fulldeps/extern-multiple-copies2/foo2.rs rename to tests/run-make/extern-multiple-copies2/foo2.rs diff --git a/tests/run-make-fulldeps/extern-overrides-distribution/Makefile b/tests/run-make/extern-overrides-distribution/Makefile similarity index 100% rename from tests/run-make-fulldeps/extern-overrides-distribution/Makefile rename to tests/run-make/extern-overrides-distribution/Makefile diff --git a/tests/run-make-fulldeps/extern-overrides-distribution/libc.rs b/tests/run-make/extern-overrides-distribution/libc.rs similarity index 100% rename from tests/run-make-fulldeps/extern-overrides-distribution/libc.rs rename to tests/run-make/extern-overrides-distribution/libc.rs diff --git a/tests/run-make-fulldeps/extern-overrides-distribution/main.rs b/tests/run-make/extern-overrides-distribution/main.rs similarity index 100% rename from tests/run-make-fulldeps/extern-overrides-distribution/main.rs rename to tests/run-make/extern-overrides-distribution/main.rs diff --git a/tests/run-make-fulldeps/extra-filename-with-temp-outputs/Makefile b/tests/run-make/extra-filename-with-temp-outputs/Makefile similarity index 100% rename from tests/run-make-fulldeps/extra-filename-with-temp-outputs/Makefile rename to tests/run-make/extra-filename-with-temp-outputs/Makefile diff --git a/tests/run-make-fulldeps/extra-filename-with-temp-outputs/foo.rs b/tests/run-make/extra-filename-with-temp-outputs/foo.rs similarity index 100% rename from tests/run-make-fulldeps/extra-filename-with-temp-outputs/foo.rs rename to tests/run-make/extra-filename-with-temp-outputs/foo.rs diff --git a/tests/run-make-fulldeps/foreign-double-unwind/Makefile b/tests/run-make/foreign-double-unwind/Makefile similarity index 100% rename from tests/run-make-fulldeps/foreign-double-unwind/Makefile rename to tests/run-make/foreign-double-unwind/Makefile diff --git a/tests/run-make-fulldeps/foreign-double-unwind/foo.cpp b/tests/run-make/foreign-double-unwind/foo.cpp similarity index 100% rename from tests/run-make-fulldeps/foreign-double-unwind/foo.cpp rename to tests/run-make/foreign-double-unwind/foo.cpp diff --git a/tests/run-make-fulldeps/foreign-double-unwind/foo.rs b/tests/run-make/foreign-double-unwind/foo.rs similarity index 100% rename from tests/run-make-fulldeps/foreign-double-unwind/foo.rs rename to tests/run-make/foreign-double-unwind/foo.rs diff --git a/tests/run-make-fulldeps/foreign-exceptions/Makefile b/tests/run-make/foreign-exceptions/Makefile similarity index 100% rename from tests/run-make-fulldeps/foreign-exceptions/Makefile rename to tests/run-make/foreign-exceptions/Makefile diff --git a/tests/run-make-fulldeps/foreign-exceptions/foo.cpp b/tests/run-make/foreign-exceptions/foo.cpp similarity index 100% rename from tests/run-make-fulldeps/foreign-exceptions/foo.cpp rename to tests/run-make/foreign-exceptions/foo.cpp diff --git a/tests/run-make-fulldeps/foreign-exceptions/foo.rs b/tests/run-make/foreign-exceptions/foo.rs similarity index 100% rename from tests/run-make-fulldeps/foreign-exceptions/foo.rs rename to tests/run-make/foreign-exceptions/foo.rs diff --git a/tests/run-make-fulldeps/foreign-rust-exceptions/Makefile b/tests/run-make/foreign-rust-exceptions/Makefile similarity index 100% rename from tests/run-make-fulldeps/foreign-rust-exceptions/Makefile rename to tests/run-make/foreign-rust-exceptions/Makefile diff --git a/tests/run-make-fulldeps/foreign-rust-exceptions/bar.rs b/tests/run-make/foreign-rust-exceptions/bar.rs similarity index 100% rename from tests/run-make-fulldeps/foreign-rust-exceptions/bar.rs rename to tests/run-make/foreign-rust-exceptions/bar.rs diff --git a/tests/run-make-fulldeps/foreign-rust-exceptions/foo.rs b/tests/run-make/foreign-rust-exceptions/foo.rs similarity index 100% rename from tests/run-make-fulldeps/foreign-rust-exceptions/foo.rs rename to tests/run-make/foreign-rust-exceptions/foo.rs diff --git a/tests/run-make-fulldeps/fpic/Makefile b/tests/run-make/fpic/Makefile similarity index 100% rename from tests/run-make-fulldeps/fpic/Makefile rename to tests/run-make/fpic/Makefile diff --git a/tests/run-make-fulldeps/fpic/hello.rs b/tests/run-make/fpic/hello.rs similarity index 100% rename from tests/run-make-fulldeps/fpic/hello.rs rename to tests/run-make/fpic/hello.rs diff --git a/tests/run-make-fulldeps/glibc-staticlib-args/Makefile b/tests/run-make/glibc-staticlib-args/Makefile similarity index 100% rename from tests/run-make-fulldeps/glibc-staticlib-args/Makefile rename to tests/run-make/glibc-staticlib-args/Makefile diff --git a/tests/run-make-fulldeps/glibc-staticlib-args/library.rs b/tests/run-make/glibc-staticlib-args/library.rs similarity index 100% rename from tests/run-make-fulldeps/glibc-staticlib-args/library.rs rename to tests/run-make/glibc-staticlib-args/library.rs diff --git a/tests/run-make-fulldeps/glibc-staticlib-args/program.c b/tests/run-make/glibc-staticlib-args/program.c similarity index 100% rename from tests/run-make-fulldeps/glibc-staticlib-args/program.c rename to tests/run-make/glibc-staticlib-args/program.c diff --git a/tests/run-make-fulldeps/hir-tree/Makefile b/tests/run-make/hir-tree/Makefile similarity index 100% rename from tests/run-make-fulldeps/hir-tree/Makefile rename to tests/run-make/hir-tree/Makefile diff --git a/tests/run-make-fulldeps/hir-tree/input.rs b/tests/run-make/hir-tree/input.rs similarity index 100% rename from tests/run-make-fulldeps/hir-tree/input.rs rename to tests/run-make/hir-tree/input.rs diff --git a/tests/run-make-fulldeps/hotplug_codegen_backend/Makefile b/tests/run-make/hotplug_codegen_backend/Makefile similarity index 100% rename from tests/run-make-fulldeps/hotplug_codegen_backend/Makefile rename to tests/run-make/hotplug_codegen_backend/Makefile diff --git a/tests/run-make-fulldeps/hotplug_codegen_backend/some_crate.rs b/tests/run-make/hotplug_codegen_backend/some_crate.rs similarity index 100% rename from tests/run-make-fulldeps/hotplug_codegen_backend/some_crate.rs rename to tests/run-make/hotplug_codegen_backend/some_crate.rs diff --git a/tests/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs b/tests/run-make/hotplug_codegen_backend/the_backend.rs similarity index 100% rename from tests/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs rename to tests/run-make/hotplug_codegen_backend/the_backend.rs diff --git a/tests/run-make-fulldeps/include_bytes_deps/Makefile b/tests/run-make/include_bytes_deps/Makefile similarity index 100% rename from tests/run-make-fulldeps/include_bytes_deps/Makefile rename to tests/run-make/include_bytes_deps/Makefile diff --git a/tests/run-make-fulldeps/include_bytes_deps/input.bin b/tests/run-make/include_bytes_deps/input.bin similarity index 100% rename from tests/run-make-fulldeps/include_bytes_deps/input.bin rename to tests/run-make/include_bytes_deps/input.bin diff --git a/tests/run-make-fulldeps/include_bytes_deps/input.md b/tests/run-make/include_bytes_deps/input.md similarity index 100% rename from tests/run-make-fulldeps/include_bytes_deps/input.md rename to tests/run-make/include_bytes_deps/input.md diff --git a/tests/run-make-fulldeps/include_bytes_deps/input.txt b/tests/run-make/include_bytes_deps/input.txt similarity index 100% rename from tests/run-make-fulldeps/include_bytes_deps/input.txt rename to tests/run-make/include_bytes_deps/input.txt diff --git a/tests/run-make-fulldeps/include_bytes_deps/main.rs b/tests/run-make/include_bytes_deps/main.rs similarity index 100% rename from tests/run-make-fulldeps/include_bytes_deps/main.rs rename to tests/run-make/include_bytes_deps/main.rs diff --git a/tests/run-make-fulldeps/incr-add-rust-src-component/Makefile b/tests/run-make/incr-add-rust-src-component/Makefile similarity index 100% rename from tests/run-make-fulldeps/incr-add-rust-src-component/Makefile rename to tests/run-make/incr-add-rust-src-component/Makefile diff --git a/tests/run-make-fulldeps/incr-add-rust-src-component/main.rs b/tests/run-make/incr-add-rust-src-component/main.rs similarity index 100% rename from tests/run-make-fulldeps/incr-add-rust-src-component/main.rs rename to tests/run-make/incr-add-rust-src-component/main.rs diff --git a/tests/run-make-fulldeps/inline-always-many-cgu/Makefile b/tests/run-make/inline-always-many-cgu/Makefile similarity index 100% rename from tests/run-make-fulldeps/inline-always-many-cgu/Makefile rename to tests/run-make/inline-always-many-cgu/Makefile diff --git a/tests/run-make-fulldeps/inline-always-many-cgu/foo.rs b/tests/run-make/inline-always-many-cgu/foo.rs similarity index 100% rename from tests/run-make-fulldeps/inline-always-many-cgu/foo.rs rename to tests/run-make/inline-always-many-cgu/foo.rs diff --git a/tests/run-make-fulldeps/interdependent-c-libraries/Makefile b/tests/run-make/interdependent-c-libraries/Makefile similarity index 100% rename from tests/run-make-fulldeps/interdependent-c-libraries/Makefile rename to tests/run-make/interdependent-c-libraries/Makefile diff --git a/tests/run-make-fulldeps/interdependent-c-libraries/bar.c b/tests/run-make/interdependent-c-libraries/bar.c similarity index 100% rename from tests/run-make-fulldeps/interdependent-c-libraries/bar.c rename to tests/run-make/interdependent-c-libraries/bar.c diff --git a/tests/run-make-fulldeps/interdependent-c-libraries/bar.rs b/tests/run-make/interdependent-c-libraries/bar.rs similarity index 100% rename from tests/run-make-fulldeps/interdependent-c-libraries/bar.rs rename to tests/run-make/interdependent-c-libraries/bar.rs diff --git a/tests/run-make-fulldeps/interdependent-c-libraries/foo.c b/tests/run-make/interdependent-c-libraries/foo.c similarity index 100% rename from tests/run-make-fulldeps/interdependent-c-libraries/foo.c rename to tests/run-make/interdependent-c-libraries/foo.c diff --git a/tests/run-make-fulldeps/interdependent-c-libraries/foo.rs b/tests/run-make/interdependent-c-libraries/foo.rs similarity index 100% rename from tests/run-make-fulldeps/interdependent-c-libraries/foo.rs rename to tests/run-make/interdependent-c-libraries/foo.rs diff --git a/tests/run-make-fulldeps/interdependent-c-libraries/main.rs b/tests/run-make/interdependent-c-libraries/main.rs similarity index 100% rename from tests/run-make-fulldeps/interdependent-c-libraries/main.rs rename to tests/run-make/interdependent-c-libraries/main.rs diff --git a/tests/run-make-fulldeps/intrinsic-unreachable/Makefile b/tests/run-make/intrinsic-unreachable/Makefile similarity index 100% rename from tests/run-make-fulldeps/intrinsic-unreachable/Makefile rename to tests/run-make/intrinsic-unreachable/Makefile diff --git a/tests/run-make-fulldeps/intrinsic-unreachable/exit-ret.rs b/tests/run-make/intrinsic-unreachable/exit-ret.rs similarity index 100% rename from tests/run-make-fulldeps/intrinsic-unreachable/exit-ret.rs rename to tests/run-make/intrinsic-unreachable/exit-ret.rs diff --git a/tests/run-make-fulldeps/intrinsic-unreachable/exit-unreachable.rs b/tests/run-make/intrinsic-unreachable/exit-unreachable.rs similarity index 100% rename from tests/run-make-fulldeps/intrinsic-unreachable/exit-unreachable.rs rename to tests/run-make/intrinsic-unreachable/exit-unreachable.rs diff --git a/tests/run-make-fulldeps/invalid-library/Makefile b/tests/run-make/invalid-library/Makefile similarity index 100% rename from tests/run-make-fulldeps/invalid-library/Makefile rename to tests/run-make/invalid-library/Makefile diff --git a/tests/run-make-fulldeps/invalid-library/foo.rs b/tests/run-make/invalid-library/foo.rs similarity index 100% rename from tests/run-make-fulldeps/invalid-library/foo.rs rename to tests/run-make/invalid-library/foo.rs diff --git a/tests/run-make-fulldeps/invalid-staticlib/Makefile b/tests/run-make/invalid-staticlib/Makefile similarity index 100% rename from tests/run-make-fulldeps/invalid-staticlib/Makefile rename to tests/run-make/invalid-staticlib/Makefile diff --git a/tests/run-make-fulldeps/issue-11908/Makefile b/tests/run-make/issue-11908/Makefile similarity index 100% rename from tests/run-make-fulldeps/issue-11908/Makefile rename to tests/run-make/issue-11908/Makefile diff --git a/tests/run-make-fulldeps/issue-11908/bar.rs b/tests/run-make/issue-11908/bar.rs similarity index 100% rename from tests/run-make-fulldeps/issue-11908/bar.rs rename to tests/run-make/issue-11908/bar.rs diff --git a/tests/run-make-fulldeps/issue-11908/foo.rs b/tests/run-make/issue-11908/foo.rs similarity index 100% rename from tests/run-make-fulldeps/issue-11908/foo.rs rename to tests/run-make/issue-11908/foo.rs diff --git a/tests/run-make-fulldeps/issue-14500/Makefile b/tests/run-make/issue-14500/Makefile similarity index 100% rename from tests/run-make-fulldeps/issue-14500/Makefile rename to tests/run-make/issue-14500/Makefile diff --git a/tests/run-make-fulldeps/issue-14500/bar.rs b/tests/run-make/issue-14500/bar.rs similarity index 100% rename from tests/run-make-fulldeps/issue-14500/bar.rs rename to tests/run-make/issue-14500/bar.rs diff --git a/tests/run-make-fulldeps/issue-14500/foo.c b/tests/run-make/issue-14500/foo.c similarity index 100% rename from tests/run-make-fulldeps/issue-14500/foo.c rename to tests/run-make/issue-14500/foo.c diff --git a/tests/run-make-fulldeps/issue-14500/foo.rs b/tests/run-make/issue-14500/foo.rs similarity index 100% rename from tests/run-make-fulldeps/issue-14500/foo.rs rename to tests/run-make/issue-14500/foo.rs diff --git a/tests/run-make-fulldeps/issue-14698/Makefile b/tests/run-make/issue-14698/Makefile similarity index 100% rename from tests/run-make-fulldeps/issue-14698/Makefile rename to tests/run-make/issue-14698/Makefile diff --git a/tests/run-make-fulldeps/issue-14698/foo.rs b/tests/run-make/issue-14698/foo.rs similarity index 100% rename from tests/run-make-fulldeps/issue-14698/foo.rs rename to tests/run-make/issue-14698/foo.rs diff --git a/tests/run-make-fulldeps/issue-15460/Makefile b/tests/run-make/issue-15460/Makefile similarity index 100% rename from tests/run-make-fulldeps/issue-15460/Makefile rename to tests/run-make/issue-15460/Makefile diff --git a/tests/run-make-fulldeps/issue-15460/bar.rs b/tests/run-make/issue-15460/bar.rs similarity index 100% rename from tests/run-make-fulldeps/issue-15460/bar.rs rename to tests/run-make/issue-15460/bar.rs diff --git a/tests/run-make-fulldeps/issue-15460/foo.c b/tests/run-make/issue-15460/foo.c similarity index 100% rename from tests/run-make-fulldeps/issue-15460/foo.c rename to tests/run-make/issue-15460/foo.c diff --git a/tests/run-make-fulldeps/issue-15460/foo.rs b/tests/run-make/issue-15460/foo.rs similarity index 100% rename from tests/run-make-fulldeps/issue-15460/foo.rs rename to tests/run-make/issue-15460/foo.rs diff --git a/tests/run-make-fulldeps/issue-18943/Makefile b/tests/run-make/issue-18943/Makefile similarity index 100% rename from tests/run-make-fulldeps/issue-18943/Makefile rename to tests/run-make/issue-18943/Makefile diff --git a/tests/run-make-fulldeps/issue-18943/foo.rs b/tests/run-make/issue-18943/foo.rs similarity index 100% rename from tests/run-make-fulldeps/issue-18943/foo.rs rename to tests/run-make/issue-18943/foo.rs diff --git a/tests/run-make-fulldeps/issue-20626/Makefile b/tests/run-make/issue-20626/Makefile similarity index 100% rename from tests/run-make-fulldeps/issue-20626/Makefile rename to tests/run-make/issue-20626/Makefile diff --git a/tests/run-make-fulldeps/issue-20626/foo.rs b/tests/run-make/issue-20626/foo.rs similarity index 100% rename from tests/run-make-fulldeps/issue-20626/foo.rs rename to tests/run-make/issue-20626/foo.rs diff --git a/tests/run-make-fulldeps/issue-22131/Makefile b/tests/run-make/issue-22131/Makefile similarity index 100% rename from tests/run-make-fulldeps/issue-22131/Makefile rename to tests/run-make/issue-22131/Makefile diff --git a/tests/run-make-fulldeps/issue-22131/foo.rs b/tests/run-make/issue-22131/foo.rs similarity index 100% rename from tests/run-make-fulldeps/issue-22131/foo.rs rename to tests/run-make/issue-22131/foo.rs diff --git a/tests/run-make-fulldeps/issue-24445/Makefile b/tests/run-make/issue-24445/Makefile similarity index 100% rename from tests/run-make-fulldeps/issue-24445/Makefile rename to tests/run-make/issue-24445/Makefile diff --git a/tests/run-make-fulldeps/issue-24445/foo.c b/tests/run-make/issue-24445/foo.c similarity index 100% rename from tests/run-make-fulldeps/issue-24445/foo.c rename to tests/run-make/issue-24445/foo.c diff --git a/tests/run-make-fulldeps/issue-24445/foo.rs b/tests/run-make/issue-24445/foo.rs similarity index 100% rename from tests/run-make-fulldeps/issue-24445/foo.rs rename to tests/run-make/issue-24445/foo.rs diff --git a/tests/run-make-fulldeps/issue-25581/Makefile b/tests/run-make/issue-25581/Makefile similarity index 100% rename from tests/run-make-fulldeps/issue-25581/Makefile rename to tests/run-make/issue-25581/Makefile diff --git a/tests/run-make-fulldeps/issue-25581/test.c b/tests/run-make/issue-25581/test.c similarity index 100% rename from tests/run-make-fulldeps/issue-25581/test.c rename to tests/run-make/issue-25581/test.c diff --git a/tests/run-make-fulldeps/issue-25581/test.rs b/tests/run-make/issue-25581/test.rs similarity index 100% rename from tests/run-make-fulldeps/issue-25581/test.rs rename to tests/run-make/issue-25581/test.rs diff --git a/tests/run-make-fulldeps/issue-26006/Makefile b/tests/run-make/issue-26006/Makefile similarity index 100% rename from tests/run-make-fulldeps/issue-26006/Makefile rename to tests/run-make/issue-26006/Makefile diff --git a/tests/run-make-fulldeps/issue-26006/in/libc/lib.rs b/tests/run-make/issue-26006/in/libc/lib.rs similarity index 100% rename from tests/run-make-fulldeps/issue-26006/in/libc/lib.rs rename to tests/run-make/issue-26006/in/libc/lib.rs diff --git a/tests/run-make-fulldeps/issue-26006/in/time/lib.rs b/tests/run-make/issue-26006/in/time/lib.rs similarity index 100% rename from tests/run-make-fulldeps/issue-26006/in/time/lib.rs rename to tests/run-make/issue-26006/in/time/lib.rs diff --git a/tests/run-make-fulldeps/issue-26092/Makefile b/tests/run-make/issue-26092/Makefile similarity index 100% rename from tests/run-make-fulldeps/issue-26092/Makefile rename to tests/run-make/issue-26092/Makefile diff --git a/tests/run-make-fulldeps/issue-26092/blank.rs b/tests/run-make/issue-26092/blank.rs similarity index 100% rename from tests/run-make-fulldeps/issue-26092/blank.rs rename to tests/run-make/issue-26092/blank.rs diff --git a/tests/run-make-fulldeps/issue-28595/Makefile b/tests/run-make/issue-28595/Makefile similarity index 100% rename from tests/run-make-fulldeps/issue-28595/Makefile rename to tests/run-make/issue-28595/Makefile diff --git a/tests/run-make-fulldeps/issue-28595/a.c b/tests/run-make/issue-28595/a.c similarity index 100% rename from tests/run-make-fulldeps/issue-28595/a.c rename to tests/run-make/issue-28595/a.c diff --git a/tests/run-make-fulldeps/issue-28595/a.rs b/tests/run-make/issue-28595/a.rs similarity index 100% rename from tests/run-make-fulldeps/issue-28595/a.rs rename to tests/run-make/issue-28595/a.rs diff --git a/tests/run-make-fulldeps/issue-28595/b.c b/tests/run-make/issue-28595/b.c similarity index 100% rename from tests/run-make-fulldeps/issue-28595/b.c rename to tests/run-make/issue-28595/b.c diff --git a/tests/run-make-fulldeps/issue-28595/b.rs b/tests/run-make/issue-28595/b.rs similarity index 100% rename from tests/run-make-fulldeps/issue-28595/b.rs rename to tests/run-make/issue-28595/b.rs diff --git a/tests/run-make-fulldeps/issue-28766/Makefile b/tests/run-make/issue-28766/Makefile similarity index 100% rename from tests/run-make-fulldeps/issue-28766/Makefile rename to tests/run-make/issue-28766/Makefile diff --git a/tests/run-make-fulldeps/issue-28766/foo.rs b/tests/run-make/issue-28766/foo.rs similarity index 100% rename from tests/run-make-fulldeps/issue-28766/foo.rs rename to tests/run-make/issue-28766/foo.rs diff --git a/tests/run-make-fulldeps/issue-28766/main.rs b/tests/run-make/issue-28766/main.rs similarity index 100% rename from tests/run-make-fulldeps/issue-28766/main.rs rename to tests/run-make/issue-28766/main.rs diff --git a/tests/run-make-fulldeps/issue-30063/Makefile b/tests/run-make/issue-30063/Makefile similarity index 100% rename from tests/run-make-fulldeps/issue-30063/Makefile rename to tests/run-make/issue-30063/Makefile diff --git a/tests/run-make-fulldeps/issue-30063/foo.rs b/tests/run-make/issue-30063/foo.rs similarity index 100% rename from tests/run-make-fulldeps/issue-30063/foo.rs rename to tests/run-make/issue-30063/foo.rs diff --git a/tests/run-make-fulldeps/issue-33329/Makefile b/tests/run-make/issue-33329/Makefile similarity index 100% rename from tests/run-make-fulldeps/issue-33329/Makefile rename to tests/run-make/issue-33329/Makefile diff --git a/tests/run-make-fulldeps/issue-33329/main.rs b/tests/run-make/issue-33329/main.rs similarity index 100% rename from tests/run-make-fulldeps/issue-33329/main.rs rename to tests/run-make/issue-33329/main.rs diff --git a/tests/run-make-fulldeps/issue-35164/Makefile b/tests/run-make/issue-35164/Makefile similarity index 100% rename from tests/run-make-fulldeps/issue-35164/Makefile rename to tests/run-make/issue-35164/Makefile diff --git a/tests/run-make-fulldeps/issue-35164/main.rs b/tests/run-make/issue-35164/main.rs similarity index 100% rename from tests/run-make-fulldeps/issue-35164/main.rs rename to tests/run-make/issue-35164/main.rs diff --git a/tests/run-make-fulldeps/issue-35164/submodule/mod.rs b/tests/run-make/issue-35164/submodule/mod.rs similarity index 100% rename from tests/run-make-fulldeps/issue-35164/submodule/mod.rs rename to tests/run-make/issue-35164/submodule/mod.rs diff --git a/tests/run-make-fulldeps/issue-37839/Makefile b/tests/run-make/issue-37839/Makefile similarity index 100% rename from tests/run-make-fulldeps/issue-37839/Makefile rename to tests/run-make/issue-37839/Makefile diff --git a/tests/run-make-fulldeps/issue-37839/a.rs b/tests/run-make/issue-37839/a.rs similarity index 100% rename from tests/run-make-fulldeps/issue-37839/a.rs rename to tests/run-make/issue-37839/a.rs diff --git a/tests/run-make-fulldeps/issue-37839/b.rs b/tests/run-make/issue-37839/b.rs similarity index 100% rename from tests/run-make-fulldeps/issue-37839/b.rs rename to tests/run-make/issue-37839/b.rs diff --git a/tests/run-make-fulldeps/issue-37839/c.rs b/tests/run-make/issue-37839/c.rs similarity index 100% rename from tests/run-make-fulldeps/issue-37839/c.rs rename to tests/run-make/issue-37839/c.rs diff --git a/tests/run-make-fulldeps/issue-37893/Makefile b/tests/run-make/issue-37893/Makefile similarity index 100% rename from tests/run-make-fulldeps/issue-37893/Makefile rename to tests/run-make/issue-37893/Makefile diff --git a/tests/run-make-fulldeps/issue-37893/a.rs b/tests/run-make/issue-37893/a.rs similarity index 100% rename from tests/run-make-fulldeps/issue-37893/a.rs rename to tests/run-make/issue-37893/a.rs diff --git a/tests/run-make-fulldeps/issue-37893/b.rs b/tests/run-make/issue-37893/b.rs similarity index 100% rename from tests/run-make-fulldeps/issue-37893/b.rs rename to tests/run-make/issue-37893/b.rs diff --git a/tests/run-make-fulldeps/issue-37893/c.rs b/tests/run-make/issue-37893/c.rs similarity index 100% rename from tests/run-make-fulldeps/issue-37893/c.rs rename to tests/run-make/issue-37893/c.rs diff --git a/tests/run-make-fulldeps/issue-38237/Makefile b/tests/run-make/issue-38237/Makefile similarity index 100% rename from tests/run-make-fulldeps/issue-38237/Makefile rename to tests/run-make/issue-38237/Makefile diff --git a/tests/run-make-fulldeps/issue-38237/bar.rs b/tests/run-make/issue-38237/bar.rs similarity index 100% rename from tests/run-make-fulldeps/issue-38237/bar.rs rename to tests/run-make/issue-38237/bar.rs diff --git a/tests/run-make-fulldeps/issue-38237/baz.rs b/tests/run-make/issue-38237/baz.rs similarity index 100% rename from tests/run-make-fulldeps/issue-38237/baz.rs rename to tests/run-make/issue-38237/baz.rs diff --git a/tests/run-make-fulldeps/issue-38237/foo.rs b/tests/run-make/issue-38237/foo.rs similarity index 100% rename from tests/run-make-fulldeps/issue-38237/foo.rs rename to tests/run-make/issue-38237/foo.rs diff --git a/tests/run-make-fulldeps/issue-40535/Makefile b/tests/run-make/issue-40535/Makefile similarity index 100% rename from tests/run-make-fulldeps/issue-40535/Makefile rename to tests/run-make/issue-40535/Makefile diff --git a/tests/run-make-fulldeps/issue-40535/bar.rs b/tests/run-make/issue-40535/bar.rs similarity index 100% rename from tests/run-make-fulldeps/issue-40535/bar.rs rename to tests/run-make/issue-40535/bar.rs diff --git a/tests/run-make-fulldeps/issue-40535/baz.rs b/tests/run-make/issue-40535/baz.rs similarity index 100% rename from tests/run-make-fulldeps/issue-40535/baz.rs rename to tests/run-make/issue-40535/baz.rs diff --git a/tests/run-make-fulldeps/issue-40535/foo.rs b/tests/run-make/issue-40535/foo.rs similarity index 100% rename from tests/run-make-fulldeps/issue-40535/foo.rs rename to tests/run-make/issue-40535/foo.rs diff --git a/tests/run-make-fulldeps/issue-46239/Makefile b/tests/run-make/issue-46239/Makefile similarity index 100% rename from tests/run-make-fulldeps/issue-46239/Makefile rename to tests/run-make/issue-46239/Makefile diff --git a/tests/run-make-fulldeps/issue-46239/main.rs b/tests/run-make/issue-46239/main.rs similarity index 100% rename from tests/run-make-fulldeps/issue-46239/main.rs rename to tests/run-make/issue-46239/main.rs diff --git a/tests/run-make-fulldeps/issue-47551/Makefile b/tests/run-make/issue-47551/Makefile similarity index 100% rename from tests/run-make-fulldeps/issue-47551/Makefile rename to tests/run-make/issue-47551/Makefile diff --git a/tests/run-make-fulldeps/issue-47551/eh_frame-terminator.rs b/tests/run-make/issue-47551/eh_frame-terminator.rs similarity index 100% rename from tests/run-make-fulldeps/issue-47551/eh_frame-terminator.rs rename to tests/run-make/issue-47551/eh_frame-terminator.rs diff --git a/tests/run-make-fulldeps/issue-51671/Makefile b/tests/run-make/issue-51671/Makefile similarity index 100% rename from tests/run-make-fulldeps/issue-51671/Makefile rename to tests/run-make/issue-51671/Makefile diff --git a/tests/run-make-fulldeps/issue-51671/app.rs b/tests/run-make/issue-51671/app.rs similarity index 100% rename from tests/run-make-fulldeps/issue-51671/app.rs rename to tests/run-make/issue-51671/app.rs diff --git a/tests/run-make-fulldeps/issue-53964/Makefile b/tests/run-make/issue-53964/Makefile similarity index 100% rename from tests/run-make-fulldeps/issue-53964/Makefile rename to tests/run-make/issue-53964/Makefile diff --git a/tests/run-make-fulldeps/issue-53964/app.rs b/tests/run-make/issue-53964/app.rs similarity index 100% rename from tests/run-make-fulldeps/issue-53964/app.rs rename to tests/run-make/issue-53964/app.rs diff --git a/tests/run-make-fulldeps/issue-53964/panic.rs b/tests/run-make/issue-53964/panic.rs similarity index 100% rename from tests/run-make-fulldeps/issue-53964/panic.rs rename to tests/run-make/issue-53964/panic.rs diff --git a/tests/run-make-fulldeps/issue-64153/Makefile b/tests/run-make/issue-64153/Makefile similarity index 100% rename from tests/run-make-fulldeps/issue-64153/Makefile rename to tests/run-make/issue-64153/Makefile diff --git a/tests/run-make-fulldeps/issue-64153/downstream.rs b/tests/run-make/issue-64153/downstream.rs similarity index 100% rename from tests/run-make-fulldeps/issue-64153/downstream.rs rename to tests/run-make/issue-64153/downstream.rs diff --git a/tests/run-make-fulldeps/issue-64153/upstream.rs b/tests/run-make/issue-64153/upstream.rs similarity index 100% rename from tests/run-make-fulldeps/issue-64153/upstream.rs rename to tests/run-make/issue-64153/upstream.rs diff --git a/tests/run-make-fulldeps/issue-68794-textrel-on-minimal-lib/Makefile b/tests/run-make/issue-68794-textrel-on-minimal-lib/Makefile similarity index 100% rename from tests/run-make-fulldeps/issue-68794-textrel-on-minimal-lib/Makefile rename to tests/run-make/issue-68794-textrel-on-minimal-lib/Makefile diff --git a/tests/run-make-fulldeps/issue-68794-textrel-on-minimal-lib/bar.c b/tests/run-make/issue-68794-textrel-on-minimal-lib/bar.c similarity index 100% rename from tests/run-make-fulldeps/issue-68794-textrel-on-minimal-lib/bar.c rename to tests/run-make/issue-68794-textrel-on-minimal-lib/bar.c diff --git a/tests/run-make-fulldeps/issue-68794-textrel-on-minimal-lib/foo.rs b/tests/run-make/issue-68794-textrel-on-minimal-lib/foo.rs similarity index 100% rename from tests/run-make-fulldeps/issue-68794-textrel-on-minimal-lib/foo.rs rename to tests/run-make/issue-68794-textrel-on-minimal-lib/foo.rs diff --git a/tests/run-make-fulldeps/issue-69368/Makefile b/tests/run-make/issue-69368/Makefile similarity index 100% rename from tests/run-make-fulldeps/issue-69368/Makefile rename to tests/run-make/issue-69368/Makefile diff --git a/tests/run-make-fulldeps/issue-69368/a.rs b/tests/run-make/issue-69368/a.rs similarity index 100% rename from tests/run-make-fulldeps/issue-69368/a.rs rename to tests/run-make/issue-69368/a.rs diff --git a/tests/run-make-fulldeps/issue-69368/b.rs b/tests/run-make/issue-69368/b.rs similarity index 100% rename from tests/run-make-fulldeps/issue-69368/b.rs rename to tests/run-make/issue-69368/b.rs diff --git a/tests/run-make-fulldeps/issue-69368/c.rs b/tests/run-make/issue-69368/c.rs similarity index 100% rename from tests/run-make-fulldeps/issue-69368/c.rs rename to tests/run-make/issue-69368/c.rs diff --git a/tests/run-make-fulldeps/issue-7349/Makefile b/tests/run-make/issue-7349/Makefile similarity index 100% rename from tests/run-make-fulldeps/issue-7349/Makefile rename to tests/run-make/issue-7349/Makefile diff --git a/tests/run-make-fulldeps/issue-7349/foo.rs b/tests/run-make/issue-7349/foo.rs similarity index 100% rename from tests/run-make-fulldeps/issue-7349/foo.rs rename to tests/run-make/issue-7349/foo.rs diff --git a/tests/run-make-fulldeps/issue-83045/Makefile b/tests/run-make/issue-83045/Makefile similarity index 100% rename from tests/run-make-fulldeps/issue-83045/Makefile rename to tests/run-make/issue-83045/Makefile diff --git a/tests/run-make-fulldeps/issue-83045/a.rs b/tests/run-make/issue-83045/a.rs similarity index 100% rename from tests/run-make-fulldeps/issue-83045/a.rs rename to tests/run-make/issue-83045/a.rs diff --git a/tests/run-make-fulldeps/issue-83045/b.rs b/tests/run-make/issue-83045/b.rs similarity index 100% rename from tests/run-make-fulldeps/issue-83045/b.rs rename to tests/run-make/issue-83045/b.rs diff --git a/tests/run-make-fulldeps/issue-83045/c.rs b/tests/run-make/issue-83045/c.rs similarity index 100% rename from tests/run-make-fulldeps/issue-83045/c.rs rename to tests/run-make/issue-83045/c.rs diff --git a/tests/run-make-fulldeps/issue-84395-lto-embed-bitcode/Makefile b/tests/run-make/issue-84395-lto-embed-bitcode/Makefile similarity index 100% rename from tests/run-make-fulldeps/issue-84395-lto-embed-bitcode/Makefile rename to tests/run-make/issue-84395-lto-embed-bitcode/Makefile diff --git a/tests/run-make-fulldeps/issue-84395-lto-embed-bitcode/test.rs b/tests/run-make/issue-84395-lto-embed-bitcode/test.rs similarity index 100% rename from tests/run-make-fulldeps/issue-84395-lto-embed-bitcode/test.rs rename to tests/run-make/issue-84395-lto-embed-bitcode/test.rs diff --git a/tests/run-make-fulldeps/issue-97463-abi-param-passing/Makefile b/tests/run-make/issue-97463-abi-param-passing/Makefile similarity index 100% rename from tests/run-make-fulldeps/issue-97463-abi-param-passing/Makefile rename to tests/run-make/issue-97463-abi-param-passing/Makefile diff --git a/tests/run-make-fulldeps/issue-97463-abi-param-passing/bad.c b/tests/run-make/issue-97463-abi-param-passing/bad.c similarity index 100% rename from tests/run-make-fulldeps/issue-97463-abi-param-passing/bad.c rename to tests/run-make/issue-97463-abi-param-passing/bad.c diff --git a/tests/run-make-fulldeps/issue-97463-abi-param-passing/param_passing.rs b/tests/run-make/issue-97463-abi-param-passing/param_passing.rs similarity index 100% rename from tests/run-make-fulldeps/issue-97463-abi-param-passing/param_passing.rs rename to tests/run-make/issue-97463-abi-param-passing/param_passing.rs diff --git a/tests/run-make-fulldeps/issue64319/Makefile b/tests/run-make/issue64319/Makefile similarity index 100% rename from tests/run-make-fulldeps/issue64319/Makefile rename to tests/run-make/issue64319/Makefile diff --git a/tests/run-make-fulldeps/issue64319/bar.rs b/tests/run-make/issue64319/bar.rs similarity index 100% rename from tests/run-make-fulldeps/issue64319/bar.rs rename to tests/run-make/issue64319/bar.rs diff --git a/tests/run-make-fulldeps/issue64319/foo.rs b/tests/run-make/issue64319/foo.rs similarity index 100% rename from tests/run-make-fulldeps/issue64319/foo.rs rename to tests/run-make/issue64319/foo.rs diff --git a/tests/run-make-fulldeps/libs-through-symlinks/Makefile b/tests/run-make/libs-through-symlinks/Makefile similarity index 100% rename from tests/run-make-fulldeps/libs-through-symlinks/Makefile rename to tests/run-make/libs-through-symlinks/Makefile diff --git a/tests/run-make-fulldeps/libs-through-symlinks/bar.rs b/tests/run-make/libs-through-symlinks/bar.rs similarity index 100% rename from tests/run-make-fulldeps/libs-through-symlinks/bar.rs rename to tests/run-make/libs-through-symlinks/bar.rs diff --git a/tests/run-make-fulldeps/libs-through-symlinks/foo.rs b/tests/run-make/libs-through-symlinks/foo.rs similarity index 100% rename from tests/run-make-fulldeps/libs-through-symlinks/foo.rs rename to tests/run-make/libs-through-symlinks/foo.rs diff --git a/tests/run-make-fulldeps/libtest-json/Makefile b/tests/run-make/libtest-json/Makefile similarity index 100% rename from tests/run-make-fulldeps/libtest-json/Makefile rename to tests/run-make/libtest-json/Makefile diff --git a/tests/run-make-fulldeps/libtest-json/f.rs b/tests/run-make/libtest-json/f.rs similarity index 100% rename from tests/run-make-fulldeps/libtest-json/f.rs rename to tests/run-make/libtest-json/f.rs diff --git a/tests/run-make-fulldeps/libtest-json/output-default.json b/tests/run-make/libtest-json/output-default.json similarity index 100% rename from tests/run-make-fulldeps/libtest-json/output-default.json rename to tests/run-make/libtest-json/output-default.json diff --git a/tests/run-make-fulldeps/libtest-json/output-stdout-success.json b/tests/run-make/libtest-json/output-stdout-success.json similarity index 100% rename from tests/run-make-fulldeps/libtest-json/output-stdout-success.json rename to tests/run-make/libtest-json/output-stdout-success.json diff --git a/tests/run-make-fulldeps/libtest-json/validate_json.py b/tests/run-make/libtest-json/validate_json.py similarity index 100% rename from tests/run-make-fulldeps/libtest-json/validate_json.py rename to tests/run-make/libtest-json/validate_json.py diff --git a/tests/run-make-fulldeps/link-arg/Makefile b/tests/run-make/link-arg/Makefile similarity index 100% rename from tests/run-make-fulldeps/link-arg/Makefile rename to tests/run-make/link-arg/Makefile diff --git a/tests/run-make-fulldeps/link-arg/empty.rs b/tests/run-make/link-arg/empty.rs similarity index 100% rename from tests/run-make-fulldeps/link-arg/empty.rs rename to tests/run-make/link-arg/empty.rs diff --git a/tests/run-make-fulldeps/link-args-order/Makefile b/tests/run-make/link-args-order/Makefile similarity index 100% rename from tests/run-make-fulldeps/link-args-order/Makefile rename to tests/run-make/link-args-order/Makefile diff --git a/tests/run-make-fulldeps/link-args-order/empty.rs b/tests/run-make/link-args-order/empty.rs similarity index 100% rename from tests/run-make-fulldeps/link-args-order/empty.rs rename to tests/run-make/link-args-order/empty.rs diff --git a/tests/run-make-fulldeps/link-cfg/Makefile b/tests/run-make/link-cfg/Makefile similarity index 100% rename from tests/run-make-fulldeps/link-cfg/Makefile rename to tests/run-make/link-cfg/Makefile diff --git a/tests/run-make-fulldeps/link-cfg/dep-with-staticlib.rs b/tests/run-make/link-cfg/dep-with-staticlib.rs similarity index 100% rename from tests/run-make-fulldeps/link-cfg/dep-with-staticlib.rs rename to tests/run-make/link-cfg/dep-with-staticlib.rs diff --git a/tests/run-make-fulldeps/link-cfg/dep.rs b/tests/run-make/link-cfg/dep.rs similarity index 100% rename from tests/run-make-fulldeps/link-cfg/dep.rs rename to tests/run-make/link-cfg/dep.rs diff --git a/tests/run-make-fulldeps/link-cfg/no-deps.rs b/tests/run-make/link-cfg/no-deps.rs similarity index 100% rename from tests/run-make-fulldeps/link-cfg/no-deps.rs rename to tests/run-make/link-cfg/no-deps.rs diff --git a/tests/run-make-fulldeps/link-cfg/return1.c b/tests/run-make/link-cfg/return1.c similarity index 100% rename from tests/run-make-fulldeps/link-cfg/return1.c rename to tests/run-make/link-cfg/return1.c diff --git a/tests/run-make-fulldeps/link-cfg/return2.c b/tests/run-make/link-cfg/return2.c similarity index 100% rename from tests/run-make-fulldeps/link-cfg/return2.c rename to tests/run-make/link-cfg/return2.c diff --git a/tests/run-make-fulldeps/link-cfg/return3.c b/tests/run-make/link-cfg/return3.c similarity index 100% rename from tests/run-make-fulldeps/link-cfg/return3.c rename to tests/run-make/link-cfg/return3.c diff --git a/tests/run-make-fulldeps/link-cfg/with-deps.rs b/tests/run-make/link-cfg/with-deps.rs similarity index 100% rename from tests/run-make-fulldeps/link-cfg/with-deps.rs rename to tests/run-make/link-cfg/with-deps.rs diff --git a/tests/run-make-fulldeps/link-cfg/with-staticlib-deps.rs b/tests/run-make/link-cfg/with-staticlib-deps.rs similarity index 100% rename from tests/run-make-fulldeps/link-cfg/with-staticlib-deps.rs rename to tests/run-make/link-cfg/with-staticlib-deps.rs diff --git a/tests/run-make-fulldeps/link-dedup/Makefile b/tests/run-make/link-dedup/Makefile similarity index 100% rename from tests/run-make-fulldeps/link-dedup/Makefile rename to tests/run-make/link-dedup/Makefile diff --git a/tests/run-make-fulldeps/link-dedup/depa.rs b/tests/run-make/link-dedup/depa.rs similarity index 100% rename from tests/run-make-fulldeps/link-dedup/depa.rs rename to tests/run-make/link-dedup/depa.rs diff --git a/tests/run-make-fulldeps/link-dedup/depb.rs b/tests/run-make/link-dedup/depb.rs similarity index 100% rename from tests/run-make-fulldeps/link-dedup/depb.rs rename to tests/run-make/link-dedup/depb.rs diff --git a/tests/run-make-fulldeps/link-dedup/depc.rs b/tests/run-make/link-dedup/depc.rs similarity index 100% rename from tests/run-make-fulldeps/link-dedup/depc.rs rename to tests/run-make/link-dedup/depc.rs diff --git a/tests/run-make-fulldeps/link-dedup/empty.rs b/tests/run-make/link-dedup/empty.rs similarity index 100% rename from tests/run-make-fulldeps/link-dedup/empty.rs rename to tests/run-make/link-dedup/empty.rs diff --git a/tests/run-make-fulldeps/link-path-order/Makefile b/tests/run-make/link-path-order/Makefile similarity index 100% rename from tests/run-make-fulldeps/link-path-order/Makefile rename to tests/run-make/link-path-order/Makefile diff --git a/tests/run-make-fulldeps/link-path-order/correct.c b/tests/run-make/link-path-order/correct.c similarity index 100% rename from tests/run-make-fulldeps/link-path-order/correct.c rename to tests/run-make/link-path-order/correct.c diff --git a/tests/run-make-fulldeps/link-path-order/main.rs b/tests/run-make/link-path-order/main.rs similarity index 100% rename from tests/run-make-fulldeps/link-path-order/main.rs rename to tests/run-make/link-path-order/main.rs diff --git a/tests/run-make-fulldeps/link-path-order/wrong.c b/tests/run-make/link-path-order/wrong.c similarity index 100% rename from tests/run-make-fulldeps/link-path-order/wrong.c rename to tests/run-make/link-path-order/wrong.c diff --git a/tests/run-make-fulldeps/linkage-attr-on-static/Makefile b/tests/run-make/linkage-attr-on-static/Makefile similarity index 100% rename from tests/run-make-fulldeps/linkage-attr-on-static/Makefile rename to tests/run-make/linkage-attr-on-static/Makefile diff --git a/tests/run-make-fulldeps/linkage-attr-on-static/bar.rs b/tests/run-make/linkage-attr-on-static/bar.rs similarity index 100% rename from tests/run-make-fulldeps/linkage-attr-on-static/bar.rs rename to tests/run-make/linkage-attr-on-static/bar.rs diff --git a/tests/run-make-fulldeps/linkage-attr-on-static/foo.c b/tests/run-make/linkage-attr-on-static/foo.c similarity index 100% rename from tests/run-make-fulldeps/linkage-attr-on-static/foo.c rename to tests/run-make/linkage-attr-on-static/foo.c diff --git a/tests/run-make-fulldeps/long-linker-command-lines-cmd-exe/Makefile b/tests/run-make/long-linker-command-lines-cmd-exe/Makefile similarity index 100% rename from tests/run-make-fulldeps/long-linker-command-lines-cmd-exe/Makefile rename to tests/run-make/long-linker-command-lines-cmd-exe/Makefile diff --git a/tests/run-make-fulldeps/long-linker-command-lines-cmd-exe/foo.bat b/tests/run-make/long-linker-command-lines-cmd-exe/foo.bat similarity index 100% rename from tests/run-make-fulldeps/long-linker-command-lines-cmd-exe/foo.bat rename to tests/run-make/long-linker-command-lines-cmd-exe/foo.bat diff --git a/tests/run-make-fulldeps/long-linker-command-lines-cmd-exe/foo.rs b/tests/run-make/long-linker-command-lines-cmd-exe/foo.rs similarity index 100% rename from tests/run-make-fulldeps/long-linker-command-lines-cmd-exe/foo.rs rename to tests/run-make/long-linker-command-lines-cmd-exe/foo.rs diff --git a/tests/run-make-fulldeps/long-linker-command-lines/Makefile b/tests/run-make/long-linker-command-lines/Makefile similarity index 100% rename from tests/run-make-fulldeps/long-linker-command-lines/Makefile rename to tests/run-make/long-linker-command-lines/Makefile diff --git a/tests/run-make-fulldeps/long-linker-command-lines/foo.rs b/tests/run-make/long-linker-command-lines/foo.rs similarity index 100% rename from tests/run-make-fulldeps/long-linker-command-lines/foo.rs rename to tests/run-make/long-linker-command-lines/foo.rs diff --git a/tests/run-make-fulldeps/longjmp-across-rust/Makefile b/tests/run-make/longjmp-across-rust/Makefile similarity index 100% rename from tests/run-make-fulldeps/longjmp-across-rust/Makefile rename to tests/run-make/longjmp-across-rust/Makefile diff --git a/tests/run-make-fulldeps/longjmp-across-rust/foo.c b/tests/run-make/longjmp-across-rust/foo.c similarity index 100% rename from tests/run-make-fulldeps/longjmp-across-rust/foo.c rename to tests/run-make/longjmp-across-rust/foo.c diff --git a/tests/run-make-fulldeps/longjmp-across-rust/main.rs b/tests/run-make/longjmp-across-rust/main.rs similarity index 100% rename from tests/run-make-fulldeps/longjmp-across-rust/main.rs rename to tests/run-make/longjmp-across-rust/main.rs diff --git a/tests/run-make-fulldeps/ls-metadata/Makefile b/tests/run-make/ls-metadata/Makefile similarity index 100% rename from tests/run-make-fulldeps/ls-metadata/Makefile rename to tests/run-make/ls-metadata/Makefile diff --git a/tests/run-make-fulldeps/ls-metadata/foo.rs b/tests/run-make/ls-metadata/foo.rs similarity index 100% rename from tests/run-make-fulldeps/ls-metadata/foo.rs rename to tests/run-make/ls-metadata/foo.rs diff --git a/tests/run-make-fulldeps/lto-dylib-dep/Makefile b/tests/run-make/lto-dylib-dep/Makefile similarity index 100% rename from tests/run-make-fulldeps/lto-dylib-dep/Makefile rename to tests/run-make/lto-dylib-dep/Makefile diff --git a/tests/run-make-fulldeps/lto-dylib-dep/a_dylib.rs b/tests/run-make/lto-dylib-dep/a_dylib.rs similarity index 100% rename from tests/run-make-fulldeps/lto-dylib-dep/a_dylib.rs rename to tests/run-make/lto-dylib-dep/a_dylib.rs diff --git a/tests/run-make-fulldeps/lto-dylib-dep/main.rs b/tests/run-make/lto-dylib-dep/main.rs similarity index 100% rename from tests/run-make-fulldeps/lto-dylib-dep/main.rs rename to tests/run-make/lto-dylib-dep/main.rs diff --git a/tests/run-make-fulldeps/lto-empty/Makefile b/tests/run-make/lto-empty/Makefile similarity index 100% rename from tests/run-make-fulldeps/lto-empty/Makefile rename to tests/run-make/lto-empty/Makefile diff --git a/tests/run-make-fulldeps/lto-empty/lib.rs b/tests/run-make/lto-empty/lib.rs similarity index 100% rename from tests/run-make-fulldeps/lto-empty/lib.rs rename to tests/run-make/lto-empty/lib.rs diff --git a/tests/run-make-fulldeps/lto-no-link-whole-rlib/Makefile b/tests/run-make/lto-no-link-whole-rlib/Makefile similarity index 100% rename from tests/run-make-fulldeps/lto-no-link-whole-rlib/Makefile rename to tests/run-make/lto-no-link-whole-rlib/Makefile diff --git a/tests/run-make-fulldeps/lto-no-link-whole-rlib/bar.c b/tests/run-make/lto-no-link-whole-rlib/bar.c similarity index 100% rename from tests/run-make-fulldeps/lto-no-link-whole-rlib/bar.c rename to tests/run-make/lto-no-link-whole-rlib/bar.c diff --git a/tests/run-make-fulldeps/lto-no-link-whole-rlib/foo.c b/tests/run-make/lto-no-link-whole-rlib/foo.c similarity index 100% rename from tests/run-make-fulldeps/lto-no-link-whole-rlib/foo.c rename to tests/run-make/lto-no-link-whole-rlib/foo.c diff --git a/tests/run-make-fulldeps/lto-no-link-whole-rlib/lib1.rs b/tests/run-make/lto-no-link-whole-rlib/lib1.rs similarity index 100% rename from tests/run-make-fulldeps/lto-no-link-whole-rlib/lib1.rs rename to tests/run-make/lto-no-link-whole-rlib/lib1.rs diff --git a/tests/run-make-fulldeps/lto-no-link-whole-rlib/lib2.rs b/tests/run-make/lto-no-link-whole-rlib/lib2.rs similarity index 100% rename from tests/run-make-fulldeps/lto-no-link-whole-rlib/lib2.rs rename to tests/run-make/lto-no-link-whole-rlib/lib2.rs diff --git a/tests/run-make-fulldeps/lto-no-link-whole-rlib/main.rs b/tests/run-make/lto-no-link-whole-rlib/main.rs similarity index 100% rename from tests/run-make-fulldeps/lto-no-link-whole-rlib/main.rs rename to tests/run-make/lto-no-link-whole-rlib/main.rs diff --git a/tests/run-make-fulldeps/lto-readonly-lib/Makefile b/tests/run-make/lto-readonly-lib/Makefile similarity index 100% rename from tests/run-make-fulldeps/lto-readonly-lib/Makefile rename to tests/run-make/lto-readonly-lib/Makefile diff --git a/tests/run-make-fulldeps/lto-readonly-lib/lib.rs b/tests/run-make/lto-readonly-lib/lib.rs similarity index 100% rename from tests/run-make-fulldeps/lto-readonly-lib/lib.rs rename to tests/run-make/lto-readonly-lib/lib.rs diff --git a/tests/run-make-fulldeps/lto-readonly-lib/main.rs b/tests/run-make/lto-readonly-lib/main.rs similarity index 100% rename from tests/run-make-fulldeps/lto-readonly-lib/main.rs rename to tests/run-make/lto-readonly-lib/main.rs diff --git a/tests/run-make-fulldeps/lto-smoke-c/Makefile b/tests/run-make/lto-smoke-c/Makefile similarity index 100% rename from tests/run-make-fulldeps/lto-smoke-c/Makefile rename to tests/run-make/lto-smoke-c/Makefile diff --git a/tests/run-make-fulldeps/lto-smoke-c/bar.c b/tests/run-make/lto-smoke-c/bar.c similarity index 100% rename from tests/run-make-fulldeps/lto-smoke-c/bar.c rename to tests/run-make/lto-smoke-c/bar.c diff --git a/tests/run-make-fulldeps/lto-smoke-c/foo.rs b/tests/run-make/lto-smoke-c/foo.rs similarity index 100% rename from tests/run-make-fulldeps/lto-smoke-c/foo.rs rename to tests/run-make/lto-smoke-c/foo.rs diff --git a/tests/run-make-fulldeps/lto-smoke/Makefile b/tests/run-make/lto-smoke/Makefile similarity index 100% rename from tests/run-make-fulldeps/lto-smoke/Makefile rename to tests/run-make/lto-smoke/Makefile diff --git a/tests/run-make-fulldeps/lto-smoke/lib.rs b/tests/run-make/lto-smoke/lib.rs similarity index 100% rename from tests/run-make-fulldeps/lto-smoke/lib.rs rename to tests/run-make/lto-smoke/lib.rs diff --git a/tests/run-make-fulldeps/lto-smoke/main.rs b/tests/run-make/lto-smoke/main.rs similarity index 100% rename from tests/run-make-fulldeps/lto-smoke/main.rs rename to tests/run-make/lto-smoke/main.rs diff --git a/tests/run-make-fulldeps/manual-crate-name/Makefile b/tests/run-make/manual-crate-name/Makefile similarity index 100% rename from tests/run-make-fulldeps/manual-crate-name/Makefile rename to tests/run-make/manual-crate-name/Makefile diff --git a/tests/run-make-fulldeps/manual-crate-name/bar.rs b/tests/run-make/manual-crate-name/bar.rs similarity index 100% rename from tests/run-make-fulldeps/manual-crate-name/bar.rs rename to tests/run-make/manual-crate-name/bar.rs diff --git a/tests/run-make-fulldeps/manual-link/Makefile b/tests/run-make/manual-link/Makefile similarity index 100% rename from tests/run-make-fulldeps/manual-link/Makefile rename to tests/run-make/manual-link/Makefile diff --git a/tests/run-make-fulldeps/manual-link/bar.c b/tests/run-make/manual-link/bar.c similarity index 100% rename from tests/run-make-fulldeps/manual-link/bar.c rename to tests/run-make/manual-link/bar.c diff --git a/tests/run-make-fulldeps/manual-link/foo.c b/tests/run-make/manual-link/foo.c similarity index 100% rename from tests/run-make-fulldeps/manual-link/foo.c rename to tests/run-make/manual-link/foo.c diff --git a/tests/run-make-fulldeps/manual-link/foo.rs b/tests/run-make/manual-link/foo.rs similarity index 100% rename from tests/run-make-fulldeps/manual-link/foo.rs rename to tests/run-make/manual-link/foo.rs diff --git a/tests/run-make-fulldeps/manual-link/main.rs b/tests/run-make/manual-link/main.rs similarity index 100% rename from tests/run-make-fulldeps/manual-link/main.rs rename to tests/run-make/manual-link/main.rs diff --git a/tests/run-make-fulldeps/many-crates-but-no-match/Makefile b/tests/run-make/many-crates-but-no-match/Makefile similarity index 100% rename from tests/run-make-fulldeps/many-crates-but-no-match/Makefile rename to tests/run-make/many-crates-but-no-match/Makefile diff --git a/tests/run-make-fulldeps/many-crates-but-no-match/crateA1.rs b/tests/run-make/many-crates-but-no-match/crateA1.rs similarity index 100% rename from tests/run-make-fulldeps/many-crates-but-no-match/crateA1.rs rename to tests/run-make/many-crates-but-no-match/crateA1.rs diff --git a/tests/run-make-fulldeps/many-crates-but-no-match/crateA2.rs b/tests/run-make/many-crates-but-no-match/crateA2.rs similarity index 100% rename from tests/run-make-fulldeps/many-crates-but-no-match/crateA2.rs rename to tests/run-make/many-crates-but-no-match/crateA2.rs diff --git a/tests/run-make-fulldeps/many-crates-but-no-match/crateA3.rs b/tests/run-make/many-crates-but-no-match/crateA3.rs similarity index 100% rename from tests/run-make-fulldeps/many-crates-but-no-match/crateA3.rs rename to tests/run-make/many-crates-but-no-match/crateA3.rs diff --git a/tests/run-make-fulldeps/many-crates-but-no-match/crateB.rs b/tests/run-make/many-crates-but-no-match/crateB.rs similarity index 100% rename from tests/run-make-fulldeps/many-crates-but-no-match/crateB.rs rename to tests/run-make/many-crates-but-no-match/crateB.rs diff --git a/tests/run-make-fulldeps/many-crates-but-no-match/crateC.rs b/tests/run-make/many-crates-but-no-match/crateC.rs similarity index 100% rename from tests/run-make-fulldeps/many-crates-but-no-match/crateC.rs rename to tests/run-make/many-crates-but-no-match/crateC.rs diff --git a/tests/run-make-fulldeps/metadata-flag-frobs-symbols/Makefile b/tests/run-make/metadata-flag-frobs-symbols/Makefile similarity index 100% rename from tests/run-make-fulldeps/metadata-flag-frobs-symbols/Makefile rename to tests/run-make/metadata-flag-frobs-symbols/Makefile diff --git a/tests/run-make-fulldeps/metadata-flag-frobs-symbols/bar.rs b/tests/run-make/metadata-flag-frobs-symbols/bar.rs similarity index 100% rename from tests/run-make-fulldeps/metadata-flag-frobs-symbols/bar.rs rename to tests/run-make/metadata-flag-frobs-symbols/bar.rs diff --git a/tests/run-make-fulldeps/metadata-flag-frobs-symbols/foo.rs b/tests/run-make/metadata-flag-frobs-symbols/foo.rs similarity index 100% rename from tests/run-make-fulldeps/metadata-flag-frobs-symbols/foo.rs rename to tests/run-make/metadata-flag-frobs-symbols/foo.rs diff --git a/tests/run-make-fulldeps/min-global-align/Makefile b/tests/run-make/min-global-align/Makefile similarity index 100% rename from tests/run-make-fulldeps/min-global-align/Makefile rename to tests/run-make/min-global-align/Makefile diff --git a/tests/run-make-fulldeps/min-global-align/min_global_align.rs b/tests/run-make/min-global-align/min_global_align.rs similarity index 100% rename from tests/run-make-fulldeps/min-global-align/min_global_align.rs rename to tests/run-make/min-global-align/min_global_align.rs diff --git a/tests/run-make-fulldeps/mingw-export-call-convention/Makefile b/tests/run-make/mingw-export-call-convention/Makefile similarity index 100% rename from tests/run-make-fulldeps/mingw-export-call-convention/Makefile rename to tests/run-make/mingw-export-call-convention/Makefile diff --git a/tests/run-make-fulldeps/mingw-export-call-convention/foo.rs b/tests/run-make/mingw-export-call-convention/foo.rs similarity index 100% rename from tests/run-make-fulldeps/mingw-export-call-convention/foo.rs rename to tests/run-make/mingw-export-call-convention/foo.rs diff --git a/tests/run-make-fulldeps/mismatching-target-triples/Makefile b/tests/run-make/mismatching-target-triples/Makefile similarity index 100% rename from tests/run-make-fulldeps/mismatching-target-triples/Makefile rename to tests/run-make/mismatching-target-triples/Makefile diff --git a/tests/run-make-fulldeps/mismatching-target-triples/bar.rs b/tests/run-make/mismatching-target-triples/bar.rs similarity index 100% rename from tests/run-make-fulldeps/mismatching-target-triples/bar.rs rename to tests/run-make/mismatching-target-triples/bar.rs diff --git a/tests/run-make-fulldeps/mismatching-target-triples/foo.rs b/tests/run-make/mismatching-target-triples/foo.rs similarity index 100% rename from tests/run-make-fulldeps/mismatching-target-triples/foo.rs rename to tests/run-make/mismatching-target-triples/foo.rs diff --git a/tests/run-make-fulldeps/missing-crate-dependency/Makefile b/tests/run-make/missing-crate-dependency/Makefile similarity index 100% rename from tests/run-make-fulldeps/missing-crate-dependency/Makefile rename to tests/run-make/missing-crate-dependency/Makefile diff --git a/tests/run-make-fulldeps/missing-crate-dependency/crateA.rs b/tests/run-make/missing-crate-dependency/crateA.rs similarity index 100% rename from tests/run-make-fulldeps/missing-crate-dependency/crateA.rs rename to tests/run-make/missing-crate-dependency/crateA.rs diff --git a/tests/run-make-fulldeps/missing-crate-dependency/crateB.rs b/tests/run-make/missing-crate-dependency/crateB.rs similarity index 100% rename from tests/run-make-fulldeps/missing-crate-dependency/crateB.rs rename to tests/run-make/missing-crate-dependency/crateB.rs diff --git a/tests/run-make-fulldeps/missing-crate-dependency/crateC.rs b/tests/run-make/missing-crate-dependency/crateC.rs similarity index 100% rename from tests/run-make-fulldeps/missing-crate-dependency/crateC.rs rename to tests/run-make/missing-crate-dependency/crateC.rs diff --git a/tests/run-make-fulldeps/mixing-deps/Makefile b/tests/run-make/mixing-deps/Makefile similarity index 100% rename from tests/run-make-fulldeps/mixing-deps/Makefile rename to tests/run-make/mixing-deps/Makefile diff --git a/tests/run-make-fulldeps/mixing-deps/both.rs b/tests/run-make/mixing-deps/both.rs similarity index 100% rename from tests/run-make-fulldeps/mixing-deps/both.rs rename to tests/run-make/mixing-deps/both.rs diff --git a/tests/run-make-fulldeps/mixing-deps/dylib.rs b/tests/run-make/mixing-deps/dylib.rs similarity index 100% rename from tests/run-make-fulldeps/mixing-deps/dylib.rs rename to tests/run-make/mixing-deps/dylib.rs diff --git a/tests/run-make-fulldeps/mixing-deps/prog.rs b/tests/run-make/mixing-deps/prog.rs similarity index 100% rename from tests/run-make-fulldeps/mixing-deps/prog.rs rename to tests/run-make/mixing-deps/prog.rs diff --git a/tests/run-make-fulldeps/mixing-formats/Makefile b/tests/run-make/mixing-formats/Makefile similarity index 100% rename from tests/run-make-fulldeps/mixing-formats/Makefile rename to tests/run-make/mixing-formats/Makefile diff --git a/tests/run-make-fulldeps/mixing-formats/bar1.rs b/tests/run-make/mixing-formats/bar1.rs similarity index 100% rename from tests/run-make-fulldeps/mixing-formats/bar1.rs rename to tests/run-make/mixing-formats/bar1.rs diff --git a/tests/run-make-fulldeps/mixing-formats/bar2.rs b/tests/run-make/mixing-formats/bar2.rs similarity index 100% rename from tests/run-make-fulldeps/mixing-formats/bar2.rs rename to tests/run-make/mixing-formats/bar2.rs diff --git a/tests/run-make-fulldeps/mixing-formats/baz.rs b/tests/run-make/mixing-formats/baz.rs similarity index 100% rename from tests/run-make-fulldeps/mixing-formats/baz.rs rename to tests/run-make/mixing-formats/baz.rs diff --git a/tests/run-make-fulldeps/mixing-formats/baz2.rs b/tests/run-make/mixing-formats/baz2.rs similarity index 100% rename from tests/run-make-fulldeps/mixing-formats/baz2.rs rename to tests/run-make/mixing-formats/baz2.rs diff --git a/tests/run-make-fulldeps/mixing-formats/foo.rs b/tests/run-make/mixing-formats/foo.rs similarity index 100% rename from tests/run-make-fulldeps/mixing-formats/foo.rs rename to tests/run-make/mixing-formats/foo.rs diff --git a/tests/run-make-fulldeps/mixing-libs/Makefile b/tests/run-make/mixing-libs/Makefile similarity index 100% rename from tests/run-make-fulldeps/mixing-libs/Makefile rename to tests/run-make/mixing-libs/Makefile diff --git a/tests/run-make-fulldeps/mixing-libs/dylib.rs b/tests/run-make/mixing-libs/dylib.rs similarity index 100% rename from tests/run-make-fulldeps/mixing-libs/dylib.rs rename to tests/run-make/mixing-libs/dylib.rs diff --git a/tests/run-make-fulldeps/mixing-libs/prog.rs b/tests/run-make/mixing-libs/prog.rs similarity index 100% rename from tests/run-make-fulldeps/mixing-libs/prog.rs rename to tests/run-make/mixing-libs/prog.rs diff --git a/tests/run-make-fulldeps/mixing-libs/rlib.rs b/tests/run-make/mixing-libs/rlib.rs similarity index 100% rename from tests/run-make-fulldeps/mixing-libs/rlib.rs rename to tests/run-make/mixing-libs/rlib.rs diff --git a/tests/run-make-fulldeps/msvc-opt-minsize/Makefile b/tests/run-make/msvc-opt-minsize/Makefile similarity index 100% rename from tests/run-make-fulldeps/msvc-opt-minsize/Makefile rename to tests/run-make/msvc-opt-minsize/Makefile diff --git a/tests/run-make-fulldeps/msvc-opt-minsize/foo.rs b/tests/run-make/msvc-opt-minsize/foo.rs similarity index 100% rename from tests/run-make-fulldeps/msvc-opt-minsize/foo.rs rename to tests/run-make/msvc-opt-minsize/foo.rs diff --git a/tests/run-make-fulldeps/multiple-emits/Makefile b/tests/run-make/multiple-emits/Makefile similarity index 100% rename from tests/run-make-fulldeps/multiple-emits/Makefile rename to tests/run-make/multiple-emits/Makefile diff --git a/tests/run-make-fulldeps/multiple-emits/foo.rs b/tests/run-make/multiple-emits/foo.rs similarity index 100% rename from tests/run-make-fulldeps/multiple-emits/foo.rs rename to tests/run-make/multiple-emits/foo.rs diff --git a/tests/run-make-fulldeps/no-builtins-lto/Makefile b/tests/run-make/no-builtins-lto/Makefile similarity index 100% rename from tests/run-make-fulldeps/no-builtins-lto/Makefile rename to tests/run-make/no-builtins-lto/Makefile diff --git a/tests/run-make-fulldeps/no-builtins-lto/main.rs b/tests/run-make/no-builtins-lto/main.rs similarity index 100% rename from tests/run-make-fulldeps/no-builtins-lto/main.rs rename to tests/run-make/no-builtins-lto/main.rs diff --git a/tests/run-make-fulldeps/no-builtins-lto/no_builtins.rs b/tests/run-make/no-builtins-lto/no_builtins.rs similarity index 100% rename from tests/run-make-fulldeps/no-builtins-lto/no_builtins.rs rename to tests/run-make/no-builtins-lto/no_builtins.rs diff --git a/tests/run-make-fulldeps/no-duplicate-libs/Makefile b/tests/run-make/no-duplicate-libs/Makefile similarity index 100% rename from tests/run-make-fulldeps/no-duplicate-libs/Makefile rename to tests/run-make/no-duplicate-libs/Makefile diff --git a/tests/run-make-fulldeps/no-duplicate-libs/bar.c b/tests/run-make/no-duplicate-libs/bar.c similarity index 100% rename from tests/run-make-fulldeps/no-duplicate-libs/bar.c rename to tests/run-make/no-duplicate-libs/bar.c diff --git a/tests/run-make-fulldeps/no-duplicate-libs/foo.c b/tests/run-make/no-duplicate-libs/foo.c similarity index 100% rename from tests/run-make-fulldeps/no-duplicate-libs/foo.c rename to tests/run-make/no-duplicate-libs/foo.c diff --git a/tests/run-make-fulldeps/no-duplicate-libs/main.rs b/tests/run-make/no-duplicate-libs/main.rs similarity index 100% rename from tests/run-make-fulldeps/no-duplicate-libs/main.rs rename to tests/run-make/no-duplicate-libs/main.rs diff --git a/tests/run-make-fulldeps/no-intermediate-extras/Makefile b/tests/run-make/no-intermediate-extras/Makefile similarity index 100% rename from tests/run-make-fulldeps/no-intermediate-extras/Makefile rename to tests/run-make/no-intermediate-extras/Makefile diff --git a/tests/run-make-fulldeps/no-intermediate-extras/foo.rs b/tests/run-make/no-intermediate-extras/foo.rs similarity index 100% rename from tests/run-make-fulldeps/no-intermediate-extras/foo.rs rename to tests/run-make/no-intermediate-extras/foo.rs diff --git a/tests/run-make-fulldeps/obey-crate-type-flag/Makefile b/tests/run-make/obey-crate-type-flag/Makefile similarity index 100% rename from tests/run-make-fulldeps/obey-crate-type-flag/Makefile rename to tests/run-make/obey-crate-type-flag/Makefile diff --git a/tests/run-make-fulldeps/obey-crate-type-flag/test.rs b/tests/run-make/obey-crate-type-flag/test.rs similarity index 100% rename from tests/run-make-fulldeps/obey-crate-type-flag/test.rs rename to tests/run-make/obey-crate-type-flag/test.rs diff --git a/tests/run-make-fulldeps/output-filename-conflicts-with-directory/Makefile b/tests/run-make/output-filename-conflicts-with-directory/Makefile similarity index 100% rename from tests/run-make-fulldeps/output-filename-conflicts-with-directory/Makefile rename to tests/run-make/output-filename-conflicts-with-directory/Makefile diff --git a/tests/run-make-fulldeps/output-filename-conflicts-with-directory/foo.rs b/tests/run-make/output-filename-conflicts-with-directory/foo.rs similarity index 100% rename from tests/run-make-fulldeps/output-filename-conflicts-with-directory/foo.rs rename to tests/run-make/output-filename-conflicts-with-directory/foo.rs diff --git a/tests/run-make-fulldeps/output-filename-overwrites-input/Makefile b/tests/run-make/output-filename-overwrites-input/Makefile similarity index 100% rename from tests/run-make-fulldeps/output-filename-overwrites-input/Makefile rename to tests/run-make/output-filename-overwrites-input/Makefile diff --git a/tests/run-make-fulldeps/output-filename-overwrites-input/bar.rs b/tests/run-make/output-filename-overwrites-input/bar.rs similarity index 100% rename from tests/run-make-fulldeps/output-filename-overwrites-input/bar.rs rename to tests/run-make/output-filename-overwrites-input/bar.rs diff --git a/tests/run-make-fulldeps/output-filename-overwrites-input/foo.rs b/tests/run-make/output-filename-overwrites-input/foo.rs similarity index 100% rename from tests/run-make-fulldeps/output-filename-overwrites-input/foo.rs rename to tests/run-make/output-filename-overwrites-input/foo.rs diff --git a/tests/run-make-fulldeps/output-type-permutations/Makefile b/tests/run-make/output-type-permutations/Makefile similarity index 100% rename from tests/run-make-fulldeps/output-type-permutations/Makefile rename to tests/run-make/output-type-permutations/Makefile diff --git a/tests/run-make-fulldeps/output-type-permutations/foo.rs b/tests/run-make/output-type-permutations/foo.rs similarity index 100% rename from tests/run-make-fulldeps/output-type-permutations/foo.rs rename to tests/run-make/output-type-permutations/foo.rs diff --git a/tests/run-make-fulldeps/output-with-hyphens/Makefile b/tests/run-make/output-with-hyphens/Makefile similarity index 100% rename from tests/run-make-fulldeps/output-with-hyphens/Makefile rename to tests/run-make/output-with-hyphens/Makefile diff --git a/tests/run-make-fulldeps/output-with-hyphens/foo-bar.rs b/tests/run-make/output-with-hyphens/foo-bar.rs similarity index 100% rename from tests/run-make-fulldeps/output-with-hyphens/foo-bar.rs rename to tests/run-make/output-with-hyphens/foo-bar.rs diff --git a/tests/run-make-fulldeps/override-aliased-flags/Makefile b/tests/run-make/override-aliased-flags/Makefile similarity index 100% rename from tests/run-make-fulldeps/override-aliased-flags/Makefile rename to tests/run-make/override-aliased-flags/Makefile diff --git a/tests/run-make-fulldeps/override-aliased-flags/main.rs b/tests/run-make/override-aliased-flags/main.rs similarity index 100% rename from tests/run-make-fulldeps/override-aliased-flags/main.rs rename to tests/run-make/override-aliased-flags/main.rs diff --git a/tests/run-make-fulldeps/panic-impl-transitive/Makefile b/tests/run-make/panic-impl-transitive/Makefile similarity index 100% rename from tests/run-make-fulldeps/panic-impl-transitive/Makefile rename to tests/run-make/panic-impl-transitive/Makefile diff --git a/tests/run-make-fulldeps/panic-impl-transitive/panic-impl-consumer.rs b/tests/run-make/panic-impl-transitive/panic-impl-consumer.rs similarity index 100% rename from tests/run-make-fulldeps/panic-impl-transitive/panic-impl-consumer.rs rename to tests/run-make/panic-impl-transitive/panic-impl-consumer.rs diff --git a/tests/run-make-fulldeps/panic-impl-transitive/panic-impl-provider.rs b/tests/run-make/panic-impl-transitive/panic-impl-provider.rs similarity index 100% rename from tests/run-make-fulldeps/panic-impl-transitive/panic-impl-provider.rs rename to tests/run-make/panic-impl-transitive/panic-impl-provider.rs diff --git a/tests/run-make-fulldeps/pass-non-c-like-enum-to-c/Makefile b/tests/run-make/pass-non-c-like-enum-to-c/Makefile similarity index 100% rename from tests/run-make-fulldeps/pass-non-c-like-enum-to-c/Makefile rename to tests/run-make/pass-non-c-like-enum-to-c/Makefile diff --git a/tests/run-make-fulldeps/pass-non-c-like-enum-to-c/nonclike.rs b/tests/run-make/pass-non-c-like-enum-to-c/nonclike.rs similarity index 100% rename from tests/run-make-fulldeps/pass-non-c-like-enum-to-c/nonclike.rs rename to tests/run-make/pass-non-c-like-enum-to-c/nonclike.rs diff --git a/tests/run-make-fulldeps/pass-non-c-like-enum-to-c/test.c b/tests/run-make/pass-non-c-like-enum-to-c/test.c similarity index 100% rename from tests/run-make-fulldeps/pass-non-c-like-enum-to-c/test.c rename to tests/run-make/pass-non-c-like-enum-to-c/test.c diff --git a/tests/run-make-fulldeps/pgo-branch-weights/Makefile b/tests/run-make/pgo-branch-weights/Makefile similarity index 100% rename from tests/run-make-fulldeps/pgo-branch-weights/Makefile rename to tests/run-make/pgo-branch-weights/Makefile diff --git a/tests/run-make-fulldeps/pgo-branch-weights/filecheck-patterns.txt b/tests/run-make/pgo-branch-weights/filecheck-patterns.txt similarity index 100% rename from tests/run-make-fulldeps/pgo-branch-weights/filecheck-patterns.txt rename to tests/run-make/pgo-branch-weights/filecheck-patterns.txt diff --git a/tests/run-make-fulldeps/pgo-branch-weights/interesting.rs b/tests/run-make/pgo-branch-weights/interesting.rs similarity index 100% rename from tests/run-make-fulldeps/pgo-branch-weights/interesting.rs rename to tests/run-make/pgo-branch-weights/interesting.rs diff --git a/tests/run-make-fulldeps/pgo-branch-weights/main.rs b/tests/run-make/pgo-branch-weights/main.rs similarity index 100% rename from tests/run-make-fulldeps/pgo-branch-weights/main.rs rename to tests/run-make/pgo-branch-weights/main.rs diff --git a/tests/run-make-fulldeps/pgo-branch-weights/opaque.rs b/tests/run-make/pgo-branch-weights/opaque.rs similarity index 100% rename from tests/run-make-fulldeps/pgo-branch-weights/opaque.rs rename to tests/run-make/pgo-branch-weights/opaque.rs diff --git a/tests/run-make-fulldeps/pgo-gen-lto/Makefile b/tests/run-make/pgo-gen-lto/Makefile similarity index 100% rename from tests/run-make-fulldeps/pgo-gen-lto/Makefile rename to tests/run-make/pgo-gen-lto/Makefile diff --git a/tests/run-make-fulldeps/pgo-gen-lto/test.rs b/tests/run-make/pgo-gen-lto/test.rs similarity index 100% rename from tests/run-make-fulldeps/pgo-gen-lto/test.rs rename to tests/run-make/pgo-gen-lto/test.rs diff --git a/tests/run-make-fulldeps/pgo-gen-no-imp-symbols/Makefile b/tests/run-make/pgo-gen-no-imp-symbols/Makefile similarity index 100% rename from tests/run-make-fulldeps/pgo-gen-no-imp-symbols/Makefile rename to tests/run-make/pgo-gen-no-imp-symbols/Makefile diff --git a/tests/run-make-fulldeps/pgo-gen-no-imp-symbols/test.rs b/tests/run-make/pgo-gen-no-imp-symbols/test.rs similarity index 100% rename from tests/run-make-fulldeps/pgo-gen-no-imp-symbols/test.rs rename to tests/run-make/pgo-gen-no-imp-symbols/test.rs diff --git a/tests/run-make-fulldeps/pgo-gen/Makefile b/tests/run-make/pgo-gen/Makefile similarity index 100% rename from tests/run-make-fulldeps/pgo-gen/Makefile rename to tests/run-make/pgo-gen/Makefile diff --git a/tests/run-make-fulldeps/pgo-gen/test.rs b/tests/run-make/pgo-gen/test.rs similarity index 100% rename from tests/run-make-fulldeps/pgo-gen/test.rs rename to tests/run-make/pgo-gen/test.rs diff --git a/tests/run-make-fulldeps/pgo-indirect-call-promotion/Makefile b/tests/run-make/pgo-indirect-call-promotion/Makefile similarity index 100% rename from tests/run-make-fulldeps/pgo-indirect-call-promotion/Makefile rename to tests/run-make/pgo-indirect-call-promotion/Makefile diff --git a/tests/run-make-fulldeps/pgo-indirect-call-promotion/filecheck-patterns.txt b/tests/run-make/pgo-indirect-call-promotion/filecheck-patterns.txt similarity index 100% rename from tests/run-make-fulldeps/pgo-indirect-call-promotion/filecheck-patterns.txt rename to tests/run-make/pgo-indirect-call-promotion/filecheck-patterns.txt diff --git a/tests/run-make-fulldeps/pgo-indirect-call-promotion/interesting.rs b/tests/run-make/pgo-indirect-call-promotion/interesting.rs similarity index 100% rename from tests/run-make-fulldeps/pgo-indirect-call-promotion/interesting.rs rename to tests/run-make/pgo-indirect-call-promotion/interesting.rs diff --git a/tests/run-make-fulldeps/pgo-indirect-call-promotion/main.rs b/tests/run-make/pgo-indirect-call-promotion/main.rs similarity index 100% rename from tests/run-make-fulldeps/pgo-indirect-call-promotion/main.rs rename to tests/run-make/pgo-indirect-call-promotion/main.rs diff --git a/tests/run-make-fulldeps/pgo-indirect-call-promotion/opaque.rs b/tests/run-make/pgo-indirect-call-promotion/opaque.rs similarity index 100% rename from tests/run-make-fulldeps/pgo-indirect-call-promotion/opaque.rs rename to tests/run-make/pgo-indirect-call-promotion/opaque.rs diff --git a/tests/run-make-fulldeps/pgo-use/Makefile b/tests/run-make/pgo-use/Makefile similarity index 100% rename from tests/run-make-fulldeps/pgo-use/Makefile rename to tests/run-make/pgo-use/Makefile diff --git a/tests/run-make-fulldeps/pgo-use/filecheck-patterns.txt b/tests/run-make/pgo-use/filecheck-patterns.txt similarity index 100% rename from tests/run-make-fulldeps/pgo-use/filecheck-patterns.txt rename to tests/run-make/pgo-use/filecheck-patterns.txt diff --git a/tests/run-make-fulldeps/pgo-use/main.rs b/tests/run-make/pgo-use/main.rs similarity index 100% rename from tests/run-make-fulldeps/pgo-use/main.rs rename to tests/run-make/pgo-use/main.rs diff --git a/tests/run-make-fulldeps/pointer-auth-link-with-c/Makefile b/tests/run-make/pointer-auth-link-with-c/Makefile similarity index 100% rename from tests/run-make-fulldeps/pointer-auth-link-with-c/Makefile rename to tests/run-make/pointer-auth-link-with-c/Makefile diff --git a/tests/run-make-fulldeps/pointer-auth-link-with-c/test.c b/tests/run-make/pointer-auth-link-with-c/test.c similarity index 100% rename from tests/run-make-fulldeps/pointer-auth-link-with-c/test.c rename to tests/run-make/pointer-auth-link-with-c/test.c diff --git a/tests/run-make-fulldeps/pointer-auth-link-with-c/test.rs b/tests/run-make/pointer-auth-link-with-c/test.rs similarity index 100% rename from tests/run-make-fulldeps/pointer-auth-link-with-c/test.rs rename to tests/run-make/pointer-auth-link-with-c/test.rs diff --git a/tests/run-make-fulldeps/prefer-dylib/Makefile b/tests/run-make/prefer-dylib/Makefile similarity index 100% rename from tests/run-make-fulldeps/prefer-dylib/Makefile rename to tests/run-make/prefer-dylib/Makefile diff --git a/tests/run-make-fulldeps/prefer-dylib/bar.rs b/tests/run-make/prefer-dylib/bar.rs similarity index 100% rename from tests/run-make-fulldeps/prefer-dylib/bar.rs rename to tests/run-make/prefer-dylib/bar.rs diff --git a/tests/run-make-fulldeps/prefer-dylib/foo.rs b/tests/run-make/prefer-dylib/foo.rs similarity index 100% rename from tests/run-make-fulldeps/prefer-dylib/foo.rs rename to tests/run-make/prefer-dylib/foo.rs diff --git a/tests/run-make-fulldeps/prefer-rlib/Makefile b/tests/run-make/prefer-rlib/Makefile similarity index 100% rename from tests/run-make-fulldeps/prefer-rlib/Makefile rename to tests/run-make/prefer-rlib/Makefile diff --git a/tests/run-make-fulldeps/prefer-rlib/bar.rs b/tests/run-make/prefer-rlib/bar.rs similarity index 100% rename from tests/run-make-fulldeps/prefer-rlib/bar.rs rename to tests/run-make/prefer-rlib/bar.rs diff --git a/tests/run-make-fulldeps/prefer-rlib/foo.rs b/tests/run-make/prefer-rlib/foo.rs similarity index 100% rename from tests/run-make-fulldeps/prefer-rlib/foo.rs rename to tests/run-make/prefer-rlib/foo.rs diff --git a/tests/run-make-fulldeps/pretty-print-to-file/Makefile b/tests/run-make/pretty-print-to-file/Makefile similarity index 100% rename from tests/run-make-fulldeps/pretty-print-to-file/Makefile rename to tests/run-make/pretty-print-to-file/Makefile diff --git a/tests/run-make-fulldeps/pretty-print-to-file/input.pp b/tests/run-make/pretty-print-to-file/input.pp similarity index 100% rename from tests/run-make-fulldeps/pretty-print-to-file/input.pp rename to tests/run-make/pretty-print-to-file/input.pp diff --git a/tests/run-make-fulldeps/pretty-print-to-file/input.rs b/tests/run-make/pretty-print-to-file/input.rs similarity index 100% rename from tests/run-make-fulldeps/pretty-print-to-file/input.rs rename to tests/run-make/pretty-print-to-file/input.rs diff --git a/tests/run-make-fulldeps/print-calling-conventions/Makefile b/tests/run-make/print-calling-conventions/Makefile similarity index 100% rename from tests/run-make-fulldeps/print-calling-conventions/Makefile rename to tests/run-make/print-calling-conventions/Makefile diff --git a/tests/run-make-fulldeps/print-cfg/Makefile b/tests/run-make/print-cfg/Makefile similarity index 100% rename from tests/run-make-fulldeps/print-cfg/Makefile rename to tests/run-make/print-cfg/Makefile diff --git a/tests/run-make-fulldeps/print-target-list/Makefile b/tests/run-make/print-target-list/Makefile similarity index 100% rename from tests/run-make-fulldeps/print-target-list/Makefile rename to tests/run-make/print-target-list/Makefile diff --git a/tests/run-make-fulldeps/profile/Makefile b/tests/run-make/profile/Makefile similarity index 100% rename from tests/run-make-fulldeps/profile/Makefile rename to tests/run-make/profile/Makefile diff --git a/tests/run-make-fulldeps/profile/test.rs b/tests/run-make/profile/test.rs similarity index 100% rename from tests/run-make-fulldeps/profile/test.rs rename to tests/run-make/profile/test.rs diff --git a/tests/run-make-fulldeps/prune-link-args/Makefile b/tests/run-make/prune-link-args/Makefile similarity index 100% rename from tests/run-make-fulldeps/prune-link-args/Makefile rename to tests/run-make/prune-link-args/Makefile diff --git a/tests/run-make-fulldeps/prune-link-args/empty.rs b/tests/run-make/prune-link-args/empty.rs similarity index 100% rename from tests/run-make-fulldeps/prune-link-args/empty.rs rename to tests/run-make/prune-link-args/empty.rs diff --git a/tests/run-make-fulldeps/redundant-libs/Makefile b/tests/run-make/redundant-libs/Makefile similarity index 100% rename from tests/run-make-fulldeps/redundant-libs/Makefile rename to tests/run-make/redundant-libs/Makefile diff --git a/tests/run-make-fulldeps/redundant-libs/bar.c b/tests/run-make/redundant-libs/bar.c similarity index 100% rename from tests/run-make-fulldeps/redundant-libs/bar.c rename to tests/run-make/redundant-libs/bar.c diff --git a/tests/run-make-fulldeps/redundant-libs/baz.c b/tests/run-make/redundant-libs/baz.c similarity index 100% rename from tests/run-make-fulldeps/redundant-libs/baz.c rename to tests/run-make/redundant-libs/baz.c diff --git a/tests/run-make-fulldeps/redundant-libs/foo.c b/tests/run-make/redundant-libs/foo.c similarity index 100% rename from tests/run-make-fulldeps/redundant-libs/foo.c rename to tests/run-make/redundant-libs/foo.c diff --git a/tests/run-make-fulldeps/redundant-libs/main.rs b/tests/run-make/redundant-libs/main.rs similarity index 100% rename from tests/run-make-fulldeps/redundant-libs/main.rs rename to tests/run-make/redundant-libs/main.rs diff --git a/tests/run-make-fulldeps/relocation-model/Makefile b/tests/run-make/relocation-model/Makefile similarity index 100% rename from tests/run-make-fulldeps/relocation-model/Makefile rename to tests/run-make/relocation-model/Makefile diff --git a/tests/run-make-fulldeps/relocation-model/foo.rs b/tests/run-make/relocation-model/foo.rs similarity index 100% rename from tests/run-make-fulldeps/relocation-model/foo.rs rename to tests/run-make/relocation-model/foo.rs diff --git a/tests/run-make-fulldeps/relro-levels/Makefile b/tests/run-make/relro-levels/Makefile similarity index 100% rename from tests/run-make-fulldeps/relro-levels/Makefile rename to tests/run-make/relro-levels/Makefile diff --git a/tests/run-make-fulldeps/relro-levels/hello.rs b/tests/run-make/relro-levels/hello.rs similarity index 100% rename from tests/run-make-fulldeps/relro-levels/hello.rs rename to tests/run-make/relro-levels/hello.rs diff --git a/tests/run-make-fulldeps/remap-path-prefix/Makefile b/tests/run-make/remap-path-prefix/Makefile similarity index 100% rename from tests/run-make-fulldeps/remap-path-prefix/Makefile rename to tests/run-make/remap-path-prefix/Makefile diff --git a/tests/run-make-fulldeps/remap-path-prefix/auxiliary/lib.rs b/tests/run-make/remap-path-prefix/auxiliary/lib.rs similarity index 100% rename from tests/run-make-fulldeps/remap-path-prefix/auxiliary/lib.rs rename to tests/run-make/remap-path-prefix/auxiliary/lib.rs diff --git a/tests/run-make-fulldeps/reproducible-build-2/Makefile b/tests/run-make/reproducible-build-2/Makefile similarity index 100% rename from tests/run-make-fulldeps/reproducible-build-2/Makefile rename to tests/run-make/reproducible-build-2/Makefile diff --git a/tests/run-make-fulldeps/reproducible-build-2/linker.rs b/tests/run-make/reproducible-build-2/linker.rs similarity index 100% rename from tests/run-make-fulldeps/reproducible-build-2/linker.rs rename to tests/run-make/reproducible-build-2/linker.rs diff --git a/tests/run-make-fulldeps/reproducible-build-2/reproducible-build-aux.rs b/tests/run-make/reproducible-build-2/reproducible-build-aux.rs similarity index 100% rename from tests/run-make-fulldeps/reproducible-build-2/reproducible-build-aux.rs rename to tests/run-make/reproducible-build-2/reproducible-build-aux.rs diff --git a/tests/run-make-fulldeps/reproducible-build-2/reproducible-build.rs b/tests/run-make/reproducible-build-2/reproducible-build.rs similarity index 100% rename from tests/run-make-fulldeps/reproducible-build-2/reproducible-build.rs rename to tests/run-make/reproducible-build-2/reproducible-build.rs diff --git a/tests/run-make-fulldeps/reproducible-build/Makefile b/tests/run-make/reproducible-build/Makefile similarity index 100% rename from tests/run-make-fulldeps/reproducible-build/Makefile rename to tests/run-make/reproducible-build/Makefile diff --git a/tests/run-make-fulldeps/reproducible-build/linker.rs b/tests/run-make/reproducible-build/linker.rs similarity index 100% rename from tests/run-make-fulldeps/reproducible-build/linker.rs rename to tests/run-make/reproducible-build/linker.rs diff --git a/tests/run-make-fulldeps/reproducible-build/reproducible-build-aux.rs b/tests/run-make/reproducible-build/reproducible-build-aux.rs similarity index 100% rename from tests/run-make-fulldeps/reproducible-build/reproducible-build-aux.rs rename to tests/run-make/reproducible-build/reproducible-build-aux.rs diff --git a/tests/run-make-fulldeps/reproducible-build/reproducible-build.rs b/tests/run-make/reproducible-build/reproducible-build.rs similarity index 100% rename from tests/run-make-fulldeps/reproducible-build/reproducible-build.rs rename to tests/run-make/reproducible-build/reproducible-build.rs diff --git a/tests/run-make-fulldeps/resolve-rename/Makefile b/tests/run-make/resolve-rename/Makefile similarity index 100% rename from tests/run-make-fulldeps/resolve-rename/Makefile rename to tests/run-make/resolve-rename/Makefile diff --git a/tests/run-make-fulldeps/resolve-rename/bar.rs b/tests/run-make/resolve-rename/bar.rs similarity index 100% rename from tests/run-make-fulldeps/resolve-rename/bar.rs rename to tests/run-make/resolve-rename/bar.rs diff --git a/tests/run-make-fulldeps/resolve-rename/baz.rs b/tests/run-make/resolve-rename/baz.rs similarity index 100% rename from tests/run-make-fulldeps/resolve-rename/baz.rs rename to tests/run-make/resolve-rename/baz.rs diff --git a/tests/run-make-fulldeps/resolve-rename/foo.rs b/tests/run-make/resolve-rename/foo.rs similarity index 100% rename from tests/run-make-fulldeps/resolve-rename/foo.rs rename to tests/run-make/resolve-rename/foo.rs diff --git a/tests/run-make-fulldeps/return-non-c-like-enum-from-c/Makefile b/tests/run-make/return-non-c-like-enum-from-c/Makefile similarity index 100% rename from tests/run-make-fulldeps/return-non-c-like-enum-from-c/Makefile rename to tests/run-make/return-non-c-like-enum-from-c/Makefile diff --git a/tests/run-make-fulldeps/return-non-c-like-enum-from-c/nonclike.rs b/tests/run-make/return-non-c-like-enum-from-c/nonclike.rs similarity index 100% rename from tests/run-make-fulldeps/return-non-c-like-enum-from-c/nonclike.rs rename to tests/run-make/return-non-c-like-enum-from-c/nonclike.rs diff --git a/tests/run-make-fulldeps/return-non-c-like-enum-from-c/test.c b/tests/run-make/return-non-c-like-enum-from-c/test.c similarity index 100% rename from tests/run-make-fulldeps/return-non-c-like-enum-from-c/test.c rename to tests/run-make/return-non-c-like-enum-from-c/test.c diff --git a/tests/run-make-fulldeps/return-non-c-like-enum/Makefile b/tests/run-make/return-non-c-like-enum/Makefile similarity index 100% rename from tests/run-make-fulldeps/return-non-c-like-enum/Makefile rename to tests/run-make/return-non-c-like-enum/Makefile diff --git a/tests/run-make-fulldeps/return-non-c-like-enum/nonclike.rs b/tests/run-make/return-non-c-like-enum/nonclike.rs similarity index 100% rename from tests/run-make-fulldeps/return-non-c-like-enum/nonclike.rs rename to tests/run-make/return-non-c-like-enum/nonclike.rs diff --git a/tests/run-make-fulldeps/return-non-c-like-enum/test.c b/tests/run-make/return-non-c-like-enum/test.c similarity index 100% rename from tests/run-make-fulldeps/return-non-c-like-enum/test.c rename to tests/run-make/return-non-c-like-enum/test.c diff --git a/tests/run-make-fulldeps/rlib-chain/Makefile b/tests/run-make/rlib-chain/Makefile similarity index 100% rename from tests/run-make-fulldeps/rlib-chain/Makefile rename to tests/run-make/rlib-chain/Makefile diff --git a/tests/run-make-fulldeps/rlib-chain/m1.rs b/tests/run-make/rlib-chain/m1.rs similarity index 100% rename from tests/run-make-fulldeps/rlib-chain/m1.rs rename to tests/run-make/rlib-chain/m1.rs diff --git a/tests/run-make-fulldeps/rlib-chain/m2.rs b/tests/run-make/rlib-chain/m2.rs similarity index 100% rename from tests/run-make-fulldeps/rlib-chain/m2.rs rename to tests/run-make/rlib-chain/m2.rs diff --git a/tests/run-make-fulldeps/rlib-chain/m3.rs b/tests/run-make/rlib-chain/m3.rs similarity index 100% rename from tests/run-make-fulldeps/rlib-chain/m3.rs rename to tests/run-make/rlib-chain/m3.rs diff --git a/tests/run-make-fulldeps/rlib-chain/m4.rs b/tests/run-make/rlib-chain/m4.rs similarity index 100% rename from tests/run-make-fulldeps/rlib-chain/m4.rs rename to tests/run-make/rlib-chain/m4.rs diff --git a/tests/run-make/rlib-format-packed-bundled-libs/Makefile b/tests/run-make/rlib-format-packed-bundled-libs/Makefile index 7fb6ce8d1e4..046c82f9469 100644 --- a/tests/run-make/rlib-format-packed-bundled-libs/Makefile +++ b/tests/run-make/rlib-format-packed-bundled-libs/Makefile @@ -1,4 +1,4 @@ --include ../../run-make-fulldeps/tools.mk +include ../../run-make-fulldeps/tools.mk # ignore-cross-compile diff --git a/tests/run-make-fulldeps/rustdoc-determinism/Makefile b/tests/run-make/rustdoc-determinism/Makefile similarity index 100% rename from tests/run-make-fulldeps/rustdoc-determinism/Makefile rename to tests/run-make/rustdoc-determinism/Makefile diff --git a/tests/run-make-fulldeps/rustdoc-determinism/bar.rs b/tests/run-make/rustdoc-determinism/bar.rs similarity index 100% rename from tests/run-make-fulldeps/rustdoc-determinism/bar.rs rename to tests/run-make/rustdoc-determinism/bar.rs diff --git a/tests/run-make-fulldeps/rustdoc-determinism/foo.rs b/tests/run-make/rustdoc-determinism/foo.rs similarity index 100% rename from tests/run-make-fulldeps/rustdoc-determinism/foo.rs rename to tests/run-make/rustdoc-determinism/foo.rs diff --git a/tests/run-make-fulldeps/rustdoc-error-lines/Makefile b/tests/run-make/rustdoc-error-lines/Makefile similarity index 100% rename from tests/run-make-fulldeps/rustdoc-error-lines/Makefile rename to tests/run-make/rustdoc-error-lines/Makefile diff --git a/tests/run-make-fulldeps/rustdoc-error-lines/input.rs b/tests/run-make/rustdoc-error-lines/input.rs similarity index 100% rename from tests/run-make-fulldeps/rustdoc-error-lines/input.rs rename to tests/run-make/rustdoc-error-lines/input.rs diff --git a/tests/run-make-fulldeps/rustdoc-io-error/Makefile b/tests/run-make/rustdoc-io-error/Makefile similarity index 100% rename from tests/run-make-fulldeps/rustdoc-io-error/Makefile rename to tests/run-make/rustdoc-io-error/Makefile diff --git a/tests/run-make-fulldeps/rustdoc-io-error/foo.rs b/tests/run-make/rustdoc-io-error/foo.rs similarity index 100% rename from tests/run-make-fulldeps/rustdoc-io-error/foo.rs rename to tests/run-make/rustdoc-io-error/foo.rs diff --git a/tests/run-make-fulldeps/rustdoc-map-file/Makefile b/tests/run-make/rustdoc-map-file/Makefile similarity index 100% rename from tests/run-make-fulldeps/rustdoc-map-file/Makefile rename to tests/run-make/rustdoc-map-file/Makefile diff --git a/tests/run-make-fulldeps/rustdoc-map-file/expected.json b/tests/run-make/rustdoc-map-file/expected.json similarity index 100% rename from tests/run-make-fulldeps/rustdoc-map-file/expected.json rename to tests/run-make/rustdoc-map-file/expected.json diff --git a/tests/run-make-fulldeps/rustdoc-map-file/foo.rs b/tests/run-make/rustdoc-map-file/foo.rs similarity index 100% rename from tests/run-make-fulldeps/rustdoc-map-file/foo.rs rename to tests/run-make/rustdoc-map-file/foo.rs diff --git a/tests/run-make-fulldeps/rustdoc-map-file/validate_json.py b/tests/run-make/rustdoc-map-file/validate_json.py similarity index 100% rename from tests/run-make-fulldeps/rustdoc-map-file/validate_json.py rename to tests/run-make/rustdoc-map-file/validate_json.py diff --git a/tests/run-make-fulldeps/rustdoc-output-path/Makefile b/tests/run-make/rustdoc-output-path/Makefile similarity index 100% rename from tests/run-make-fulldeps/rustdoc-output-path/Makefile rename to tests/run-make/rustdoc-output-path/Makefile diff --git a/tests/run-make-fulldeps/rustdoc-output-path/foo.rs b/tests/run-make/rustdoc-output-path/foo.rs similarity index 100% rename from tests/run-make-fulldeps/rustdoc-output-path/foo.rs rename to tests/run-make/rustdoc-output-path/foo.rs diff --git a/tests/run-make-fulldeps/rustdoc-scrape-examples-macros/Makefile b/tests/run-make/rustdoc-scrape-examples-macros/Makefile similarity index 95% rename from tests/run-make-fulldeps/rustdoc-scrape-examples-macros/Makefile rename to tests/run-make/rustdoc-scrape-examples-macros/Makefile index c857aa4b993..3cc6dcac366 100644 --- a/tests/run-make-fulldeps/rustdoc-scrape-examples-macros/Makefile +++ b/tests/run-make/rustdoc-scrape-examples-macros/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../../run-make/tools.mk OUTPUT_DIR := "$(TMPDIR)/rustdoc" DYLIB_NAME := $(shell echo | $(RUSTC) --crate-name foobar_macro --crate-type dylib --print file-names -) diff --git a/tests/run-make-fulldeps/rustdoc-scrape-examples-macros/examples/ex.rs b/tests/run-make/rustdoc-scrape-examples-macros/examples/ex.rs similarity index 100% rename from tests/run-make-fulldeps/rustdoc-scrape-examples-macros/examples/ex.rs rename to tests/run-make/rustdoc-scrape-examples-macros/examples/ex.rs diff --git a/tests/run-make-fulldeps/rustdoc-scrape-examples-macros/src/lib.rs b/tests/run-make/rustdoc-scrape-examples-macros/src/lib.rs similarity index 100% rename from tests/run-make-fulldeps/rustdoc-scrape-examples-macros/src/lib.rs rename to tests/run-make/rustdoc-scrape-examples-macros/src/lib.rs diff --git a/tests/run-make-fulldeps/rustdoc-scrape-examples-macros/src/proc.rs b/tests/run-make/rustdoc-scrape-examples-macros/src/proc.rs similarity index 100% rename from tests/run-make-fulldeps/rustdoc-scrape-examples-macros/src/proc.rs rename to tests/run-make/rustdoc-scrape-examples-macros/src/proc.rs diff --git a/tests/run-make-fulldeps/rustdoc-target-spec-json-path/Makefile b/tests/run-make/rustdoc-target-spec-json-path/Makefile similarity index 100% rename from tests/run-make-fulldeps/rustdoc-target-spec-json-path/Makefile rename to tests/run-make/rustdoc-target-spec-json-path/Makefile diff --git a/tests/run-make-fulldeps/rustdoc-target-spec-json-path/dummy_core.rs b/tests/run-make/rustdoc-target-spec-json-path/dummy_core.rs similarity index 100% rename from tests/run-make-fulldeps/rustdoc-target-spec-json-path/dummy_core.rs rename to tests/run-make/rustdoc-target-spec-json-path/dummy_core.rs diff --git a/tests/run-make-fulldeps/rustdoc-target-spec-json-path/my_crate.rs b/tests/run-make/rustdoc-target-spec-json-path/my_crate.rs similarity index 100% rename from tests/run-make-fulldeps/rustdoc-target-spec-json-path/my_crate.rs rename to tests/run-make/rustdoc-target-spec-json-path/my_crate.rs diff --git a/tests/run-make-fulldeps/rustdoc-target-spec-json-path/target.json b/tests/run-make/rustdoc-target-spec-json-path/target.json similarity index 100% rename from tests/run-make-fulldeps/rustdoc-target-spec-json-path/target.json rename to tests/run-make/rustdoc-target-spec-json-path/target.json diff --git a/tests/run-make-fulldeps/rustdoc-themes/Makefile b/tests/run-make/rustdoc-themes/Makefile similarity index 100% rename from tests/run-make-fulldeps/rustdoc-themes/Makefile rename to tests/run-make/rustdoc-themes/Makefile diff --git a/tests/run-make-fulldeps/rustdoc-themes/foo.rs b/tests/run-make/rustdoc-themes/foo.rs similarity index 100% rename from tests/run-make-fulldeps/rustdoc-themes/foo.rs rename to tests/run-make/rustdoc-themes/foo.rs diff --git a/tests/run-make-fulldeps/sanitizer-cdylib-link/Makefile b/tests/run-make/sanitizer-cdylib-link/Makefile similarity index 100% rename from tests/run-make-fulldeps/sanitizer-cdylib-link/Makefile rename to tests/run-make/sanitizer-cdylib-link/Makefile diff --git a/tests/run-make-fulldeps/sanitizer-cdylib-link/library.rs b/tests/run-make/sanitizer-cdylib-link/library.rs similarity index 100% rename from tests/run-make-fulldeps/sanitizer-cdylib-link/library.rs rename to tests/run-make/sanitizer-cdylib-link/library.rs diff --git a/tests/run-make-fulldeps/sanitizer-cdylib-link/program.rs b/tests/run-make/sanitizer-cdylib-link/program.rs similarity index 100% rename from tests/run-make-fulldeps/sanitizer-cdylib-link/program.rs rename to tests/run-make/sanitizer-cdylib-link/program.rs diff --git a/tests/run-make-fulldeps/sanitizer-dylib-link/Makefile b/tests/run-make/sanitizer-dylib-link/Makefile similarity index 100% rename from tests/run-make-fulldeps/sanitizer-dylib-link/Makefile rename to tests/run-make/sanitizer-dylib-link/Makefile diff --git a/tests/run-make-fulldeps/sanitizer-dylib-link/library.rs b/tests/run-make/sanitizer-dylib-link/library.rs similarity index 100% rename from tests/run-make-fulldeps/sanitizer-dylib-link/library.rs rename to tests/run-make/sanitizer-dylib-link/library.rs diff --git a/tests/run-make-fulldeps/sanitizer-dylib-link/program.rs b/tests/run-make/sanitizer-dylib-link/program.rs similarity index 100% rename from tests/run-make-fulldeps/sanitizer-dylib-link/program.rs rename to tests/run-make/sanitizer-dylib-link/program.rs diff --git a/tests/run-make-fulldeps/sanitizer-staticlib-link/Makefile b/tests/run-make/sanitizer-staticlib-link/Makefile similarity index 100% rename from tests/run-make-fulldeps/sanitizer-staticlib-link/Makefile rename to tests/run-make/sanitizer-staticlib-link/Makefile diff --git a/tests/run-make-fulldeps/sanitizer-staticlib-link/library.rs b/tests/run-make/sanitizer-staticlib-link/library.rs similarity index 100% rename from tests/run-make-fulldeps/sanitizer-staticlib-link/library.rs rename to tests/run-make/sanitizer-staticlib-link/library.rs diff --git a/tests/run-make-fulldeps/sanitizer-staticlib-link/program.c b/tests/run-make/sanitizer-staticlib-link/program.c similarity index 100% rename from tests/run-make-fulldeps/sanitizer-staticlib-link/program.c rename to tests/run-make/sanitizer-staticlib-link/program.c diff --git a/tests/run-make-fulldeps/sanitizer-staticlib-link/program.rs b/tests/run-make/sanitizer-staticlib-link/program.rs similarity index 100% rename from tests/run-make-fulldeps/sanitizer-staticlib-link/program.rs rename to tests/run-make/sanitizer-staticlib-link/program.rs diff --git a/tests/run-make-fulldeps/separate-link-fail/Makefile b/tests/run-make/separate-link-fail/Makefile similarity index 100% rename from tests/run-make-fulldeps/separate-link-fail/Makefile rename to tests/run-make/separate-link-fail/Makefile diff --git a/tests/run-make-fulldeps/separate-link/Makefile b/tests/run-make/separate-link/Makefile similarity index 100% rename from tests/run-make-fulldeps/separate-link/Makefile rename to tests/run-make/separate-link/Makefile diff --git a/tests/run-make-fulldeps/sepcomp-cci-copies/Makefile b/tests/run-make/sepcomp-cci-copies/Makefile similarity index 100% rename from tests/run-make-fulldeps/sepcomp-cci-copies/Makefile rename to tests/run-make/sepcomp-cci-copies/Makefile diff --git a/tests/run-make-fulldeps/sepcomp-cci-copies/cci_lib.rs b/tests/run-make/sepcomp-cci-copies/cci_lib.rs similarity index 100% rename from tests/run-make-fulldeps/sepcomp-cci-copies/cci_lib.rs rename to tests/run-make/sepcomp-cci-copies/cci_lib.rs diff --git a/tests/run-make-fulldeps/sepcomp-cci-copies/foo.rs b/tests/run-make/sepcomp-cci-copies/foo.rs similarity index 100% rename from tests/run-make-fulldeps/sepcomp-cci-copies/foo.rs rename to tests/run-make/sepcomp-cci-copies/foo.rs diff --git a/tests/run-make-fulldeps/sepcomp-inlining/Makefile b/tests/run-make/sepcomp-inlining/Makefile similarity index 100% rename from tests/run-make-fulldeps/sepcomp-inlining/Makefile rename to tests/run-make/sepcomp-inlining/Makefile diff --git a/tests/run-make-fulldeps/sepcomp-inlining/foo.rs b/tests/run-make/sepcomp-inlining/foo.rs similarity index 100% rename from tests/run-make-fulldeps/sepcomp-inlining/foo.rs rename to tests/run-make/sepcomp-inlining/foo.rs diff --git a/tests/run-make-fulldeps/sepcomp-separate/Makefile b/tests/run-make/sepcomp-separate/Makefile similarity index 100% rename from tests/run-make-fulldeps/sepcomp-separate/Makefile rename to tests/run-make/sepcomp-separate/Makefile diff --git a/tests/run-make-fulldeps/sepcomp-separate/foo.rs b/tests/run-make/sepcomp-separate/foo.rs similarity index 100% rename from tests/run-make-fulldeps/sepcomp-separate/foo.rs rename to tests/run-make/sepcomp-separate/foo.rs diff --git a/tests/run-make-fulldeps/share-generics-dylib/Makefile b/tests/run-make/share-generics-dylib/Makefile similarity index 100% rename from tests/run-make-fulldeps/share-generics-dylib/Makefile rename to tests/run-make/share-generics-dylib/Makefile diff --git a/tests/run-make-fulldeps/share-generics-dylib/instance_provider_a.rs b/tests/run-make/share-generics-dylib/instance_provider_a.rs similarity index 100% rename from tests/run-make-fulldeps/share-generics-dylib/instance_provider_a.rs rename to tests/run-make/share-generics-dylib/instance_provider_a.rs diff --git a/tests/run-make-fulldeps/share-generics-dylib/instance_provider_b.rs b/tests/run-make/share-generics-dylib/instance_provider_b.rs similarity index 100% rename from tests/run-make-fulldeps/share-generics-dylib/instance_provider_b.rs rename to tests/run-make/share-generics-dylib/instance_provider_b.rs diff --git a/tests/run-make-fulldeps/share-generics-dylib/instance_user_a_rlib.rs b/tests/run-make/share-generics-dylib/instance_user_a_rlib.rs similarity index 100% rename from tests/run-make-fulldeps/share-generics-dylib/instance_user_a_rlib.rs rename to tests/run-make/share-generics-dylib/instance_user_a_rlib.rs diff --git a/tests/run-make-fulldeps/share-generics-dylib/instance_user_b_rlib.rs b/tests/run-make/share-generics-dylib/instance_user_b_rlib.rs similarity index 100% rename from tests/run-make-fulldeps/share-generics-dylib/instance_user_b_rlib.rs rename to tests/run-make/share-generics-dylib/instance_user_b_rlib.rs diff --git a/tests/run-make-fulldeps/share-generics-dylib/instance_user_dylib.rs b/tests/run-make/share-generics-dylib/instance_user_dylib.rs similarity index 100% rename from tests/run-make-fulldeps/share-generics-dylib/instance_user_dylib.rs rename to tests/run-make/share-generics-dylib/instance_user_dylib.rs diff --git a/tests/run-make-fulldeps/share-generics-dylib/linked_leaf.rs b/tests/run-make/share-generics-dylib/linked_leaf.rs similarity index 100% rename from tests/run-make-fulldeps/share-generics-dylib/linked_leaf.rs rename to tests/run-make/share-generics-dylib/linked_leaf.rs diff --git a/tests/run-make-fulldeps/simd-ffi/Makefile b/tests/run-make/simd-ffi/Makefile similarity index 100% rename from tests/run-make-fulldeps/simd-ffi/Makefile rename to tests/run-make/simd-ffi/Makefile diff --git a/tests/run-make-fulldeps/simd-ffi/simd.rs b/tests/run-make/simd-ffi/simd.rs similarity index 100% rename from tests/run-make-fulldeps/simd-ffi/simd.rs rename to tests/run-make/simd-ffi/simd.rs diff --git a/tests/run-make-fulldeps/simple-dylib/Makefile b/tests/run-make/simple-dylib/Makefile similarity index 100% rename from tests/run-make-fulldeps/simple-dylib/Makefile rename to tests/run-make/simple-dylib/Makefile diff --git a/tests/run-make-fulldeps/simple-dylib/bar.rs b/tests/run-make/simple-dylib/bar.rs similarity index 100% rename from tests/run-make-fulldeps/simple-dylib/bar.rs rename to tests/run-make/simple-dylib/bar.rs diff --git a/tests/run-make-fulldeps/simple-dylib/foo.rs b/tests/run-make/simple-dylib/foo.rs similarity index 100% rename from tests/run-make-fulldeps/simple-dylib/foo.rs rename to tests/run-make/simple-dylib/foo.rs diff --git a/tests/run-make-fulldeps/simple-rlib/Makefile b/tests/run-make/simple-rlib/Makefile similarity index 100% rename from tests/run-make-fulldeps/simple-rlib/Makefile rename to tests/run-make/simple-rlib/Makefile diff --git a/tests/run-make-fulldeps/simple-rlib/bar.rs b/tests/run-make/simple-rlib/bar.rs similarity index 100% rename from tests/run-make-fulldeps/simple-rlib/bar.rs rename to tests/run-make/simple-rlib/bar.rs diff --git a/tests/run-make-fulldeps/simple-rlib/foo.rs b/tests/run-make/simple-rlib/foo.rs similarity index 100% rename from tests/run-make-fulldeps/simple-rlib/foo.rs rename to tests/run-make/simple-rlib/foo.rs diff --git a/tests/run-make-fulldeps/split-debuginfo/Makefile b/tests/run-make/split-debuginfo/Makefile similarity index 100% rename from tests/run-make-fulldeps/split-debuginfo/Makefile rename to tests/run-make/split-debuginfo/Makefile diff --git a/tests/run-make-fulldeps/split-debuginfo/bar.rs b/tests/run-make/split-debuginfo/bar.rs similarity index 100% rename from tests/run-make-fulldeps/split-debuginfo/bar.rs rename to tests/run-make/split-debuginfo/bar.rs diff --git a/tests/run-make-fulldeps/split-debuginfo/baz.rs b/tests/run-make/split-debuginfo/baz.rs similarity index 100% rename from tests/run-make-fulldeps/split-debuginfo/baz.rs rename to tests/run-make/split-debuginfo/baz.rs diff --git a/tests/run-make-fulldeps/split-debuginfo/foo.rs b/tests/run-make/split-debuginfo/foo.rs similarity index 100% rename from tests/run-make-fulldeps/split-debuginfo/foo.rs rename to tests/run-make/split-debuginfo/foo.rs diff --git a/tests/run-make-fulldeps/split-debuginfo/main.rs b/tests/run-make/split-debuginfo/main.rs similarity index 100% rename from tests/run-make-fulldeps/split-debuginfo/main.rs rename to tests/run-make/split-debuginfo/main.rs diff --git a/tests/run-make-fulldeps/stable-symbol-names/Makefile b/tests/run-make/stable-symbol-names/Makefile similarity index 100% rename from tests/run-make-fulldeps/stable-symbol-names/Makefile rename to tests/run-make/stable-symbol-names/Makefile diff --git a/tests/run-make-fulldeps/stable-symbol-names/stable-symbol-names1.rs b/tests/run-make/stable-symbol-names/stable-symbol-names1.rs similarity index 100% rename from tests/run-make-fulldeps/stable-symbol-names/stable-symbol-names1.rs rename to tests/run-make/stable-symbol-names/stable-symbol-names1.rs diff --git a/tests/run-make-fulldeps/stable-symbol-names/stable-symbol-names2.rs b/tests/run-make/stable-symbol-names/stable-symbol-names2.rs similarity index 100% rename from tests/run-make-fulldeps/stable-symbol-names/stable-symbol-names2.rs rename to tests/run-make/stable-symbol-names/stable-symbol-names2.rs diff --git a/tests/run-make-fulldeps/static-dylib-by-default/Makefile b/tests/run-make/static-dylib-by-default/Makefile similarity index 100% rename from tests/run-make-fulldeps/static-dylib-by-default/Makefile rename to tests/run-make/static-dylib-by-default/Makefile diff --git a/tests/run-make-fulldeps/static-dylib-by-default/bar.rs b/tests/run-make/static-dylib-by-default/bar.rs similarity index 100% rename from tests/run-make-fulldeps/static-dylib-by-default/bar.rs rename to tests/run-make/static-dylib-by-default/bar.rs diff --git a/tests/run-make-fulldeps/static-dylib-by-default/foo.rs b/tests/run-make/static-dylib-by-default/foo.rs similarity index 100% rename from tests/run-make-fulldeps/static-dylib-by-default/foo.rs rename to tests/run-make/static-dylib-by-default/foo.rs diff --git a/tests/run-make-fulldeps/static-dylib-by-default/main.c b/tests/run-make/static-dylib-by-default/main.c similarity index 100% rename from tests/run-make-fulldeps/static-dylib-by-default/main.c rename to tests/run-make/static-dylib-by-default/main.c diff --git a/tests/run-make-fulldeps/static-extern-type/Makefile b/tests/run-make/static-extern-type/Makefile similarity index 100% rename from tests/run-make-fulldeps/static-extern-type/Makefile rename to tests/run-make/static-extern-type/Makefile diff --git a/tests/run-make-fulldeps/static-extern-type/define-foo.c b/tests/run-make/static-extern-type/define-foo.c similarity index 100% rename from tests/run-make-fulldeps/static-extern-type/define-foo.c rename to tests/run-make/static-extern-type/define-foo.c diff --git a/tests/run-make-fulldeps/static-extern-type/use-foo.rs b/tests/run-make/static-extern-type/use-foo.rs similarity index 100% rename from tests/run-make-fulldeps/static-extern-type/use-foo.rs rename to tests/run-make/static-extern-type/use-foo.rs diff --git a/tests/run-make-fulldeps/static-unwinding/Makefile b/tests/run-make/static-unwinding/Makefile similarity index 100% rename from tests/run-make-fulldeps/static-unwinding/Makefile rename to tests/run-make/static-unwinding/Makefile diff --git a/tests/run-make-fulldeps/static-unwinding/lib.rs b/tests/run-make/static-unwinding/lib.rs similarity index 100% rename from tests/run-make-fulldeps/static-unwinding/lib.rs rename to tests/run-make/static-unwinding/lib.rs diff --git a/tests/run-make-fulldeps/static-unwinding/main.rs b/tests/run-make/static-unwinding/main.rs similarity index 100% rename from tests/run-make-fulldeps/static-unwinding/main.rs rename to tests/run-make/static-unwinding/main.rs diff --git a/tests/run-make-fulldeps/staticlib-blank-lib/Makefile b/tests/run-make/staticlib-blank-lib/Makefile similarity index 100% rename from tests/run-make-fulldeps/staticlib-blank-lib/Makefile rename to tests/run-make/staticlib-blank-lib/Makefile diff --git a/tests/run-make-fulldeps/staticlib-blank-lib/foo.rs b/tests/run-make/staticlib-blank-lib/foo.rs similarity index 100% rename from tests/run-make-fulldeps/staticlib-blank-lib/foo.rs rename to tests/run-make/staticlib-blank-lib/foo.rs diff --git a/tests/run-make-fulldeps/std-core-cycle/Makefile b/tests/run-make/std-core-cycle/Makefile similarity index 100% rename from tests/run-make-fulldeps/std-core-cycle/Makefile rename to tests/run-make/std-core-cycle/Makefile diff --git a/tests/run-make-fulldeps/std-core-cycle/bar.rs b/tests/run-make/std-core-cycle/bar.rs similarity index 100% rename from tests/run-make-fulldeps/std-core-cycle/bar.rs rename to tests/run-make/std-core-cycle/bar.rs diff --git a/tests/run-make-fulldeps/std-core-cycle/foo.rs b/tests/run-make/std-core-cycle/foo.rs similarity index 100% rename from tests/run-make-fulldeps/std-core-cycle/foo.rs rename to tests/run-make/std-core-cycle/foo.rs diff --git a/tests/run-make-fulldeps/stdin-non-utf8/Makefile b/tests/run-make/stdin-non-utf8/Makefile similarity index 100% rename from tests/run-make-fulldeps/stdin-non-utf8/Makefile rename to tests/run-make/stdin-non-utf8/Makefile diff --git a/tests/run-make-fulldeps/stdin-non-utf8/non-utf8 b/tests/run-make/stdin-non-utf8/non-utf8 similarity index 100% rename from tests/run-make-fulldeps/stdin-non-utf8/non-utf8 rename to tests/run-make/stdin-non-utf8/non-utf8 diff --git a/tests/run-make-fulldeps/suspicious-library/Makefile b/tests/run-make/suspicious-library/Makefile similarity index 100% rename from tests/run-make-fulldeps/suspicious-library/Makefile rename to tests/run-make/suspicious-library/Makefile diff --git a/tests/run-make-fulldeps/suspicious-library/bar.rs b/tests/run-make/suspicious-library/bar.rs similarity index 100% rename from tests/run-make-fulldeps/suspicious-library/bar.rs rename to tests/run-make/suspicious-library/bar.rs diff --git a/tests/run-make-fulldeps/suspicious-library/foo.rs b/tests/run-make/suspicious-library/foo.rs similarity index 100% rename from tests/run-make-fulldeps/suspicious-library/foo.rs rename to tests/run-make/suspicious-library/foo.rs diff --git a/tests/run-make-fulldeps/symbol-visibility/Makefile b/tests/run-make/symbol-visibility/Makefile similarity index 100% rename from tests/run-make-fulldeps/symbol-visibility/Makefile rename to tests/run-make/symbol-visibility/Makefile diff --git a/tests/run-make-fulldeps/symbol-visibility/a_cdylib.rs b/tests/run-make/symbol-visibility/a_cdylib.rs similarity index 100% rename from tests/run-make-fulldeps/symbol-visibility/a_cdylib.rs rename to tests/run-make/symbol-visibility/a_cdylib.rs diff --git a/tests/run-make-fulldeps/symbol-visibility/a_proc_macro.rs b/tests/run-make/symbol-visibility/a_proc_macro.rs similarity index 100% rename from tests/run-make-fulldeps/symbol-visibility/a_proc_macro.rs rename to tests/run-make/symbol-visibility/a_proc_macro.rs diff --git a/tests/run-make-fulldeps/symbol-visibility/a_rust_dylib.rs b/tests/run-make/symbol-visibility/a_rust_dylib.rs similarity index 100% rename from tests/run-make-fulldeps/symbol-visibility/a_rust_dylib.rs rename to tests/run-make/symbol-visibility/a_rust_dylib.rs diff --git a/tests/run-make-fulldeps/symbol-visibility/an_executable.rs b/tests/run-make/symbol-visibility/an_executable.rs similarity index 100% rename from tests/run-make-fulldeps/symbol-visibility/an_executable.rs rename to tests/run-make/symbol-visibility/an_executable.rs diff --git a/tests/run-make-fulldeps/symbol-visibility/an_rlib.rs b/tests/run-make/symbol-visibility/an_rlib.rs similarity index 100% rename from tests/run-make-fulldeps/symbol-visibility/an_rlib.rs rename to tests/run-make/symbol-visibility/an_rlib.rs diff --git a/tests/run-make-fulldeps/symbols-include-type-name/Makefile b/tests/run-make/symbols-include-type-name/Makefile similarity index 100% rename from tests/run-make-fulldeps/symbols-include-type-name/Makefile rename to tests/run-make/symbols-include-type-name/Makefile diff --git a/tests/run-make-fulldeps/symbols-include-type-name/lib.rs b/tests/run-make/symbols-include-type-name/lib.rs similarity index 100% rename from tests/run-make-fulldeps/symbols-include-type-name/lib.rs rename to tests/run-make/symbols-include-type-name/lib.rs diff --git a/tests/run-make-fulldeps/symlinked-extern/Makefile b/tests/run-make/symlinked-extern/Makefile similarity index 100% rename from tests/run-make-fulldeps/symlinked-extern/Makefile rename to tests/run-make/symlinked-extern/Makefile diff --git a/tests/run-make-fulldeps/symlinked-extern/bar.rs b/tests/run-make/symlinked-extern/bar.rs similarity index 100% rename from tests/run-make-fulldeps/symlinked-extern/bar.rs rename to tests/run-make/symlinked-extern/bar.rs diff --git a/tests/run-make-fulldeps/symlinked-extern/baz.rs b/tests/run-make/symlinked-extern/baz.rs similarity index 100% rename from tests/run-make-fulldeps/symlinked-extern/baz.rs rename to tests/run-make/symlinked-extern/baz.rs diff --git a/tests/run-make-fulldeps/symlinked-extern/foo.rs b/tests/run-make/symlinked-extern/foo.rs similarity index 100% rename from tests/run-make-fulldeps/symlinked-extern/foo.rs rename to tests/run-make/symlinked-extern/foo.rs diff --git a/tests/run-make-fulldeps/symlinked-libraries/Makefile b/tests/run-make/symlinked-libraries/Makefile similarity index 100% rename from tests/run-make-fulldeps/symlinked-libraries/Makefile rename to tests/run-make/symlinked-libraries/Makefile diff --git a/tests/run-make-fulldeps/symlinked-libraries/bar.rs b/tests/run-make/symlinked-libraries/bar.rs similarity index 100% rename from tests/run-make-fulldeps/symlinked-libraries/bar.rs rename to tests/run-make/symlinked-libraries/bar.rs diff --git a/tests/run-make-fulldeps/symlinked-libraries/foo.rs b/tests/run-make/symlinked-libraries/foo.rs similarity index 100% rename from tests/run-make-fulldeps/symlinked-libraries/foo.rs rename to tests/run-make/symlinked-libraries/foo.rs diff --git a/tests/run-make-fulldeps/symlinked-rlib/Makefile b/tests/run-make/symlinked-rlib/Makefile similarity index 100% rename from tests/run-make-fulldeps/symlinked-rlib/Makefile rename to tests/run-make/symlinked-rlib/Makefile diff --git a/tests/run-make-fulldeps/symlinked-rlib/bar.rs b/tests/run-make/symlinked-rlib/bar.rs similarity index 100% rename from tests/run-make-fulldeps/symlinked-rlib/bar.rs rename to tests/run-make/symlinked-rlib/bar.rs diff --git a/tests/run-make-fulldeps/symlinked-rlib/foo.rs b/tests/run-make/symlinked-rlib/foo.rs similarity index 100% rename from tests/run-make-fulldeps/symlinked-rlib/foo.rs rename to tests/run-make/symlinked-rlib/foo.rs diff --git a/tests/run-make-fulldeps/sysroot-crates-are-unstable/Makefile b/tests/run-make/sysroot-crates-are-unstable/Makefile similarity index 100% rename from tests/run-make-fulldeps/sysroot-crates-are-unstable/Makefile rename to tests/run-make/sysroot-crates-are-unstable/Makefile diff --git a/tests/run-make-fulldeps/sysroot-crates-are-unstable/test.py b/tests/run-make/sysroot-crates-are-unstable/test.py similarity index 100% rename from tests/run-make-fulldeps/sysroot-crates-are-unstable/test.py rename to tests/run-make/sysroot-crates-are-unstable/test.py diff --git a/tests/run-make-fulldeps/target-cpu-native/Makefile b/tests/run-make/target-cpu-native/Makefile similarity index 100% rename from tests/run-make-fulldeps/target-cpu-native/Makefile rename to tests/run-make/target-cpu-native/Makefile diff --git a/tests/run-make-fulldeps/target-cpu-native/foo.rs b/tests/run-make/target-cpu-native/foo.rs similarity index 100% rename from tests/run-make-fulldeps/target-cpu-native/foo.rs rename to tests/run-make/target-cpu-native/foo.rs diff --git a/tests/run-make-fulldeps/target-specs/Makefile b/tests/run-make/target-specs/Makefile similarity index 100% rename from tests/run-make-fulldeps/target-specs/Makefile rename to tests/run-make/target-specs/Makefile diff --git a/tests/run-make-fulldeps/target-specs/definitely-not-builtin-target.json b/tests/run-make/target-specs/definitely-not-builtin-target.json similarity index 100% rename from tests/run-make-fulldeps/target-specs/definitely-not-builtin-target.json rename to tests/run-make/target-specs/definitely-not-builtin-target.json diff --git a/tests/run-make-fulldeps/target-specs/foo.rs b/tests/run-make/target-specs/foo.rs similarity index 100% rename from tests/run-make-fulldeps/target-specs/foo.rs rename to tests/run-make/target-specs/foo.rs diff --git a/tests/run-make-fulldeps/target-specs/mismatching-data-layout.json b/tests/run-make/target-specs/mismatching-data-layout.json similarity index 100% rename from tests/run-make-fulldeps/target-specs/mismatching-data-layout.json rename to tests/run-make/target-specs/mismatching-data-layout.json diff --git a/tests/run-make-fulldeps/target-specs/my-awesome-platform.json b/tests/run-make/target-specs/my-awesome-platform.json similarity index 100% rename from tests/run-make-fulldeps/target-specs/my-awesome-platform.json rename to tests/run-make/target-specs/my-awesome-platform.json diff --git a/tests/run-make-fulldeps/target-specs/my-incomplete-platform.json b/tests/run-make/target-specs/my-incomplete-platform.json similarity index 100% rename from tests/run-make-fulldeps/target-specs/my-incomplete-platform.json rename to tests/run-make/target-specs/my-incomplete-platform.json diff --git a/tests/run-make-fulldeps/target-specs/my-invalid-platform.json b/tests/run-make/target-specs/my-invalid-platform.json similarity index 100% rename from tests/run-make-fulldeps/target-specs/my-invalid-platform.json rename to tests/run-make/target-specs/my-invalid-platform.json diff --git a/tests/run-make-fulldeps/target-specs/my-x86_64-unknown-linux-gnu-platform.json b/tests/run-make/target-specs/my-x86_64-unknown-linux-gnu-platform.json similarity index 100% rename from tests/run-make-fulldeps/target-specs/my-x86_64-unknown-linux-gnu-platform.json rename to tests/run-make/target-specs/my-x86_64-unknown-linux-gnu-platform.json diff --git a/tests/run-make-fulldeps/target-without-atomic-cas/Makefile b/tests/run-make/target-without-atomic-cas/Makefile similarity index 100% rename from tests/run-make-fulldeps/target-without-atomic-cas/Makefile rename to tests/run-make/target-without-atomic-cas/Makefile diff --git a/tests/run-make-fulldeps/test-harness/Makefile b/tests/run-make/test-harness/Makefile similarity index 100% rename from tests/run-make-fulldeps/test-harness/Makefile rename to tests/run-make/test-harness/Makefile diff --git a/tests/run-make-fulldeps/test-harness/test-ignore-cfg.rs b/tests/run-make/test-harness/test-ignore-cfg.rs similarity index 100% rename from tests/run-make-fulldeps/test-harness/test-ignore-cfg.rs rename to tests/run-make/test-harness/test-ignore-cfg.rs diff --git a/tests/run-make-fulldeps/type-mismatch-same-crate-name/Makefile b/tests/run-make/type-mismatch-same-crate-name/Makefile similarity index 100% rename from tests/run-make-fulldeps/type-mismatch-same-crate-name/Makefile rename to tests/run-make/type-mismatch-same-crate-name/Makefile diff --git a/tests/run-make-fulldeps/type-mismatch-same-crate-name/crateA.rs b/tests/run-make/type-mismatch-same-crate-name/crateA.rs similarity index 100% rename from tests/run-make-fulldeps/type-mismatch-same-crate-name/crateA.rs rename to tests/run-make/type-mismatch-same-crate-name/crateA.rs diff --git a/tests/run-make-fulldeps/type-mismatch-same-crate-name/crateB.rs b/tests/run-make/type-mismatch-same-crate-name/crateB.rs similarity index 100% rename from tests/run-make-fulldeps/type-mismatch-same-crate-name/crateB.rs rename to tests/run-make/type-mismatch-same-crate-name/crateB.rs diff --git a/tests/run-make-fulldeps/type-mismatch-same-crate-name/crateC.rs b/tests/run-make/type-mismatch-same-crate-name/crateC.rs similarity index 100% rename from tests/run-make-fulldeps/type-mismatch-same-crate-name/crateC.rs rename to tests/run-make/type-mismatch-same-crate-name/crateC.rs diff --git a/tests/run-make-fulldeps/use-extern-for-plugins/Makefile b/tests/run-make/use-extern-for-plugins/Makefile similarity index 100% rename from tests/run-make-fulldeps/use-extern-for-plugins/Makefile rename to tests/run-make/use-extern-for-plugins/Makefile diff --git a/tests/run-make-fulldeps/use-extern-for-plugins/bar.rs b/tests/run-make/use-extern-for-plugins/bar.rs similarity index 100% rename from tests/run-make-fulldeps/use-extern-for-plugins/bar.rs rename to tests/run-make/use-extern-for-plugins/bar.rs diff --git a/tests/run-make-fulldeps/use-extern-for-plugins/baz.rs b/tests/run-make/use-extern-for-plugins/baz.rs similarity index 100% rename from tests/run-make-fulldeps/use-extern-for-plugins/baz.rs rename to tests/run-make/use-extern-for-plugins/baz.rs diff --git a/tests/run-make-fulldeps/use-extern-for-plugins/foo.rs b/tests/run-make/use-extern-for-plugins/foo.rs similarity index 100% rename from tests/run-make-fulldeps/use-extern-for-plugins/foo.rs rename to tests/run-make/use-extern-for-plugins/foo.rs diff --git a/tests/run-make-fulldeps/use-suggestions-rust-2018/Makefile b/tests/run-make/use-suggestions-rust-2018/Makefile similarity index 100% rename from tests/run-make-fulldeps/use-suggestions-rust-2018/Makefile rename to tests/run-make/use-suggestions-rust-2018/Makefile diff --git a/tests/run-make-fulldeps/use-suggestions-rust-2018/ep-nested-lib.rs b/tests/run-make/use-suggestions-rust-2018/ep-nested-lib.rs similarity index 100% rename from tests/run-make-fulldeps/use-suggestions-rust-2018/ep-nested-lib.rs rename to tests/run-make/use-suggestions-rust-2018/ep-nested-lib.rs diff --git a/tests/run-make-fulldeps/use-suggestions-rust-2018/use-suggestions.rs b/tests/run-make/use-suggestions-rust-2018/use-suggestions.rs similarity index 100% rename from tests/run-make-fulldeps/use-suggestions-rust-2018/use-suggestions.rs rename to tests/run-make/use-suggestions-rust-2018/use-suggestions.rs diff --git a/tests/run-make-fulldeps/used-cdylib-macos/Makefile b/tests/run-make/used-cdylib-macos/Makefile similarity index 100% rename from tests/run-make-fulldeps/used-cdylib-macos/Makefile rename to tests/run-make/used-cdylib-macos/Makefile diff --git a/tests/run-make-fulldeps/used-cdylib-macos/dylib_used.rs b/tests/run-make/used-cdylib-macos/dylib_used.rs similarity index 100% rename from tests/run-make-fulldeps/used-cdylib-macos/dylib_used.rs rename to tests/run-make/used-cdylib-macos/dylib_used.rs diff --git a/tests/run-make-fulldeps/used/Makefile b/tests/run-make/used/Makefile similarity index 100% rename from tests/run-make-fulldeps/used/Makefile rename to tests/run-make/used/Makefile diff --git a/tests/run-make-fulldeps/used/used.rs b/tests/run-make/used/used.rs similarity index 100% rename from tests/run-make-fulldeps/used/used.rs rename to tests/run-make/used/used.rs diff --git a/tests/run-make-fulldeps/version/Makefile b/tests/run-make/version/Makefile similarity index 100% rename from tests/run-make-fulldeps/version/Makefile rename to tests/run-make/version/Makefile diff --git a/tests/run-make-fulldeps/volatile-intrinsics/Makefile b/tests/run-make/volatile-intrinsics/Makefile similarity index 100% rename from tests/run-make-fulldeps/volatile-intrinsics/Makefile rename to tests/run-make/volatile-intrinsics/Makefile diff --git a/tests/run-make-fulldeps/volatile-intrinsics/main.rs b/tests/run-make/volatile-intrinsics/main.rs similarity index 100% rename from tests/run-make-fulldeps/volatile-intrinsics/main.rs rename to tests/run-make/volatile-intrinsics/main.rs diff --git a/tests/run-make-fulldeps/weird-output-filenames/Makefile b/tests/run-make/weird-output-filenames/Makefile similarity index 100% rename from tests/run-make-fulldeps/weird-output-filenames/Makefile rename to tests/run-make/weird-output-filenames/Makefile diff --git a/tests/run-make-fulldeps/weird-output-filenames/foo.rs b/tests/run-make/weird-output-filenames/foo.rs similarity index 100% rename from tests/run-make-fulldeps/weird-output-filenames/foo.rs rename to tests/run-make/weird-output-filenames/foo.rs diff --git a/tests/run-make-fulldeps/windows-binary-no-external-deps/Makefile b/tests/run-make/windows-binary-no-external-deps/Makefile similarity index 100% rename from tests/run-make-fulldeps/windows-binary-no-external-deps/Makefile rename to tests/run-make/windows-binary-no-external-deps/Makefile diff --git a/tests/run-make-fulldeps/windows-binary-no-external-deps/hello.rs b/tests/run-make/windows-binary-no-external-deps/hello.rs similarity index 100% rename from tests/run-make-fulldeps/windows-binary-no-external-deps/hello.rs rename to tests/run-make/windows-binary-no-external-deps/hello.rs diff --git a/tests/run-make-fulldeps/windows-spawn/Makefile b/tests/run-make/windows-spawn/Makefile similarity index 100% rename from tests/run-make-fulldeps/windows-spawn/Makefile rename to tests/run-make/windows-spawn/Makefile diff --git a/tests/run-make-fulldeps/windows-spawn/hello.rs b/tests/run-make/windows-spawn/hello.rs similarity index 100% rename from tests/run-make-fulldeps/windows-spawn/hello.rs rename to tests/run-make/windows-spawn/hello.rs diff --git a/tests/run-make-fulldeps/windows-spawn/spawn.rs b/tests/run-make/windows-spawn/spawn.rs similarity index 100% rename from tests/run-make-fulldeps/windows-spawn/spawn.rs rename to tests/run-make/windows-spawn/spawn.rs diff --git a/tests/run-make-fulldeps/windows-subsystem/Makefile b/tests/run-make/windows-subsystem/Makefile similarity index 100% rename from tests/run-make-fulldeps/windows-subsystem/Makefile rename to tests/run-make/windows-subsystem/Makefile diff --git a/tests/run-make-fulldeps/windows-subsystem/console.rs b/tests/run-make/windows-subsystem/console.rs similarity index 100% rename from tests/run-make-fulldeps/windows-subsystem/console.rs rename to tests/run-make/windows-subsystem/console.rs diff --git a/tests/run-make-fulldeps/windows-subsystem/windows.rs b/tests/run-make/windows-subsystem/windows.rs similarity index 100% rename from tests/run-make-fulldeps/windows-subsystem/windows.rs rename to tests/run-make/windows-subsystem/windows.rs From 06b2d4b4aba539efe86dc139fef7536533fe4026 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 30 Mar 2023 07:43:59 -0500 Subject: [PATCH 278/346] fix wrong includes --- tests/run-make/issue-97463-abi-param-passing/Makefile | 2 +- tests/run-make/macos-fat-archive/Makefile | 2 +- tests/run-make/print-calling-conventions/Makefile | 2 +- tests/run-make/raw-dylib-import-name-type/Makefile | 2 +- tests/run-make/rlib-format-packed-bundled-libs-2/Makefile | 2 +- tests/run-make/rlib-format-packed-bundled-libs-3/Makefile | 2 +- tests/run-make/track-pgo-dep-info/Makefile | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/run-make/issue-97463-abi-param-passing/Makefile b/tests/run-make/issue-97463-abi-param-passing/Makefile index db1b53e152e..2f9c8c7c8be 100644 --- a/tests/run-make/issue-97463-abi-param-passing/Makefile +++ b/tests/run-make/issue-97463-abi-param-passing/Makefile @@ -1,4 +1,4 @@ --include ../tools.mk +include ../../run-make-fulldeps/tools.mk # ignore-msvc diff --git a/tests/run-make/macos-fat-archive/Makefile b/tests/run-make/macos-fat-archive/Makefile index cc99375db69..8dd9a747686 100644 --- a/tests/run-make/macos-fat-archive/Makefile +++ b/tests/run-make/macos-fat-archive/Makefile @@ -1,6 +1,6 @@ # only-macos --include ../../run-make-fulldeps/tools.mk +include ../../run-make-fulldeps/tools.mk "$(TMPDIR)"/libnative-library.a: native-library.c $(CC) -arch arm64 -arch x86_64 native-library.c -c -o "$(TMPDIR)"/native-library.o diff --git a/tests/run-make/print-calling-conventions/Makefile b/tests/run-make/print-calling-conventions/Makefile index d3fd06392b0..472b0723b10 100644 --- a/tests/run-make/print-calling-conventions/Makefile +++ b/tests/run-make/print-calling-conventions/Makefile @@ -1,4 +1,4 @@ --include ../tools.mk +include ../../run-make-fulldeps/tools.mk all: $(RUSTC) --print calling-conventions diff --git a/tests/run-make/raw-dylib-import-name-type/Makefile b/tests/run-make/raw-dylib-import-name-type/Makefile index fcc60e88e1a..314e22c412d 100644 --- a/tests/run-make/raw-dylib-import-name-type/Makefile +++ b/tests/run-make/raw-dylib-import-name-type/Makefile @@ -3,7 +3,7 @@ # only-x86 # only-windows --include ../../run-make-fulldeps/tools.mk +include ../../run-make-fulldeps/tools.mk all: $(RUSTC) --crate-type bin driver.rs -L "$(TMPDIR)" diff --git a/tests/run-make/rlib-format-packed-bundled-libs-2/Makefile b/tests/run-make/rlib-format-packed-bundled-libs-2/Makefile index 37b8d809a27..440fd3dd588 100644 --- a/tests/run-make/rlib-format-packed-bundled-libs-2/Makefile +++ b/tests/run-make/rlib-format-packed-bundled-libs-2/Makefile @@ -1,4 +1,4 @@ --include ../../run-make-fulldeps/tools.mk +include ../../run-make-fulldeps/tools.mk # ignore-cross-compile diff --git a/tests/run-make/rlib-format-packed-bundled-libs-3/Makefile b/tests/run-make/rlib-format-packed-bundled-libs-3/Makefile index 62dc1b5f606..b2006f3ec92 100644 --- a/tests/run-make/rlib-format-packed-bundled-libs-3/Makefile +++ b/tests/run-make/rlib-format-packed-bundled-libs-3/Makefile @@ -1,4 +1,4 @@ --include ../../run-make-fulldeps/tools.mk +include ../../run-make-fulldeps/tools.mk # ignore-cross-compile # only-linux diff --git a/tests/run-make/track-pgo-dep-info/Makefile b/tests/run-make/track-pgo-dep-info/Makefile index 60b59c04aa9..4e1e29f90db 100644 --- a/tests/run-make/track-pgo-dep-info/Makefile +++ b/tests/run-make/track-pgo-dep-info/Makefile @@ -1,7 +1,7 @@ # needs-profiler-support # ignore-windows-gnu --include ../../run-make-fulldeps/tools.mk +include ../../run-make-fulldeps/tools.mk # FIXME(eddyb) provide `HOST_RUSTC` and `TARGET_RUSTC` # instead of hardcoding them everywhere they're needed. From f015e6fe499f0d6dc2c3ea7422ac8efd1ddb3920 Mon Sep 17 00:00:00 2001 From: joboet Date: Wed, 22 Mar 2023 13:12:51 +0100 Subject: [PATCH 279/346] core: optimize `LazyCell` size --- library/core/src/cell/lazy.rs | 70 +++++++++++++++++++++++++++++------ 1 file changed, 59 insertions(+), 11 deletions(-) diff --git a/library/core/src/cell/lazy.rs b/library/core/src/cell/lazy.rs index 64a6ce51b2e..13a4c297e8a 100644 --- a/library/core/src/cell/lazy.rs +++ b/library/core/src/cell/lazy.rs @@ -1,6 +1,13 @@ -use crate::cell::{Cell, OnceCell}; -use crate::fmt; use crate::ops::Deref; +use crate::{fmt, mem}; + +use super::UnsafeCell; + +enum State { + Uninit(F), + Init(T), + Poisoned, +} /// A value which is initialized on the first access. /// @@ -31,8 +38,7 @@ use crate::ops::Deref; /// ``` #[unstable(feature = "lazy_cell", issue = "109736")] pub struct LazyCell T> { - cell: OnceCell, - init: Cell>, + state: UnsafeCell>, } impl T> LazyCell { @@ -53,8 +59,8 @@ impl T> LazyCell { /// ``` #[inline] #[unstable(feature = "lazy_cell", issue = "109736")] - pub const fn new(init: F) -> LazyCell { - LazyCell { cell: OnceCell::new(), init: Cell::new(Some(init)) } + pub const fn new(f: F) -> LazyCell { + LazyCell { state: UnsafeCell::new(State::Uninit(f)) } } /// Forces the evaluation of this lazy value and returns a reference to @@ -77,10 +83,47 @@ impl T> LazyCell { #[inline] #[unstable(feature = "lazy_cell", issue = "109736")] pub fn force(this: &LazyCell) -> &T { - this.cell.get_or_init(|| match this.init.take() { - Some(f) => f(), - None => panic!("`Lazy` instance has previously been poisoned"), - }) + let state = unsafe { &*this.state.get() }; + match state { + State::Init(data) => data, + State::Uninit(_) => unsafe { LazyCell::really_init(this) }, + State::Poisoned => panic!("LazyCell has previously been poisoned"), + } + } + + /// # Safety + /// May only be called when the state is `Uninit`. + #[cold] + unsafe fn really_init(this: &LazyCell) -> &T { + let state = unsafe { &mut *this.state.get() }; + // Temporarily mark the state as poisoned. This prevents reentrant + // accesses and correctly poisons the cell if the closure panicked. + let State::Uninit(f) = mem::replace(state, State::Poisoned) else { unreachable!() }; + + let data = f(); + + // If the closure accessed the cell, the mutable borrow will be + // invalidated, so create a new one here. + let state = unsafe { &mut *this.state.get() }; + *state = State::Init(data); + + // A reference obtained by downcasting from the mutable borrow + // would become stale if other references are created in `force`. + // Borrow the state directly instead. + let state = unsafe { &*this.state.get() }; + let State::Init(data) = state else { unreachable!() }; + data + } +} + +impl LazyCell { + #[inline] + fn get(&self) -> Option<&T> { + let state = unsafe { &*self.state.get() }; + match state { + State::Init(data) => Some(data), + _ => None, + } } } @@ -105,6 +148,11 @@ impl Default for LazyCell { #[unstable(feature = "lazy_cell", issue = "109736")] impl fmt::Debug for LazyCell { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("Lazy").field("cell", &self.cell).field("init", &"..").finish() + let mut d = f.debug_tuple("LazyCell"); + match self.get() { + Some(data) => d.field(data), + None => d.field(&format_args!("")), + }; + d.finish() } } From c7f9739bada7c54b0d848cd029c4faa4665c9adc Mon Sep 17 00:00:00 2001 From: joboet Date: Tue, 28 Mar 2023 11:33:44 +0200 Subject: [PATCH 280/346] core: improve code documentation for `LazyCell` --- library/core/src/cell/lazy.rs | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/library/core/src/cell/lazy.rs b/library/core/src/cell/lazy.rs index 13a4c297e8a..4039cc26812 100644 --- a/library/core/src/cell/lazy.rs +++ b/library/core/src/cell/lazy.rs @@ -83,9 +83,15 @@ impl T> LazyCell { #[inline] #[unstable(feature = "lazy_cell", issue = "109736")] pub fn force(this: &LazyCell) -> &T { + // SAFETY: + // This invalidates any mutable references to the data. The resulting + // reference lives either until the end of the borrow of `this` (in the + // initialized case) or is invalidates in `really_init` (in the + // uninitialized case). let state = unsafe { &*this.state.get() }; match state { State::Init(data) => data, + // SAFETY: The state is uninitialized. State::Uninit(_) => unsafe { LazyCell::really_init(this) }, State::Poisoned => panic!("LazyCell has previously been poisoned"), } @@ -95,6 +101,10 @@ impl T> LazyCell { /// May only be called when the state is `Uninit`. #[cold] unsafe fn really_init(this: &LazyCell) -> &T { + // SAFETY: + // This function is only called when the state is uninitialized, + // so no references to `state` can exist except for the reference + // in `force`, which is invalidated here and not accessed again. let state = unsafe { &mut *this.state.get() }; // Temporarily mark the state as poisoned. This prevents reentrant // accesses and correctly poisons the cell if the closure panicked. @@ -102,14 +112,19 @@ impl T> LazyCell { let data = f(); - // If the closure accessed the cell, the mutable borrow will be - // invalidated, so create a new one here. + // SAFETY: + // If the closure accessed the cell through something like a reentrant + // mutex, but caught the panic resulting from the state being poisoned, + // the mutable borrow for `state` will be invalidated, so create a new + // one here. let state = unsafe { &mut *this.state.get() }; *state = State::Init(data); - // A reference obtained by downcasting from the mutable borrow - // would become stale if other references are created in `force`. - // Borrow the state directly instead. + // SAFETY: + // A reference obtained by downcasting from the mutable borrow would + // become stale the next time `force` is called (since there is a conflict + // between the mutable reference here and the shared reference there). + // Do a new shared borrow of the state instead. let state = unsafe { &*this.state.get() }; let State::Init(data) = state else { unreachable!() }; data @@ -119,6 +134,10 @@ impl T> LazyCell { impl LazyCell { #[inline] fn get(&self) -> Option<&T> { + // SAFETY: + // This is sound for the same reason as in `force`: once the state is + // initialized, it will not be mutably accessed again, so this reference + // will stay valid for the duration of the borrow to `self`. let state = unsafe { &*self.state.get() }; match state { State::Init(data) => Some(data), From 97d49fcf60e0da214d8e08cb914821400d421caf Mon Sep 17 00:00:00 2001 From: joboet Date: Tue, 28 Mar 2023 11:39:09 +0200 Subject: [PATCH 281/346] core: use `pointer::write` to cleanup `LazyCell` initialization --- library/core/src/cell/lazy.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/library/core/src/cell/lazy.rs b/library/core/src/cell/lazy.rs index 4039cc26812..aff3388529a 100644 --- a/library/core/src/cell/lazy.rs +++ b/library/core/src/cell/lazy.rs @@ -115,16 +115,15 @@ impl T> LazyCell { // SAFETY: // If the closure accessed the cell through something like a reentrant // mutex, but caught the panic resulting from the state being poisoned, - // the mutable borrow for `state` will be invalidated, so create a new - // one here. - let state = unsafe { &mut *this.state.get() }; - *state = State::Init(data); + // the mutable borrow for `state` will be invalidated, so we need to + // go through the `UnsafeCell` pointer here. The state can only be + // poisoned at this point, so using `write` to skip the destructor + // of `State` should help the optimizer. + unsafe { this.state.get().write(State::Init(data)) }; // SAFETY: - // A reference obtained by downcasting from the mutable borrow would - // become stale the next time `force` is called (since there is a conflict - // between the mutable reference here and the shared reference there). - // Do a new shared borrow of the state instead. + // The previous references were invalidated by the `write` call above, + // so do a new shared borrow of the state instead. let state = unsafe { &*this.state.get() }; let State::Init(data) = state else { unreachable!() }; data From af080bf04be2a82273c646d807d8411518089199 Mon Sep 17 00:00:00 2001 From: joboet Date: Tue, 28 Mar 2023 13:55:24 +0200 Subject: [PATCH 282/346] fix typo and adjust comment Co-authored-by: Ralf Jung --- library/core/src/cell/lazy.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/cell/lazy.rs b/library/core/src/cell/lazy.rs index aff3388529a..44adcfa1a94 100644 --- a/library/core/src/cell/lazy.rs +++ b/library/core/src/cell/lazy.rs @@ -86,8 +86,8 @@ impl T> LazyCell { // SAFETY: // This invalidates any mutable references to the data. The resulting // reference lives either until the end of the borrow of `this` (in the - // initialized case) or is invalidates in `really_init` (in the - // uninitialized case). + // initialized case) or is invalidated in `really_init` (in the + // uninitialized case; `really_init` will create and return a fresh reference). let state = unsafe { &*this.state.get() }; match state { State::Init(data) => data, From 9b5115f92b84ce95aed3e8f6faa3f546f6cf4bdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20K=C3=A5rlin?= Date: Tue, 28 Feb 2023 19:13:21 +0100 Subject: [PATCH 283/346] rustdoc: run more HIR validation to mirror rustc --- src/librustdoc/core.rs | 3 ++ .../rustdoc-ui/const_arg_in_type_position.rs | 6 ++++ .../const_arg_in_type_position.stderr | 9 +++++ tests/rustdoc-ui/invalid-toplevel-const.rs | 2 ++ .../rustdoc-ui/invalid-toplevel-const.stderr | 9 +++++ tests/rustdoc-ui/invalid_associated_const.rs | 10 ++++++ .../invalid_associated_const.stderr | 9 +++++ .../invalid_const_in_lifetime_position.rs | 6 ++++ .../invalid_const_in_lifetime_position.stderr | 33 +++++++++++++++++++ .../invalid_const_in_type_position.rs | 4 +++ .../invalid_const_in_type_position.stderr | 9 +++++ .../invalid_infered_static_and_const.rs | 2 ++ .../invalid_infered_static_and_const.stderr | 15 +++++++++ tests/rustdoc-ui/mismatched_arg_count.rs | 12 +++++++ tests/rustdoc-ui/mismatched_arg_count.stderr | 17 ++++++++++ 15 files changed, 146 insertions(+) create mode 100644 tests/rustdoc-ui/const_arg_in_type_position.rs create mode 100644 tests/rustdoc-ui/const_arg_in_type_position.stderr create mode 100644 tests/rustdoc-ui/invalid-toplevel-const.rs create mode 100644 tests/rustdoc-ui/invalid-toplevel-const.stderr create mode 100644 tests/rustdoc-ui/invalid_associated_const.rs create mode 100644 tests/rustdoc-ui/invalid_associated_const.stderr create mode 100644 tests/rustdoc-ui/invalid_const_in_lifetime_position.rs create mode 100644 tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr create mode 100644 tests/rustdoc-ui/invalid_const_in_type_position.rs create mode 100644 tests/rustdoc-ui/invalid_const_in_type_position.stderr create mode 100644 tests/rustdoc-ui/invalid_infered_static_and_const.rs create mode 100644 tests/rustdoc-ui/invalid_infered_static_and_const.stderr create mode 100644 tests/rustdoc-ui/mismatched_arg_count.rs create mode 100644 tests/rustdoc-ui/mismatched_arg_count.stderr diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 28458f32903..b392ba05836 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -303,6 +303,9 @@ pub(crate) fn run_global_ctxt( // HACK(jynelson) this calls an _extremely_ limited subset of `typeck` // and might break if queries change their assumptions in the future. + tcx.sess.time("type_collecting", || { + tcx.hir().for_each_module(|module| tcx.ensure().collect_mod_item_types(module)) + }); // NOTE: This is copy/pasted from typeck/lib.rs and should be kept in sync with those changes. tcx.sess.time("item_types_checking", || { diff --git a/tests/rustdoc-ui/const_arg_in_type_position.rs b/tests/rustdoc-ui/const_arg_in_type_position.rs new file mode 100644 index 00000000000..4969e8d195f --- /dev/null +++ b/tests/rustdoc-ui/const_arg_in_type_position.rs @@ -0,0 +1,6 @@ +type Array = [T; N]; + +fn foo() -> Array { + //~^ ERROR constant provided when a type was expected + unimplemented!() +} diff --git a/tests/rustdoc-ui/const_arg_in_type_position.stderr b/tests/rustdoc-ui/const_arg_in_type_position.stderr new file mode 100644 index 00000000000..ea05920dea7 --- /dev/null +++ b/tests/rustdoc-ui/const_arg_in_type_position.stderr @@ -0,0 +1,9 @@ +error[E0747]: constant provided when a type was expected + --> $DIR/const_arg_in_type_position.rs:3:35 + | +LL | fn foo() -> Array { + | ^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0747`. diff --git a/tests/rustdoc-ui/invalid-toplevel-const.rs b/tests/rustdoc-ui/invalid-toplevel-const.rs new file mode 100644 index 00000000000..227be0cfc9a --- /dev/null +++ b/tests/rustdoc-ui/invalid-toplevel-const.rs @@ -0,0 +1,2 @@ +static CONST: Option = None; +//~^ ERROR: the placeholder `_` is not allowed within types on item signatures for static items [E0121] diff --git a/tests/rustdoc-ui/invalid-toplevel-const.stderr b/tests/rustdoc-ui/invalid-toplevel-const.stderr new file mode 100644 index 00000000000..953e332a32c --- /dev/null +++ b/tests/rustdoc-ui/invalid-toplevel-const.stderr @@ -0,0 +1,9 @@ +error[E0121]: the placeholder `_` is not allowed within types on item signatures for static items + --> $DIR/invalid-toplevel-const.rs:2:31 + | +LL | static CONST: Option = None; + | ^ not allowed in type signatures + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0121`. diff --git a/tests/rustdoc-ui/invalid_associated_const.rs b/tests/rustdoc-ui/invalid_associated_const.rs new file mode 100644 index 00000000000..6ab8c36f740 --- /dev/null +++ b/tests/rustdoc-ui/invalid_associated_const.rs @@ -0,0 +1,10 @@ +#![feature(associated_const_equality)] + +trait T { + type A: S = 34>; + //~^ ERROR associated type bindings are not allowed here +} + +trait S { + const C: i32; +} diff --git a/tests/rustdoc-ui/invalid_associated_const.stderr b/tests/rustdoc-ui/invalid_associated_const.stderr new file mode 100644 index 00000000000..1a8863fb18f --- /dev/null +++ b/tests/rustdoc-ui/invalid_associated_const.stderr @@ -0,0 +1,9 @@ +error[E0229]: associated type bindings are not allowed here + --> $DIR/invalid_associated_const.rs:4:17 + | +LL | type A: S = 34>; + | ^^^^^^^^ associated type not allowed here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0229`. diff --git a/tests/rustdoc-ui/invalid_const_in_lifetime_position.rs b/tests/rustdoc-ui/invalid_const_in_lifetime_position.rs new file mode 100644 index 00000000000..c3f4fd63bac --- /dev/null +++ b/tests/rustdoc-ui/invalid_const_in_lifetime_position.rs @@ -0,0 +1,6 @@ +trait X { + type Y<'a>; +} +fn f<'a>(arg : Box = &'a ()>>) {} +//~^ ERROR associated type takes 1 lifetime argument but 0 lifetime arguments +//~| ERROR associated type takes 0 generic arguments but 1 generic argument diff --git a/tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr b/tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr new file mode 100644 index 00000000000..527729a8228 --- /dev/null +++ b/tests/rustdoc-ui/invalid_const_in_lifetime_position.stderr @@ -0,0 +1,33 @@ +error[E0107]: associated type takes 1 lifetime argument but 0 lifetime arguments were supplied + --> $DIR/invalid_const_in_lifetime_position.rs:4:26 + | +LL | fn f<'a>(arg : Box = &'a ()>>) {} + | ^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/invalid_const_in_lifetime_position.rs:2:10 + | +LL | type Y<'a>; + | ^ -- +help: add missing lifetime argument + | +LL | fn f<'a>(arg : Box = &'a ()>>) {} + | +++ + +error[E0107]: associated type takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/invalid_const_in_lifetime_position.rs:4:26 + | +LL | fn f<'a>(arg : Box = &'a ()>>) {} + | ^--- help: remove these generics + | | + | expected 0 generic arguments + | +note: associated type defined here, with 0 generic parameters + --> $DIR/invalid_const_in_lifetime_position.rs:2:10 + | +LL | type Y<'a>; + | ^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/rustdoc-ui/invalid_const_in_type_position.rs b/tests/rustdoc-ui/invalid_const_in_type_position.rs new file mode 100644 index 00000000000..b8ddd80d5cb --- /dev/null +++ b/tests/rustdoc-ui/invalid_const_in_type_position.rs @@ -0,0 +1,4 @@ +use std::ops::Generator; + +fn gen() -> impl Generator<{}> {} +//~^ERROR constant provided when a type was expected diff --git a/tests/rustdoc-ui/invalid_const_in_type_position.stderr b/tests/rustdoc-ui/invalid_const_in_type_position.stderr new file mode 100644 index 00000000000..27c9a730fb4 --- /dev/null +++ b/tests/rustdoc-ui/invalid_const_in_type_position.stderr @@ -0,0 +1,9 @@ +error[E0747]: constant provided when a type was expected + --> $DIR/invalid_const_in_type_position.rs:3:28 + | +LL | fn gen() -> impl Generator<{}> {} + | ^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0747`. diff --git a/tests/rustdoc-ui/invalid_infered_static_and_const.rs b/tests/rustdoc-ui/invalid_infered_static_and_const.rs new file mode 100644 index 00000000000..3f8e68dc020 --- /dev/null +++ b/tests/rustdoc-ui/invalid_infered_static_and_const.rs @@ -0,0 +1,2 @@ +const FOO: dyn Fn() -> _ = ""; //~ ERROR E0121 +static BOO: dyn Fn() -> _ = ""; //~ ERROR E0121 diff --git a/tests/rustdoc-ui/invalid_infered_static_and_const.stderr b/tests/rustdoc-ui/invalid_infered_static_and_const.stderr new file mode 100644 index 00000000000..401020224d6 --- /dev/null +++ b/tests/rustdoc-ui/invalid_infered_static_and_const.stderr @@ -0,0 +1,15 @@ +error[E0121]: the placeholder `_` is not allowed within types on item signatures for constant items + --> $DIR/invalid_infered_static_and_const.rs:1:24 + | +LL | const FOO: dyn Fn() -> _ = ""; + | ^ not allowed in type signatures + +error[E0121]: the placeholder `_` is not allowed within types on item signatures for static items + --> $DIR/invalid_infered_static_and_const.rs:2:25 + | +LL | static BOO: dyn Fn() -> _ = ""; + | ^ not allowed in type signatures + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0121`. diff --git a/tests/rustdoc-ui/mismatched_arg_count.rs b/tests/rustdoc-ui/mismatched_arg_count.rs new file mode 100644 index 00000000000..792563fd82b --- /dev/null +++ b/tests/rustdoc-ui/mismatched_arg_count.rs @@ -0,0 +1,12 @@ +// ensures that we don't ICE when there are too many args supplied to the alias. + +trait Trait<'a> { + type Assoc; +} + +type Alias<'a, T> = >::Assoc; + +fn bar<'a, T: Trait<'a>>(_: Alias<'a, 'a, T>) {} +//~^ error: type alias takes 1 lifetime argument but 2 lifetime arguments were supplied + +fn main() {} diff --git a/tests/rustdoc-ui/mismatched_arg_count.stderr b/tests/rustdoc-ui/mismatched_arg_count.stderr new file mode 100644 index 00000000000..de58a014ee8 --- /dev/null +++ b/tests/rustdoc-ui/mismatched_arg_count.stderr @@ -0,0 +1,17 @@ +error[E0107]: type alias takes 1 lifetime argument but 2 lifetime arguments were supplied + --> $DIR/mismatched_arg_count.rs:9:29 + | +LL | fn bar<'a, T: Trait<'a>>(_: Alias<'a, 'a, T>) {} + | ^^^^^ -- help: remove this lifetime argument + | | + | expected 1 lifetime argument + | +note: type alias defined here, with 1 lifetime parameter: `'a` + --> $DIR/mismatched_arg_count.rs:7:6 + | +LL | type Alias<'a, T> = >::Assoc; + | ^^^^^ -- + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0107`. From 466fc4af84c295b9ae601d6b49d5d794e273de5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20K=C3=A5rlin?= Date: Wed, 1 Mar 2023 10:40:39 +0100 Subject: [PATCH 284/346] rustdoc: update with --bless and change expected errors --- .../rustdoc-ui/invalid-toplevel-const.stderr | 2 +- tests/rustdoc-ui/issue-105742.rs | 24 +- tests/rustdoc-ui/issue-105742.stderr | 330 +++++++++++++++++- tests/rustdoc-ui/issue-106226.stderr | 8 +- tests/rustdoc-ui/issue-79465.rs | 1 - tests/rustdoc-ui/issue-79465.stderr | 8 +- tests/rustdoc-ui/issue-96287.rs | 1 - tests/rustdoc-ui/issue-96287.stderr | 8 +- 8 files changed, 352 insertions(+), 30 deletions(-) diff --git a/tests/rustdoc-ui/invalid-toplevel-const.stderr b/tests/rustdoc-ui/invalid-toplevel-const.stderr index 953e332a32c..ae19b728bfe 100644 --- a/tests/rustdoc-ui/invalid-toplevel-const.stderr +++ b/tests/rustdoc-ui/invalid-toplevel-const.stderr @@ -1,5 +1,5 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures for static items - --> $DIR/invalid-toplevel-const.rs:2:31 + --> $DIR/invalid-toplevel-const.rs:1:31 | LL | static CONST: Option = None; | ^ not allowed in type signatures diff --git a/tests/rustdoc-ui/issue-105742.rs b/tests/rustdoc-ui/issue-105742.rs index 9f36e5315ec..6d33e47a368 100644 --- a/tests/rustdoc-ui/issue-105742.rs +++ b/tests/rustdoc-ui/issue-105742.rs @@ -1,19 +1,37 @@ // compile-flags: -Znormalize-docs - use std::ops::Index; pub fn next<'a, T>(s: &'a mut dyn SVec) { + //~^ERROR + //~|ERROR + //~|ERROR let _ = s; } pub trait SVec: Index< ::Item, + //~^ERROR + //~|ERROR + //~|ERROR + //~|ERROR Output = ::Item, + //~^ERROR + //~|ERROR + //~|ERROR + //~|ERROR Output = ::Item> as SVec>::Item, + //~^ERROR + //~|ERROR + //~|ERROR + //~|ERROR + //~|ERROR + //~|ERROR + //~|ERROR + //~|ERROR > { type Item<'a, T>; fn len(&self) -> ::Item; - //~^ ERROR - //~^^ ERROR + //~^ERROR + //~|ERROR } diff --git a/tests/rustdoc-ui/issue-105742.stderr b/tests/rustdoc-ui/issue-105742.stderr index 4d2ee972689..837e72852b4 100644 --- a/tests/rustdoc-ui/issue-105742.stderr +++ b/tests/rustdoc-ui/issue-105742.stderr @@ -1,11 +1,328 @@ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:16:38 + --> $DIR/issue-105742.rs:12:21 + | +LL | ::Item, + | ^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/issue-105742.rs:32:10 + | +LL | type Item<'a, T>; + | ^^^^ -- +help: add missing lifetime argument + | +LL | ::Item<'a>, + | ++++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/issue-105742.rs:12:21 + | +LL | ::Item, + | ^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/issue-105742.rs:32:10 + | +LL | type Item<'a, T>; + | ^^^^ - +help: add missing generic argument + | +LL | ::Item, + | +++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/issue-105742.rs:17:37 + | +LL | Output = ::Item, + | ^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/issue-105742.rs:32:10 + | +LL | type Item<'a, T>; + | ^^^^ -- +help: add missing lifetime argument + | +LL | Output = ::Item<'a>, + | ++++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/issue-105742.rs:17:37 + | +LL | Output = ::Item, + | ^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/issue-105742.rs:32:10 + | +LL | type Item<'a, T>; + | ^^^^ - +help: add missing generic argument + | +LL | Output = ::Item, + | +++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/issue-105742.rs:22:30 + | +LL | Output = ::Item> as SVec>::Item, + | ^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/issue-105742.rs:32:10 + | +LL | type Item<'a, T>; + | ^^^^ -- +help: add missing lifetime argument + | +LL | Output = ::Item<'a>> as SVec>::Item, + | ++++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/issue-105742.rs:22:30 + | +LL | Output = ::Item> as SVec>::Item, + | ^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/issue-105742.rs:32:10 + | +LL | type Item<'a, T>; + | ^^^^ - +help: add missing generic argument + | +LL | Output = ::Item> as SVec>::Item, + | +++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/issue-105742.rs:22:46 + | +LL | Output = ::Item> as SVec>::Item, + | ^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/issue-105742.rs:32:10 + | +LL | type Item<'a, T>; + | ^^^^ -- +help: add missing lifetime argument + | +LL | Output = ::Item> as SVec>::Item<'a>, + | ++++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/issue-105742.rs:22:46 + | +LL | Output = ::Item> as SVec>::Item, + | ^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/issue-105742.rs:32:10 + | +LL | type Item<'a, T>; + | ^^^^ - +help: add missing generic argument + | +LL | Output = ::Item> as SVec>::Item, + | +++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/issue-105742.rs:4:40 + | +LL | pub fn next<'a, T>(s: &'a mut dyn SVec) { + | ^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/issue-105742.rs:32:10 + | +LL | type Item<'a, T>; + | ^^^^ -- +help: add missing lifetime argument + | +LL | pub fn next<'a, T>(s: &'a mut dyn SVec = T, Output = T>) { + | ++++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/issue-105742.rs:4:40 + | +LL | pub fn next<'a, T>(s: &'a mut dyn SVec) { + | ^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/issue-105742.rs:32:10 + | +LL | type Item<'a, T>; + | ^^^^ - +help: add missing generic argument + | +LL | pub fn next<'a, T>(s: &'a mut dyn SVec = T, Output = T>) { + | +++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/issue-105742.rs:12:21 + | +LL | ::Item, + | ^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/issue-105742.rs:32:10 + | +LL | type Item<'a, T>; + | ^^^^ -- +help: add missing lifetime argument + | +LL | ::Item<'a>, + | ++++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/issue-105742.rs:12:21 + | +LL | ::Item, + | ^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/issue-105742.rs:32:10 + | +LL | type Item<'a, T>; + | ^^^^ - +help: add missing generic argument + | +LL | ::Item, + | +++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/issue-105742.rs:17:37 + | +LL | Output = ::Item, + | ^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/issue-105742.rs:32:10 + | +LL | type Item<'a, T>; + | ^^^^ -- +help: add missing lifetime argument + | +LL | Output = ::Item<'a>, + | ++++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/issue-105742.rs:17:37 + | +LL | Output = ::Item, + | ^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/issue-105742.rs:32:10 + | +LL | type Item<'a, T>; + | ^^^^ - +help: add missing generic argument + | +LL | Output = ::Item, + | +++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/issue-105742.rs:22:30 + | +LL | Output = ::Item> as SVec>::Item, + | ^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/issue-105742.rs:32:10 + | +LL | type Item<'a, T>; + | ^^^^ -- +help: add missing lifetime argument + | +LL | Output = ::Item<'a>> as SVec>::Item, + | ++++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/issue-105742.rs:22:30 + | +LL | Output = ::Item> as SVec>::Item, + | ^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/issue-105742.rs:32:10 + | +LL | type Item<'a, T>; + | ^^^^ - +help: add missing generic argument + | +LL | Output = ::Item> as SVec>::Item, + | +++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/issue-105742.rs:22:46 + | +LL | Output = ::Item> as SVec>::Item, + | ^^^^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/issue-105742.rs:32:10 + | +LL | type Item<'a, T>; + | ^^^^ -- +help: add missing lifetime argument + | +LL | Output = ::Item> as SVec>::Item<'a>, + | ++++ + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/issue-105742.rs:22:46 + | +LL | Output = ::Item> as SVec>::Item, + | ^^^^ expected 1 generic argument + | +note: associated type defined here, with 1 generic parameter: `T` + --> $DIR/issue-105742.rs:32:10 + | +LL | type Item<'a, T>; + | ^^^^ - +help: add missing generic argument + | +LL | Output = ::Item> as SVec>::Item, + | +++ + +error[E0038]: the trait `SVec` cannot be made into an object + --> $DIR/issue-105742.rs:4:31 + | +LL | pub fn next<'a, T>(s: &'a mut dyn SVec) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SVec` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/issue-105742.rs:11:17 + | +LL | pub trait SVec: Index< + | ____________----__^ + | | | + | | this trait cannot be made into an object... +LL | | ::Item, +LL | | +LL | | +... | +LL | |/ Output = ::Item, +LL | || +LL | || +LL | || +LL | || +LL | || Output = ::Item> as SVec>::Item, + | ||_________________________________________________^ ...because it uses `Self` as a type parameter +... | +LL | | +LL | | > { + | |__^ ...because it uses `Self` as a type parameter + +error[E0107]: missing generics for associated type `SVec::Item` + --> $DIR/issue-105742.rs:34:38 | LL | fn len(&self) -> ::Item; | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:14:10 + --> $DIR/issue-105742.rs:32:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -15,13 +332,13 @@ LL | fn len(&self) -> ::Item<'_>; | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:16:38 + --> $DIR/issue-105742.rs:34:38 | LL | fn len(&self) -> ::Item; | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:14:10 + --> $DIR/issue-105742.rs:32:10 | LL | type Item<'a, T>; | ^^^^ - @@ -30,6 +347,7 @@ help: add missing generic argument LL | fn len(&self) -> ::Item; | +++ -error: aborting due to 2 previous errors +error: aborting due to 21 previous errors -For more information about this error, try `rustc --explain E0107`. +Some errors have detailed explanations: E0038, E0107. +For more information about an error, try `rustc --explain E0038`. diff --git a/tests/rustdoc-ui/issue-106226.stderr b/tests/rustdoc-ui/issue-106226.stderr index 2beffbc125b..1c973dab61d 100644 --- a/tests/rustdoc-ui/issue-106226.stderr +++ b/tests/rustdoc-ui/issue-106226.stderr @@ -1,9 +1,9 @@ -error[E0308]: mismatched types - --> $DIR/issue-106226.rs:2:14 +error[E0121]: the placeholder `_` is not allowed within types on item signatures for type aliases + --> $DIR/issue-106226.rs:2:11 | LL | type F = [_; ()]; - | ^^ expected `usize`, found `()` + | ^ not allowed in type signatures error: aborting due to previous error -For more information about this error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0121`. diff --git a/tests/rustdoc-ui/issue-79465.rs b/tests/rustdoc-ui/issue-79465.rs index f1a77982fb5..e50f3995b83 100644 --- a/tests/rustdoc-ui/issue-79465.rs +++ b/tests/rustdoc-ui/issue-79465.rs @@ -1,3 +1,2 @@ pub fn f1(x: T::A) {} //~^ ERROR -//~^^ ERROR diff --git a/tests/rustdoc-ui/issue-79465.stderr b/tests/rustdoc-ui/issue-79465.stderr index 489cc14420a..d187a2e664a 100644 --- a/tests/rustdoc-ui/issue-79465.stderr +++ b/tests/rustdoc-ui/issue-79465.stderr @@ -4,12 +4,6 @@ error[E0220]: associated type `A` not found for `T` LL | pub fn f1(x: T::A) {} | ^ associated type `A` not found -error[E0220]: associated type `A` not found for `T` - --> $DIR/issue-79465.rs:1:20 - | -LL | pub fn f1(x: T::A) {} - | ^ associated type `A` not found - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0220`. diff --git a/tests/rustdoc-ui/issue-96287.rs b/tests/rustdoc-ui/issue-96287.rs index 8d8b4456e63..08cc7ef4c90 100644 --- a/tests/rustdoc-ui/issue-96287.rs +++ b/tests/rustdoc-ui/issue-96287.rs @@ -6,7 +6,6 @@ pub trait TraitWithAssoc { pub type Foo = impl Trait; //~^ ERROR -//~^^ ERROR pub trait Trait {} diff --git a/tests/rustdoc-ui/issue-96287.stderr b/tests/rustdoc-ui/issue-96287.stderr index 0236b9fe647..7722eb96028 100644 --- a/tests/rustdoc-ui/issue-96287.stderr +++ b/tests/rustdoc-ui/issue-96287.stderr @@ -4,12 +4,6 @@ error[E0220]: associated type `Assoc` not found for `V` LL | pub type Foo = impl Trait; | ^^^^^ there is a similarly named associated type `Assoc` in the trait `TraitWithAssoc` -error[E0220]: associated type `Assoc` not found for `V` - --> $DIR/issue-96287.rs:7:33 - | -LL | pub type Foo = impl Trait; - | ^^^^^ there is a similarly named associated type `Assoc` in the trait `TraitWithAssoc` - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0220`. From 2ee19c9c4c17d20d007a60c99166a073510addfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20K=C3=A5rlin?= Date: Wed, 1 Mar 2023 10:41:59 +0100 Subject: [PATCH 285/346] rustdoc: remove redundant test --- tests/rustdoc-ui/invalid_const_in_type_position.rs | 4 ---- tests/rustdoc-ui/invalid_const_in_type_position.stderr | 9 --------- 2 files changed, 13 deletions(-) delete mode 100644 tests/rustdoc-ui/invalid_const_in_type_position.rs delete mode 100644 tests/rustdoc-ui/invalid_const_in_type_position.stderr diff --git a/tests/rustdoc-ui/invalid_const_in_type_position.rs b/tests/rustdoc-ui/invalid_const_in_type_position.rs deleted file mode 100644 index b8ddd80d5cb..00000000000 --- a/tests/rustdoc-ui/invalid_const_in_type_position.rs +++ /dev/null @@ -1,4 +0,0 @@ -use std::ops::Generator; - -fn gen() -> impl Generator<{}> {} -//~^ERROR constant provided when a type was expected diff --git a/tests/rustdoc-ui/invalid_const_in_type_position.stderr b/tests/rustdoc-ui/invalid_const_in_type_position.stderr deleted file mode 100644 index 27c9a730fb4..00000000000 --- a/tests/rustdoc-ui/invalid_const_in_type_position.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0747]: constant provided when a type was expected - --> $DIR/invalid_const_in_type_position.rs:3:28 - | -LL | fn gen() -> impl Generator<{}> {} - | ^^ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0747`. From d1b6aa6834744ec653a8de9f2f4ef25612e520e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20K=C3=A5rlin?= Date: Wed, 1 Mar 2023 10:43:41 +0100 Subject: [PATCH 286/346] rustdoc: remove excess from rustdoc test --- tests/rustdoc-ui/mismatched_arg_count.rs | 4 ---- tests/rustdoc-ui/mismatched_arg_count.stderr | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/tests/rustdoc-ui/mismatched_arg_count.rs b/tests/rustdoc-ui/mismatched_arg_count.rs index 792563fd82b..7841442987b 100644 --- a/tests/rustdoc-ui/mismatched_arg_count.rs +++ b/tests/rustdoc-ui/mismatched_arg_count.rs @@ -1,5 +1,3 @@ -// ensures that we don't ICE when there are too many args supplied to the alias. - trait Trait<'a> { type Assoc; } @@ -8,5 +6,3 @@ type Alias<'a, T> = >::Assoc; fn bar<'a, T: Trait<'a>>(_: Alias<'a, 'a, T>) {} //~^ error: type alias takes 1 lifetime argument but 2 lifetime arguments were supplied - -fn main() {} diff --git a/tests/rustdoc-ui/mismatched_arg_count.stderr b/tests/rustdoc-ui/mismatched_arg_count.stderr index de58a014ee8..7e88ce954ac 100644 --- a/tests/rustdoc-ui/mismatched_arg_count.stderr +++ b/tests/rustdoc-ui/mismatched_arg_count.stderr @@ -1,5 +1,5 @@ error[E0107]: type alias takes 1 lifetime argument but 2 lifetime arguments were supplied - --> $DIR/mismatched_arg_count.rs:9:29 + --> $DIR/mismatched_arg_count.rs:7:29 | LL | fn bar<'a, T: Trait<'a>>(_: Alias<'a, 'a, T>) {} | ^^^^^ -- help: remove this lifetime argument @@ -7,7 +7,7 @@ LL | fn bar<'a, T: Trait<'a>>(_: Alias<'a, 'a, T>) {} | expected 1 lifetime argument | note: type alias defined here, with 1 lifetime parameter: `'a` - --> $DIR/mismatched_arg_count.rs:7:6 + --> $DIR/mismatched_arg_count.rs:5:6 | LL | type Alias<'a, T> = >::Assoc; | ^^^^^ -- From 4d571a9ccf239ae4d5e354786ede05fda2745f73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20K=C3=A5rlin?= Date: Wed, 1 Mar 2023 10:45:08 +0100 Subject: [PATCH 287/346] rustdoc: remove other redundant item --- tests/rustdoc-ui/invalid-toplevel-const.rs | 2 -- tests/rustdoc-ui/invalid-toplevel-const.stderr | 9 --------- 2 files changed, 11 deletions(-) delete mode 100644 tests/rustdoc-ui/invalid-toplevel-const.rs delete mode 100644 tests/rustdoc-ui/invalid-toplevel-const.stderr diff --git a/tests/rustdoc-ui/invalid-toplevel-const.rs b/tests/rustdoc-ui/invalid-toplevel-const.rs deleted file mode 100644 index 227be0cfc9a..00000000000 --- a/tests/rustdoc-ui/invalid-toplevel-const.rs +++ /dev/null @@ -1,2 +0,0 @@ -static CONST: Option = None; -//~^ ERROR: the placeholder `_` is not allowed within types on item signatures for static items [E0121] diff --git a/tests/rustdoc-ui/invalid-toplevel-const.stderr b/tests/rustdoc-ui/invalid-toplevel-const.stderr deleted file mode 100644 index ae19b728bfe..00000000000 --- a/tests/rustdoc-ui/invalid-toplevel-const.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0121]: the placeholder `_` is not allowed within types on item signatures for static items - --> $DIR/invalid-toplevel-const.rs:1:31 - | -LL | static CONST: Option = None; - | ^ not allowed in type signatures - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0121`. From df556a31774781ef645e286ee3ccaa816622f95a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20K=C3=A5rlin?= Date: Mon, 20 Mar 2023 14:14:06 +0100 Subject: [PATCH 288/346] rustdoc: add error messages to the test --- tests/rustdoc-ui/issue-105742.rs | 55 +++++++++++-------- tests/rustdoc-ui/issue-105742.stderr | 79 ++++++++++++++-------------- 2 files changed, 74 insertions(+), 60 deletions(-) diff --git a/tests/rustdoc-ui/issue-105742.rs b/tests/rustdoc-ui/issue-105742.rs index 6d33e47a368..dd79f0fac82 100644 --- a/tests/rustdoc-ui/issue-105742.rs +++ b/tests/rustdoc-ui/issue-105742.rs @@ -2,36 +2,49 @@ use std::ops::Index; pub fn next<'a, T>(s: &'a mut dyn SVec) { - //~^ERROR - //~|ERROR - //~|ERROR + //~^ expected 1 lifetime argument + //~| expected 1 generic argument + //~| the trait `SVec` cannot be made into an object + //~| `SVec` cannot be made into an object + //~| missing generics for associated type `SVec::Item` + //~| missing generics for associated type `SVec::Item` let _ = s; } pub trait SVec: Index< ::Item, - //~^ERROR - //~|ERROR - //~|ERROR - //~|ERROR + //~^ expected 1 lifetime argument + //~| expected 1 generic argument + //~| missing generics for associated type `SVec::Item` + //~| missing generics for associated type `SVec::Item` + //~| missing generics for associated type `SVec::Item` + //~| missing generics for associated type `SVec::Item` Output = ::Item, - //~^ERROR - //~|ERROR - //~|ERROR - //~|ERROR + //~^ expected 1 lifetime argument + //~| expected 1 generic argument + //~| missing generics for associated type `SVec::Item` + //~| missing generics for associated type `SVec::Item` + //~| missing generics for associated type `SVec::Item` + //~| missing generics for associated type `SVec::Item` Output = ::Item> as SVec>::Item, - //~^ERROR - //~|ERROR - //~|ERROR - //~|ERROR - //~|ERROR - //~|ERROR - //~|ERROR - //~|ERROR + //~^ expected 1 lifetime argument + //~| expected 1 generic argument + //~| expected 1 lifetime argument + //~| missing generics for associated type `SVec::Item` + //~| missing generics for associated type `SVec::Item` + //~| missing generics for associated type `SVec::Item` + //~| missing generics for associated type `SVec::Item` + //~| expected 1 generic argument + //~| missing generics for associated type `SVec::Item` + //~| missing generics for associated type `SVec::Item` + //~| missing generics for associated type `SVec::Item` + //~| missing generics for associated type `SVec::Item` > { type Item<'a, T>; fn len(&self) -> ::Item; - //~^ERROR - //~|ERROR + //~^ expected 1 lifetime argument + //~| missing generics for associated type `SVec::Item` + //~| expected 1 generic argument + //~| missing generics for associated type `SVec::Item` } diff --git a/tests/rustdoc-ui/issue-105742.stderr b/tests/rustdoc-ui/issue-105742.stderr index 837e72852b4..cd53762ef9b 100644 --- a/tests/rustdoc-ui/issue-105742.stderr +++ b/tests/rustdoc-ui/issue-105742.stderr @@ -1,11 +1,11 @@ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:12:21 + --> $DIR/issue-105742.rs:15:21 | LL | ::Item, | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:32:10 + --> $DIR/issue-105742.rs:43:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -15,13 +15,13 @@ LL | ::Item<'a>, | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:12:21 + --> $DIR/issue-105742.rs:15:21 | LL | ::Item, | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:32:10 + --> $DIR/issue-105742.rs:43:10 | LL | type Item<'a, T>; | ^^^^ - @@ -31,13 +31,13 @@ LL | ::Item, | +++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:17:37 + --> $DIR/issue-105742.rs:22:37 | LL | Output = ::Item, | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:32:10 + --> $DIR/issue-105742.rs:43:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -47,13 +47,13 @@ LL | Output = ::Item<'a>, | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:17:37 + --> $DIR/issue-105742.rs:22:37 | LL | Output = ::Item, | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:32:10 + --> $DIR/issue-105742.rs:43:10 | LL | type Item<'a, T>; | ^^^^ - @@ -63,13 +63,13 @@ LL | Output = ::Item, | +++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:22:30 + --> $DIR/issue-105742.rs:29:30 | LL | Output = ::Item> as SVec>::Item, | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:32:10 + --> $DIR/issue-105742.rs:43:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -79,13 +79,13 @@ LL | Output = ::Item<'a>> as SVec>::Item, | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:22:30 + --> $DIR/issue-105742.rs:29:30 | LL | Output = ::Item> as SVec>::Item, | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:32:10 + --> $DIR/issue-105742.rs:43:10 | LL | type Item<'a, T>; | ^^^^ - @@ -95,13 +95,13 @@ LL | Output = ::Item> as SVec>::Item, | +++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:22:46 + --> $DIR/issue-105742.rs:29:46 | LL | Output = ::Item> as SVec>::Item, | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:32:10 + --> $DIR/issue-105742.rs:43:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -111,13 +111,13 @@ LL | Output = ::Item> as SVec>::Item<'a>, | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:22:46 + --> $DIR/issue-105742.rs:29:46 | LL | Output = ::Item> as SVec>::Item, | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:32:10 + --> $DIR/issue-105742.rs:43:10 | LL | type Item<'a, T>; | ^^^^ - @@ -133,7 +133,7 @@ LL | pub fn next<'a, T>(s: &'a mut dyn SVec) { | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:32:10 + --> $DIR/issue-105742.rs:43:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -149,7 +149,7 @@ LL | pub fn next<'a, T>(s: &'a mut dyn SVec) { | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:32:10 + --> $DIR/issue-105742.rs:43:10 | LL | type Item<'a, T>; | ^^^^ - @@ -159,13 +159,13 @@ LL | pub fn next<'a, T>(s: &'a mut dyn SVec = T, Output = T>) { | +++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:12:21 + --> $DIR/issue-105742.rs:15:21 | LL | ::Item, | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:32:10 + --> $DIR/issue-105742.rs:43:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -175,13 +175,13 @@ LL | ::Item<'a>, | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:12:21 + --> $DIR/issue-105742.rs:15:21 | LL | ::Item, | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:32:10 + --> $DIR/issue-105742.rs:43:10 | LL | type Item<'a, T>; | ^^^^ - @@ -191,13 +191,13 @@ LL | ::Item, | +++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:17:37 + --> $DIR/issue-105742.rs:22:37 | LL | Output = ::Item, | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:32:10 + --> $DIR/issue-105742.rs:43:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -207,13 +207,13 @@ LL | Output = ::Item<'a>, | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:17:37 + --> $DIR/issue-105742.rs:22:37 | LL | Output = ::Item, | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:32:10 + --> $DIR/issue-105742.rs:43:10 | LL | type Item<'a, T>; | ^^^^ - @@ -223,13 +223,13 @@ LL | Output = ::Item, | +++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:22:30 + --> $DIR/issue-105742.rs:29:30 | LL | Output = ::Item> as SVec>::Item, | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:32:10 + --> $DIR/issue-105742.rs:43:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -239,13 +239,13 @@ LL | Output = ::Item<'a>> as SVec>::Item, | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:22:30 + --> $DIR/issue-105742.rs:29:30 | LL | Output = ::Item> as SVec>::Item, | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:32:10 + --> $DIR/issue-105742.rs:43:10 | LL | type Item<'a, T>; | ^^^^ - @@ -255,13 +255,13 @@ LL | Output = ::Item> as SVec>::Item, | +++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:22:46 + --> $DIR/issue-105742.rs:29:46 | LL | Output = ::Item> as SVec>::Item, | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:32:10 + --> $DIR/issue-105742.rs:43:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -271,13 +271,13 @@ LL | Output = ::Item> as SVec>::Item<'a>, | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:22:46 + --> $DIR/issue-105742.rs:29:46 | LL | Output = ::Item> as SVec>::Item, | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:32:10 + --> $DIR/issue-105742.rs:43:10 | LL | type Item<'a, T>; | ^^^^ - @@ -293,7 +293,7 @@ LL | pub fn next<'a, T>(s: &'a mut dyn SVec) { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `SVec` cannot be made into an object | note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/issue-105742.rs:11:17 + --> $DIR/issue-105742.rs:14:17 | LL | pub trait SVec: Index< | ____________----__^ @@ -307,6 +307,7 @@ LL | |/ Output = ::Item, LL | || LL | || LL | || +... || LL | || LL | || Output = ::Item> as SVec>::Item, | ||_________________________________________________^ ...because it uses `Self` as a type parameter @@ -316,13 +317,13 @@ LL | | > { | |__^ ...because it uses `Self` as a type parameter error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:34:38 + --> $DIR/issue-105742.rs:45:38 | LL | fn len(&self) -> ::Item; | ^^^^ expected 1 lifetime argument | note: associated type defined here, with 1 lifetime parameter: `'a` - --> $DIR/issue-105742.rs:32:10 + --> $DIR/issue-105742.rs:43:10 | LL | type Item<'a, T>; | ^^^^ -- @@ -332,13 +333,13 @@ LL | fn len(&self) -> ::Item<'_>; | ++++ error[E0107]: missing generics for associated type `SVec::Item` - --> $DIR/issue-105742.rs:34:38 + --> $DIR/issue-105742.rs:45:38 | LL | fn len(&self) -> ::Item; | ^^^^ expected 1 generic argument | note: associated type defined here, with 1 generic parameter: `T` - --> $DIR/issue-105742.rs:32:10 + --> $DIR/issue-105742.rs:43:10 | LL | type Item<'a, T>; | ^^^^ - From 26e1ce739400df9e989fa64c0138aaf13ced8c60 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 30 Mar 2023 07:58:50 -0500 Subject: [PATCH 289/346] move `tools.mk` to run-make apparently I missed some tests in the last commit. Rather than having dozens of tests use the long version, use the short version in `run-make` and the long version in `run-make-fulldeps` (which is now only three tests) --- tests/run-make-fulldeps/issue-19371/Makefile | 2 +- tests/run-make-fulldeps/obtain-borrowck/Makefile | 2 +- tests/run-make-fulldeps/pretty-expanded/Makefile | 2 +- tests/run-make/const_fn_mir/Makefile | 2 +- tests/run-make/coverage/coverage_tools.mk | 2 +- tests/run-make/crate-hash-rustc-version/Makefile | 2 +- tests/run-make/dep-graph/Makefile | 2 +- tests/run-make/doctests-keep-binaries/Makefile | 2 +- tests/run-make/dump-mono-stats/Makefile | 2 +- tests/run-make/emit-named-files/Makefile | 2 +- tests/run-make/emit-path-unhashed/Makefile | 2 +- tests/run-make/emit-shared-files/Makefile | 2 +- tests/run-make/env-dep-info/Makefile | 2 +- tests/run-make/export-executable-symbols/Makefile | 2 +- tests/run-make/fmt-write-bloat/Makefile | 2 +- tests/run-make/incr-foreign-head-span/Makefile | 2 +- tests/run-make/incr-prev-body-beyond-eof/Makefile | 2 +- tests/run-make/incremental-session-fail/Makefile | 2 +- tests/run-make/invalid-so/Makefile | 2 +- tests/run-make/issue-10971-temps-dir/Makefile | 2 +- tests/run-make/issue-36710/Makefile | 2 +- tests/run-make/issue-47384/Makefile | 2 +- tests/run-make/issue-71519/Makefile | 2 +- tests/run-make/issue-83045/Makefile | 2 +- tests/run-make/issue-83112-incr-test-moved-file/Makefile | 2 +- tests/run-make/issue-84395-lto-embed-bitcode/Makefile | 2 +- tests/run-make/issue-85019-moved-src-dir/Makefile | 2 +- tests/run-make/issue-85401-static-mir/Makefile | 2 +- tests/run-make/issue-85441/Makefile | 2 +- tests/run-make/issue-88756-default-output/Makefile | 2 +- tests/run-make/issue-96498/Makefile | 2 +- tests/run-make/issue-97463-abi-param-passing/Makefile | 2 +- tests/run-make/issue64319/Makefile | 2 +- tests/run-make/jobserver-error/Makefile | 2 +- tests/run-make/libtest-thread-limit/Makefile | 2 +- tests/run-make/llvm-outputs/Makefile | 2 +- tests/run-make/macos-deployment-target/Makefile | 2 +- tests/run-make/macos-fat-archive/Makefile | 2 +- tests/run-make/native-link-modifier-bundle/Makefile | 2 +- tests/run-make/native-link-modifier-verbatim-linker/Makefile | 2 +- tests/run-make/native-link-modifier-verbatim-rustc/Makefile | 2 +- tests/run-make/native-link-modifier-whole-archive/Makefile | 2 +- tests/run-make/no-input-file/Makefile | 2 +- tests/run-make/overwrite-input/Makefile | 2 +- tests/run-make/panic-impl-transitive/Makefile | 2 +- tests/run-make/pass-linker-flags-from-dep/Makefile | 2 +- tests/run-make/pass-linker-flags/Makefile | 2 +- tests/run-make/print-calling-conventions/Makefile | 2 +- tests/run-make/raw-dylib-alt-calling-convention/Makefile | 2 +- tests/run-make/raw-dylib-c/Makefile | 2 +- tests/run-make/raw-dylib-cross-compilation/Makefile | 2 +- tests/run-make/raw-dylib-import-name-type/Makefile | 2 +- tests/run-make/raw-dylib-inline-cross-dylib/Makefile | 2 +- tests/run-make/raw-dylib-link-ordinal/Makefile | 2 +- tests/run-make/raw-dylib-stdcall-ordinal/Makefile | 2 +- tests/run-make/remap-path-prefix-dwarf/Makefile | 2 +- tests/run-make/repr128-dwarf/Makefile | 2 +- tests/run-make/rlib-format-packed-bundled-libs-2/Makefile | 2 +- tests/run-make/rlib-format-packed-bundled-libs-3/Makefile | 2 +- tests/run-make/rlib-format-packed-bundled-libs/Makefile | 2 +- tests/run-make/rustc-macro-dep-files/Makefile | 2 +- tests/run-make/rustdoc-scrape-examples-multiple/scrape.mk | 2 +- tests/run-make/rustdoc-verify-output-files/Makefile | 2 +- tests/run-make/rustdoc-with-out-dir-option/Makefile | 2 +- tests/run-make/rustdoc-with-output-option/Makefile | 2 +- tests/run-make/rustdoc-with-short-out-dir-option/Makefile | 2 +- tests/run-make/share-generics-dylib/Makefile | 2 +- tests/run-make/static-pie/Makefile | 2 +- tests/run-make/test-benches/Makefile | 2 +- tests/run-make/thumb-none-cortex-m/Makefile | 2 +- tests/run-make/thumb-none-qemu/Makefile | 2 +- tests/{run-make-fulldeps => run-make}/tools.mk | 0 tests/run-make/track-path-dep-info/Makefile | 2 +- tests/run-make/track-pgo-dep-info/Makefile | 2 +- tests/run-make/translation/Makefile | 2 +- tests/run-make/unstable-flag-required/Makefile | 2 +- tests/run-make/valid-print-requests/Makefile | 2 +- tests/run-make/wasm-abi/Makefile | 2 +- tests/run-make/wasm-custom-section/Makefile | 2 +- tests/run-make/wasm-custom-sections-opt/Makefile | 2 +- tests/run-make/wasm-export-all-symbols/Makefile | 2 +- tests/run-make/wasm-import-module/Makefile | 2 +- tests/run-make/wasm-panic-small/Makefile | 2 +- tests/run-make/wasm-spurious-import/Makefile | 2 +- tests/run-make/wasm-stringify-ints-small/Makefile | 2 +- tests/run-make/wasm-symbols-different-module/Makefile | 2 +- tests/run-make/wasm-symbols-not-exported/Makefile | 2 +- tests/run-make/wasm-symbols-not-imported/Makefile | 2 +- tests/run-make/x86_64-fortanix-unknown-sgx-lvi/Makefile | 2 +- 89 files changed, 88 insertions(+), 88 deletions(-) rename tests/{run-make-fulldeps => run-make}/tools.mk (100%) diff --git a/tests/run-make-fulldeps/issue-19371/Makefile b/tests/run-make-fulldeps/issue-19371/Makefile index 994e50801c8..edec68f0862 100644 --- a/tests/run-make-fulldeps/issue-19371/Makefile +++ b/tests/run-make-fulldeps/issue-19371/Makefile @@ -1,4 +1,4 @@ -include ../tools.mk +include ../../run-make/tools.mk # This test ensures that rustc compile_input can be called twice in one task # without causing a panic. diff --git a/tests/run-make-fulldeps/obtain-borrowck/Makefile b/tests/run-make-fulldeps/obtain-borrowck/Makefile index 212d0f67d00..233f5c9eaf4 100644 --- a/tests/run-make-fulldeps/obtain-borrowck/Makefile +++ b/tests/run-make-fulldeps/obtain-borrowck/Makefile @@ -1,4 +1,4 @@ -include ../tools.mk +include ../../run-make/tools.mk # This example shows how to implement a rustc driver that retrieves MIR bodies # together with the borrow checker information. diff --git a/tests/run-make-fulldeps/pretty-expanded/Makefile b/tests/run-make-fulldeps/pretty-expanded/Makefile index 5a0097a8351..48199179ece 100644 --- a/tests/run-make-fulldeps/pretty-expanded/Makefile +++ b/tests/run-make-fulldeps/pretty-expanded/Makefile @@ -1,4 +1,4 @@ -include ../tools.mk +include ../../run-make/tools.mk all: $(RUSTC) -o $(TMPDIR)/input.expanded.rs -Zunpretty=expanded input.rs diff --git a/tests/run-make/const_fn_mir/Makefile b/tests/run-make/const_fn_mir/Makefile index ad5695093a1..b2c268f0439 100644 --- a/tests/run-make/const_fn_mir/Makefile +++ b/tests/run-make/const_fn_mir/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk all: $(RUSTC) main.rs --emit=mir -o "$(TMPDIR)"/dump.mir diff --git a/tests/run-make/coverage/coverage_tools.mk b/tests/run-make/coverage/coverage_tools.mk index 0b6bbc33167..028c020a461 100644 --- a/tests/run-make/coverage/coverage_tools.mk +++ b/tests/run-make/coverage/coverage_tools.mk @@ -3,4 +3,4 @@ # # include ../coverage/coverage_tools.mk -include ../../run-make-fulldeps/tools.mk +include ../tools.mk diff --git a/tests/run-make/crate-hash-rustc-version/Makefile b/tests/run-make/crate-hash-rustc-version/Makefile index 4f25a865ebd..cd5950e2bb3 100644 --- a/tests/run-make/crate-hash-rustc-version/Makefile +++ b/tests/run-make/crate-hash-rustc-version/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # Ensure that crates compiled with different rustc versions cannot # be dynamically linked. diff --git a/tests/run-make/dep-graph/Makefile b/tests/run-make/dep-graph/Makefile index ae97b1672ae..d06333f4454 100644 --- a/tests/run-make/dep-graph/Makefile +++ b/tests/run-make/dep-graph/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # ignore-cross-compile diff --git a/tests/run-make/doctests-keep-binaries/Makefile b/tests/run-make/doctests-keep-binaries/Makefile index 273c8980b02..7bfff690b1f 100644 --- a/tests/run-make/doctests-keep-binaries/Makefile +++ b/tests/run-make/doctests-keep-binaries/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # Check that valid binaries are persisted by running them, regardless of whether the --run or --no-run option is used. diff --git a/tests/run-make/dump-mono-stats/Makefile b/tests/run-make/dump-mono-stats/Makefile index fe1112fb0a4..196f84be6ec 100644 --- a/tests/run-make/dump-mono-stats/Makefile +++ b/tests/run-make/dump-mono-stats/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk all: $(RUSTC) --crate-type lib foo.rs -Z dump-mono-stats=$(TMPDIR) -Zdump-mono-stats-format=json diff --git a/tests/run-make/emit-named-files/Makefile b/tests/run-make/emit-named-files/Makefile index e081fa4793b..2b97b841fc0 100644 --- a/tests/run-make/emit-named-files/Makefile +++ b/tests/run-make/emit-named-files/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk OUT=$(TMPDIR)/emit diff --git a/tests/run-make/emit-path-unhashed/Makefile b/tests/run-make/emit-path-unhashed/Makefile index c144d4aa92f..74047fe5f86 100644 --- a/tests/run-make/emit-path-unhashed/Makefile +++ b/tests/run-make/emit-path-unhashed/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk OUT=$(TMPDIR)/emit diff --git a/tests/run-make/emit-shared-files/Makefile b/tests/run-make/emit-shared-files/Makefile index cad0c9e5b81..27c72b00368 100644 --- a/tests/run-make/emit-shared-files/Makefile +++ b/tests/run-make/emit-shared-files/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk INVOCATION_ONLY = $(TMPDIR)/invocation-only TOOLCHAIN_ONLY = $(TMPDIR)/toolchain-only diff --git a/tests/run-make/env-dep-info/Makefile b/tests/run-make/env-dep-info/Makefile index 1675a61b167..bc0ffc2df1e 100644 --- a/tests/run-make/env-dep-info/Makefile +++ b/tests/run-make/env-dep-info/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # FIXME(eddyb) provide `HOST_RUSTC` and `TARGET_RUSTC` # instead of hardcoding them everywhere they're needed. diff --git a/tests/run-make/export-executable-symbols/Makefile b/tests/run-make/export-executable-symbols/Makefile index daa77c99dcd..c4d29aa2bf4 100644 --- a/tests/run-make/export-executable-symbols/Makefile +++ b/tests/run-make/export-executable-symbols/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # ignore-wasm32 # ignore-wasm64 diff --git a/tests/run-make/fmt-write-bloat/Makefile b/tests/run-make/fmt-write-bloat/Makefile index 07e6e025e08..04485582660 100644 --- a/tests/run-make/fmt-write-bloat/Makefile +++ b/tests/run-make/fmt-write-bloat/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # ignore-windows diff --git a/tests/run-make/incr-foreign-head-span/Makefile b/tests/run-make/incr-foreign-head-span/Makefile index 712965eaa88..9d6102cdd72 100644 --- a/tests/run-make/incr-foreign-head-span/Makefile +++ b/tests/run-make/incr-foreign-head-span/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # ignore-none no-std is not supported # ignore-nvptx64-nvidia-cuda FIXME: can't find crate for 'std' diff --git a/tests/run-make/incr-prev-body-beyond-eof/Makefile b/tests/run-make/incr-prev-body-beyond-eof/Makefile index 24eea3acaea..aa47552f52c 100644 --- a/tests/run-make/incr-prev-body-beyond-eof/Makefile +++ b/tests/run-make/incr-prev-body-beyond-eof/Makefile @@ -1,7 +1,7 @@ # ignore-none no-std is not supported # ignore-nvptx64-nvidia-cuda FIXME: can't find crate for `std` -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # Tests that we don't ICE during incremental compilation after modifying a # function span such that its previous end line exceeds the number of lines diff --git a/tests/run-make/incremental-session-fail/Makefile b/tests/run-make/incremental-session-fail/Makefile index 6ce1370927b..f43eece2eb7 100644 --- a/tests/run-make/incremental-session-fail/Makefile +++ b/tests/run-make/incremental-session-fail/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk SESSION_DIR := $(TMPDIR)/session OUTPUT_FILE := $(TMPDIR)/build-output diff --git a/tests/run-make/invalid-so/Makefile b/tests/run-make/invalid-so/Makefile index 5b82ecd207d..e36c7040bc6 100644 --- a/tests/run-make/invalid-so/Makefile +++ b/tests/run-make/invalid-so/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk DYLIB_NAME := $(shell echo | $(RUSTC) --crate-name foo --crate-type dylib --print file-names -) diff --git a/tests/run-make/issue-10971-temps-dir/Makefile b/tests/run-make/issue-10971-temps-dir/Makefile index e589bbffe60..6e1649a58d2 100644 --- a/tests/run-make/issue-10971-temps-dir/Makefile +++ b/tests/run-make/issue-10971-temps-dir/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # Regression test for issue #10971 # Running two invocations in parallel would overwrite each other's temp files. diff --git a/tests/run-make/issue-36710/Makefile b/tests/run-make/issue-36710/Makefile index c6b71f5fbd4..c3de474fbbe 100644 --- a/tests/run-make/issue-36710/Makefile +++ b/tests/run-make/issue-36710/Makefile @@ -6,7 +6,7 @@ # (see dist-i586-gnu-i586-i686-musl Dockerfile) # ignore-sgx -include ../../run-make-fulldeps/tools.mk +include ../tools.mk all: foo $(call RUN,foo) diff --git a/tests/run-make/issue-47384/Makefile b/tests/run-make/issue-47384/Makefile index 0aadf6c88c9..afc77cb275a 100644 --- a/tests/run-make/issue-47384/Makefile +++ b/tests/run-make/issue-47384/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # only-linux # ignore-cross-compile diff --git a/tests/run-make/issue-71519/Makefile b/tests/run-make/issue-71519/Makefile index 57497f52053..0ee83328bb6 100644 --- a/tests/run-make/issue-71519/Makefile +++ b/tests/run-make/issue-71519/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # ignore-msvc # needs-rust-lld diff --git a/tests/run-make/issue-83045/Makefile b/tests/run-make/issue-83045/Makefile index fc180ccfe28..7053da00f6b 100644 --- a/tests/run-make/issue-83045/Makefile +++ b/tests/run-make/issue-83045/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # This test case creates a situation where the crate loader would run # into an ICE when confronted with an invalid setup where it cannot diff --git a/tests/run-make/issue-83112-incr-test-moved-file/Makefile b/tests/run-make/issue-83112-incr-test-moved-file/Makefile index 2f796e5b2fc..a00088cd9d6 100644 --- a/tests/run-make/issue-83112-incr-test-moved-file/Makefile +++ b/tests/run-make/issue-83112-incr-test-moved-file/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # ignore-none no-std is not supported # ignore-nvptx64-nvidia-cuda FIXME: can't find crate for 'std' diff --git a/tests/run-make/issue-84395-lto-embed-bitcode/Makefile b/tests/run-make/issue-84395-lto-embed-bitcode/Makefile index 879ce174339..95c8d08a18b 100644 --- a/tests/run-make/issue-84395-lto-embed-bitcode/Makefile +++ b/tests/run-make/issue-84395-lto-embed-bitcode/Makefile @@ -3,7 +3,7 @@ # This test makes sure the embed bitcode in elf created with # lto-embed-bitcode=optimized is valid llvm BC module. -include ../../run-make-fulldeps/tools.mk +include ../tools.mk all: $(RUSTC) test.rs --target $(TARGET) -Clink-arg=-fuse-ld=lld -Clinker-plugin-lto -Clinker=$(CLANG) -Clink-arg=-Wl,--plugin-opt=-lto-embed-bitcode=optimized -Zemit-thin-lto=no diff --git a/tests/run-make/issue-85019-moved-src-dir/Makefile b/tests/run-make/issue-85019-moved-src-dir/Makefile index 3606d4fdf57..dec289058f9 100644 --- a/tests/run-make/issue-85019-moved-src-dir/Makefile +++ b/tests/run-make/issue-85019-moved-src-dir/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk INCR=$(TMPDIR)/incr FIRST_SRC=$(TMPDIR)/first_src diff --git a/tests/run-make/issue-85401-static-mir/Makefile b/tests/run-make/issue-85401-static-mir/Makefile index 99590166bca..47a36b6e453 100644 --- a/tests/run-make/issue-85401-static-mir/Makefile +++ b/tests/run-make/issue-85401-static-mir/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # Regression test for issue #85401 # Verify that we do not ICE when trying to access MIR for statics, diff --git a/tests/run-make/issue-85441/Makefile b/tests/run-make/issue-85441/Makefile index f04b07d51fa..987d7f7d4a7 100644 --- a/tests/run-make/issue-85441/Makefile +++ b/tests/run-make/issue-85441/Makefile @@ -1,6 +1,6 @@ # only-windows-msvc -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # Tests that WS2_32.dll is not unnecessarily linked, see issue #85441 diff --git a/tests/run-make/issue-88756-default-output/Makefile b/tests/run-make/issue-88756-default-output/Makefile index 275c35c2629..d1c3d0fe082 100644 --- a/tests/run-make/issue-88756-default-output/Makefile +++ b/tests/run-make/issue-88756-default-output/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk all: $(BARE_RUSTDOC) 2>&1 | sed -E 's@/nightly/|/beta/|/stable/|/1\.[0-9]+\.[0-9]+/@/$$CHANNEL/@g' | diff - output-default.stdout diff --git a/tests/run-make/issue-96498/Makefile b/tests/run-make/issue-96498/Makefile index ce2b1b1ff7c..efdd328c671 100644 --- a/tests/run-make/issue-96498/Makefile +++ b/tests/run-make/issue-96498/Makefile @@ -1,7 +1,7 @@ # only-windows # needs-rust-lld -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # Ensure that LLD can link all: diff --git a/tests/run-make/issue-97463-abi-param-passing/Makefile b/tests/run-make/issue-97463-abi-param-passing/Makefile index 2f9c8c7c8be..b4ff88d1957 100644 --- a/tests/run-make/issue-97463-abi-param-passing/Makefile +++ b/tests/run-make/issue-97463-abi-param-passing/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # ignore-msvc diff --git a/tests/run-make/issue64319/Makefile b/tests/run-make/issue64319/Makefile index ee0d177abc9..f852fdf2d05 100644 --- a/tests/run-make/issue64319/Makefile +++ b/tests/run-make/issue64319/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # Different optimization levels imply different values for `-Zshare-generics`, # so try out a whole bunch of combinations to make sure everything is compatible diff --git a/tests/run-make/jobserver-error/Makefile b/tests/run-make/jobserver-error/Makefile index 3b9104fc354..39946ae5edb 100644 --- a/tests/run-make/jobserver-error/Makefile +++ b/tests/run-make/jobserver-error/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # only-linux diff --git a/tests/run-make/libtest-thread-limit/Makefile b/tests/run-make/libtest-thread-limit/Makefile index d43a89e60ca..9496fa30159 100644 --- a/tests/run-make/libtest-thread-limit/Makefile +++ b/tests/run-make/libtest-thread-limit/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # only-linux diff --git a/tests/run-make/llvm-outputs/Makefile b/tests/run-make/llvm-outputs/Makefile index a3f25eba0b2..cccf1dd66fb 100644 --- a/tests/run-make/llvm-outputs/Makefile +++ b/tests/run-make/llvm-outputs/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk all: echo 'fn main() {}' | $(BARE_RUSTC) - --out-dir=$(TMPDIR)/random_directory_that_does_not_exist_ir/ --emit=llvm-ir diff --git a/tests/run-make/macos-deployment-target/Makefile b/tests/run-make/macos-deployment-target/Makefile index 70fca043653..d0cf836bcdf 100644 --- a/tests/run-make/macos-deployment-target/Makefile +++ b/tests/run-make/macos-deployment-target/Makefile @@ -4,7 +4,7 @@ # This is important since its a compatibility hazard. The linker will # generate load commands differently based on what minimum OS it can assume. -include ../../run-make-fulldeps/tools.mk +include ../tools.mk ifeq ($(strip $(shell uname -m)),arm64) GREP_PATTERN = "minos 11.0" diff --git a/tests/run-make/macos-fat-archive/Makefile b/tests/run-make/macos-fat-archive/Makefile index 8dd9a747686..b6582c809e8 100644 --- a/tests/run-make/macos-fat-archive/Makefile +++ b/tests/run-make/macos-fat-archive/Makefile @@ -1,6 +1,6 @@ # only-macos -include ../../run-make-fulldeps/tools.mk +include ../tools.mk "$(TMPDIR)"/libnative-library.a: native-library.c $(CC) -arch arm64 -arch x86_64 native-library.c -c -o "$(TMPDIR)"/native-library.o diff --git a/tests/run-make/native-link-modifier-bundle/Makefile b/tests/run-make/native-link-modifier-bundle/Makefile index e8a1121bfcd..527720922fe 100644 --- a/tests/run-make/native-link-modifier-bundle/Makefile +++ b/tests/run-make/native-link-modifier-bundle/Makefile @@ -1,7 +1,7 @@ # ignore-cross-compile # ignore-windows-msvc -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # We're using the llvm-nm instead of the system nm to ensure it is compatible # with the LLVM bitcode generated by rustc. diff --git a/tests/run-make/native-link-modifier-verbatim-linker/Makefile b/tests/run-make/native-link-modifier-verbatim-linker/Makefile index 666e4084ce2..256dc2d0664 100644 --- a/tests/run-make/native-link-modifier-verbatim-linker/Makefile +++ b/tests/run-make/native-link-modifier-verbatim-linker/Makefile @@ -1,7 +1,7 @@ # ignore-cross-compile # ignore-macos -include ../../run-make-fulldeps/tools.mk +include ../tools.mk all: # Verbatim allows specify precise name. diff --git a/tests/run-make/native-link-modifier-verbatim-rustc/Makefile b/tests/run-make/native-link-modifier-verbatim-rustc/Makefile index 6f01f37804a..dfd6ec50fc0 100644 --- a/tests/run-make/native-link-modifier-verbatim-rustc/Makefile +++ b/tests/run-make/native-link-modifier-verbatim-rustc/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk all: # Verbatim allows specify precise name. diff --git a/tests/run-make/native-link-modifier-whole-archive/Makefile b/tests/run-make/native-link-modifier-whole-archive/Makefile index f26bd864ced..5eb7a416f91 100644 --- a/tests/run-make/native-link-modifier-whole-archive/Makefile +++ b/tests/run-make/native-link-modifier-whole-archive/Makefile @@ -8,7 +8,7 @@ # that code would never make it into the final executable and we'd thus be missing some # of the output. -include ../../run-make-fulldeps/tools.mk +include ../tools.mk all: $(TMPDIR)/$(call BIN,directly_linked) \ $(TMPDIR)/$(call BIN,directly_linked_test_plus_whole_archive) \ diff --git a/tests/run-make/no-input-file/Makefile b/tests/run-make/no-input-file/Makefile index 2f02159229d..a754573a524 100644 --- a/tests/run-make/no-input-file/Makefile +++ b/tests/run-make/no-input-file/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk all: $(RUSTC) --print crate-name 2>&1 | diff - no-input-file.stderr diff --git a/tests/run-make/overwrite-input/Makefile b/tests/run-make/overwrite-input/Makefile index 03b03eb147d..c62b5aab190 100644 --- a/tests/run-make/overwrite-input/Makefile +++ b/tests/run-make/overwrite-input/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk all: $(RUSTC) main.rs -o main.rs 2> $(TMPDIR)/file.stderr || echo "failed successfully" diff --git a/tests/run-make/panic-impl-transitive/Makefile b/tests/run-make/panic-impl-transitive/Makefile index c3192efcb5a..9a271a22e10 100644 --- a/tests/run-make/panic-impl-transitive/Makefile +++ b/tests/run-make/panic-impl-transitive/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # NOTE we use --emit=llvm-ir to avoid running the linker (linking will fail because there's no main # in this crate) diff --git a/tests/run-make/pass-linker-flags-from-dep/Makefile b/tests/run-make/pass-linker-flags-from-dep/Makefile index b9426326aea..b57389bb7d4 100644 --- a/tests/run-make/pass-linker-flags-from-dep/Makefile +++ b/tests/run-make/pass-linker-flags-from-dep/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk all: # Build deps diff --git a/tests/run-make/pass-linker-flags/Makefile b/tests/run-make/pass-linker-flags/Makefile index a3efb8df6ac..6ddbcbb1b08 100644 --- a/tests/run-make/pass-linker-flags/Makefile +++ b/tests/run-make/pass-linker-flags/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk all: $(RUSTC) rs.rs -Z unstable-options -l static=l1 -l link-arg=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*a1.*l2.*a2.*d1.*a3' diff --git a/tests/run-make/print-calling-conventions/Makefile b/tests/run-make/print-calling-conventions/Makefile index 472b0723b10..27b87e61086 100644 --- a/tests/run-make/print-calling-conventions/Makefile +++ b/tests/run-make/print-calling-conventions/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk all: $(RUSTC) --print calling-conventions diff --git a/tests/run-make/raw-dylib-alt-calling-convention/Makefile b/tests/run-make/raw-dylib-alt-calling-convention/Makefile index 03f8778d25d..1744c431f9c 100644 --- a/tests/run-make/raw-dylib-alt-calling-convention/Makefile +++ b/tests/run-make/raw-dylib-alt-calling-convention/Makefile @@ -3,7 +3,7 @@ # only-x86 # only-windows -include ../../run-make-fulldeps/tools.mk +include ../tools.mk all: $(RUSTC) --crate-type lib --crate-name raw_dylib_alt_calling_convention_test lib.rs diff --git a/tests/run-make/raw-dylib-c/Makefile b/tests/run-make/raw-dylib-c/Makefile index f47ab24f4fb..06e7935c026 100644 --- a/tests/run-make/raw-dylib-c/Makefile +++ b/tests/run-make/raw-dylib-c/Makefile @@ -2,7 +2,7 @@ # only-windows -include ../../run-make-fulldeps/tools.mk +include ../tools.mk all: $(RUSTC) --crate-type lib --crate-name raw_dylib_test lib.rs diff --git a/tests/run-make/raw-dylib-cross-compilation/Makefile b/tests/run-make/raw-dylib-cross-compilation/Makefile index 2a714f3a11f..a8f97edd689 100644 --- a/tests/run-make/raw-dylib-cross-compilation/Makefile +++ b/tests/run-make/raw-dylib-cross-compilation/Makefile @@ -7,7 +7,7 @@ # i686 dlltool.exe can't product x64 binaries. # ignore-i686-pc-windows-gnu -include ../../run-make-fulldeps/tools.mk +include ../tools.mk all: # Build as x86 and make sure that we have x86 objects only. diff --git a/tests/run-make/raw-dylib-import-name-type/Makefile b/tests/run-make/raw-dylib-import-name-type/Makefile index 314e22c412d..67152329807 100644 --- a/tests/run-make/raw-dylib-import-name-type/Makefile +++ b/tests/run-make/raw-dylib-import-name-type/Makefile @@ -3,7 +3,7 @@ # only-x86 # only-windows -include ../../run-make-fulldeps/tools.mk +include ../tools.mk all: $(RUSTC) --crate-type bin driver.rs -L "$(TMPDIR)" diff --git a/tests/run-make/raw-dylib-inline-cross-dylib/Makefile b/tests/run-make/raw-dylib-inline-cross-dylib/Makefile index 722a49b02cb..6d1d04bfd37 100644 --- a/tests/run-make/raw-dylib-inline-cross-dylib/Makefile +++ b/tests/run-make/raw-dylib-inline-cross-dylib/Makefile @@ -2,7 +2,7 @@ # only-windows -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # We'd be using the llvm-objdump instead of the system objdump to ensure compatibility # with the LLVM bitcode generated by rustc but on Windows piping/IO redirection under MSYS2 is wonky with llvm-objdump. diff --git a/tests/run-make/raw-dylib-link-ordinal/Makefile b/tests/run-make/raw-dylib-link-ordinal/Makefile index b55a94dbc46..374a0b59de3 100644 --- a/tests/run-make/raw-dylib-link-ordinal/Makefile +++ b/tests/run-make/raw-dylib-link-ordinal/Makefile @@ -2,7 +2,7 @@ # only-windows -include ../../run-make-fulldeps/tools.mk +include ../tools.mk all: $(RUSTC) --crate-type lib --crate-name raw_dylib_test lib.rs diff --git a/tests/run-make/raw-dylib-stdcall-ordinal/Makefile b/tests/run-make/raw-dylib-stdcall-ordinal/Makefile index b9deb7729c2..178c15ab3de 100644 --- a/tests/run-make/raw-dylib-stdcall-ordinal/Makefile +++ b/tests/run-make/raw-dylib-stdcall-ordinal/Makefile @@ -3,7 +3,7 @@ # only-x86 # only-windows -include ../../run-make-fulldeps/tools.mk +include ../tools.mk all: $(RUSTC) --crate-type lib --crate-name raw_dylib_test lib.rs diff --git a/tests/run-make/remap-path-prefix-dwarf/Makefile b/tests/run-make/remap-path-prefix-dwarf/Makefile index fbaea7b68fe..c9ede1b6027 100644 --- a/tests/run-make/remap-path-prefix-dwarf/Makefile +++ b/tests/run-make/remap-path-prefix-dwarf/Makefile @@ -6,7 +6,7 @@ SRC_DIR := $(abspath .) SRC_DIR_PARENT := $(abspath ..) -include ../../run-make-fulldeps/tools.mk +include ../tools.mk all: \ abs_input_outside_working_dir \ diff --git a/tests/run-make/repr128-dwarf/Makefile b/tests/run-make/repr128-dwarf/Makefile index 2b03c22c0d0..3f933042724 100644 --- a/tests/run-make/repr128-dwarf/Makefile +++ b/tests/run-make/repr128-dwarf/Makefile @@ -2,7 +2,7 @@ # This test should be replaced with one in tests/debuginfo once GDB or LLDB support 128-bit # enums. -include ../../run-make-fulldeps/tools.mk +include ../tools.mk all: $(RUSTC) -Cdebuginfo=2 lib.rs -o $(TMPDIR)/repr128.rlib diff --git a/tests/run-make/rlib-format-packed-bundled-libs-2/Makefile b/tests/run-make/rlib-format-packed-bundled-libs-2/Makefile index 440fd3dd588..d2a740b06b3 100644 --- a/tests/run-make/rlib-format-packed-bundled-libs-2/Makefile +++ b/tests/run-make/rlib-format-packed-bundled-libs-2/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # ignore-cross-compile diff --git a/tests/run-make/rlib-format-packed-bundled-libs-3/Makefile b/tests/run-make/rlib-format-packed-bundled-libs-3/Makefile index b2006f3ec92..1f2812cb087 100644 --- a/tests/run-make/rlib-format-packed-bundled-libs-3/Makefile +++ b/tests/run-make/rlib-format-packed-bundled-libs-3/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # ignore-cross-compile # only-linux diff --git a/tests/run-make/rlib-format-packed-bundled-libs/Makefile b/tests/run-make/rlib-format-packed-bundled-libs/Makefile index 046c82f9469..f454da67893 100644 --- a/tests/run-make/rlib-format-packed-bundled-libs/Makefile +++ b/tests/run-make/rlib-format-packed-bundled-libs/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # ignore-cross-compile diff --git a/tests/run-make/rustc-macro-dep-files/Makefile b/tests/run-make/rustc-macro-dep-files/Makefile index 6ae659db2e9..76d713c4bb3 100644 --- a/tests/run-make/rustc-macro-dep-files/Makefile +++ b/tests/run-make/rustc-macro-dep-files/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # FIXME(eddyb) provide `HOST_RUSTC` and `TARGET_RUSTC` # instead of hardcoding them everywhere they're needed. diff --git a/tests/run-make/rustdoc-scrape-examples-multiple/scrape.mk b/tests/run-make/rustdoc-scrape-examples-multiple/scrape.mk index 7a28d2145d5..57220bc6635 100644 --- a/tests/run-make/rustdoc-scrape-examples-multiple/scrape.mk +++ b/tests/run-make/rustdoc-scrape-examples-multiple/scrape.mk @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk OUTPUT_DIR := "$(TMPDIR)/rustdoc" diff --git a/tests/run-make/rustdoc-verify-output-files/Makefile b/tests/run-make/rustdoc-verify-output-files/Makefile index 0666122e8ab..57ac7078d14 100644 --- a/tests/run-make/rustdoc-verify-output-files/Makefile +++ b/tests/run-make/rustdoc-verify-output-files/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk OUTPUT_DIR := "$(TMPDIR)/rustdoc" TMP_OUTPUT_DIR := "$(TMPDIR)/tmp-rustdoc" diff --git a/tests/run-make/rustdoc-with-out-dir-option/Makefile b/tests/run-make/rustdoc-with-out-dir-option/Makefile index b3c3f5230c1..f5d5060ed13 100644 --- a/tests/run-make/rustdoc-with-out-dir-option/Makefile +++ b/tests/run-make/rustdoc-with-out-dir-option/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk OUTPUT_DIR := "$(TMPDIR)/rustdoc" diff --git a/tests/run-make/rustdoc-with-output-option/Makefile b/tests/run-make/rustdoc-with-output-option/Makefile index 02093a35cfc..d0a8205a8ee 100644 --- a/tests/run-make/rustdoc-with-output-option/Makefile +++ b/tests/run-make/rustdoc-with-output-option/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk OUTPUT_DIR := "$(TMPDIR)/rustdoc" diff --git a/tests/run-make/rustdoc-with-short-out-dir-option/Makefile b/tests/run-make/rustdoc-with-short-out-dir-option/Makefile index dc5056a86dd..1b9327bce22 100644 --- a/tests/run-make/rustdoc-with-short-out-dir-option/Makefile +++ b/tests/run-make/rustdoc-with-short-out-dir-option/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk OUTPUT_DIR := "$(TMPDIR)/rustdoc" diff --git a/tests/run-make/share-generics-dylib/Makefile b/tests/run-make/share-generics-dylib/Makefile index 065fb574c3c..5fea91bb4c2 100644 --- a/tests/run-make/share-generics-dylib/Makefile +++ b/tests/run-make/share-generics-dylib/Makefile @@ -9,7 +9,7 @@ # # This is regression test for https://github.com/rust-lang/rust/issues/67276. -include ../../run-make-fulldeps/tools.mk +include ../tools.mk COMMON_ARGS=-Cprefer-dynamic -Zshare-generics=yes -Ccodegen-units=1 -Csymbol-mangling-version=v0 diff --git a/tests/run-make/static-pie/Makefile b/tests/run-make/static-pie/Makefile index f4e6adf1b18..19c041d9428 100644 --- a/tests/run-make/static-pie/Makefile +++ b/tests/run-make/static-pie/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # only-x86_64 # only-linux diff --git a/tests/run-make/test-benches/Makefile b/tests/run-make/test-benches/Makefile index 8fc122515d0..0253a52637f 100644 --- a/tests/run-make/test-benches/Makefile +++ b/tests/run-make/test-benches/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # ignore-cross-compile diff --git a/tests/run-make/thumb-none-cortex-m/Makefile b/tests/run-make/thumb-none-cortex-m/Makefile index 3065141c08a..e941fc4a78e 100644 --- a/tests/run-make/thumb-none-cortex-m/Makefile +++ b/tests/run-make/thumb-none-cortex-m/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # How to run this # $ ./x.py clean diff --git a/tests/run-make/thumb-none-qemu/Makefile b/tests/run-make/thumb-none-qemu/Makefile index a1c2ba12cd0..eea6ca34992 100644 --- a/tests/run-make/thumb-none-qemu/Makefile +++ b/tests/run-make/thumb-none-qemu/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # only-thumb diff --git a/tests/run-make-fulldeps/tools.mk b/tests/run-make/tools.mk similarity index 100% rename from tests/run-make-fulldeps/tools.mk rename to tests/run-make/tools.mk diff --git a/tests/run-make/track-path-dep-info/Makefile b/tests/run-make/track-path-dep-info/Makefile index ee853943f8b..0d6c9b1d2f0 100644 --- a/tests/run-make/track-path-dep-info/Makefile +++ b/tests/run-make/track-path-dep-info/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # FIXME(eddyb) provide `HOST_RUSTC` and `TARGET_RUSTC` # instead of hardcoding them everywhere they're needed. diff --git a/tests/run-make/track-pgo-dep-info/Makefile b/tests/run-make/track-pgo-dep-info/Makefile index 4e1e29f90db..6c7f67d0f0a 100644 --- a/tests/run-make/track-pgo-dep-info/Makefile +++ b/tests/run-make/track-pgo-dep-info/Makefile @@ -1,7 +1,7 @@ # needs-profiler-support # ignore-windows-gnu -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # FIXME(eddyb) provide `HOST_RUSTC` and `TARGET_RUSTC` # instead of hardcoding them everywhere they're needed. diff --git a/tests/run-make/translation/Makefile b/tests/run-make/translation/Makefile index 397fc542909..0acf64e5da7 100644 --- a/tests/run-make/translation/Makefile +++ b/tests/run-make/translation/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # This test uses `ln -s` rather than copying to save testing time, but its # usage doesn't work on Windows. diff --git a/tests/run-make/unstable-flag-required/Makefile b/tests/run-make/unstable-flag-required/Makefile index d3a734fae77..17dd15b079c 100644 --- a/tests/run-make/unstable-flag-required/Makefile +++ b/tests/run-make/unstable-flag-required/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk all: $(RUSTDOC) --output-format=json x.html 2>&1 | diff - output-format-json.stderr diff --git a/tests/run-make/valid-print-requests/Makefile b/tests/run-make/valid-print-requests/Makefile index c325e536e7c..99430e98d1c 100644 --- a/tests/run-make/valid-print-requests/Makefile +++ b/tests/run-make/valid-print-requests/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk all: $(RUSTC) --print uwu 2>&1 | diff - valid-print-requests.stderr diff --git a/tests/run-make/wasm-abi/Makefile b/tests/run-make/wasm-abi/Makefile index e713ca1876d..ed95464efef 100644 --- a/tests/run-make/wasm-abi/Makefile +++ b/tests/run-make/wasm-abi/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # only-wasm32-bare diff --git a/tests/run-make/wasm-custom-section/Makefile b/tests/run-make/wasm-custom-section/Makefile index 92b0802e30a..2f7d38c2736 100644 --- a/tests/run-make/wasm-custom-section/Makefile +++ b/tests/run-make/wasm-custom-section/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # only-wasm32-bare diff --git a/tests/run-make/wasm-custom-sections-opt/Makefile b/tests/run-make/wasm-custom-sections-opt/Makefile index e5b45d96310..a0d4378131b 100644 --- a/tests/run-make/wasm-custom-sections-opt/Makefile +++ b/tests/run-make/wasm-custom-sections-opt/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # only-wasm32-bare diff --git a/tests/run-make/wasm-export-all-symbols/Makefile b/tests/run-make/wasm-export-all-symbols/Makefile index 834f4d258db..86713bc80b8 100644 --- a/tests/run-make/wasm-export-all-symbols/Makefile +++ b/tests/run-make/wasm-export-all-symbols/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # only-wasm32-bare diff --git a/tests/run-make/wasm-import-module/Makefile b/tests/run-make/wasm-import-module/Makefile index 18cef16aac3..a0b4d920b3d 100644 --- a/tests/run-make/wasm-import-module/Makefile +++ b/tests/run-make/wasm-import-module/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # only-wasm32-bare diff --git a/tests/run-make/wasm-panic-small/Makefile b/tests/run-make/wasm-panic-small/Makefile index 2af9f71357e..16f54521855 100644 --- a/tests/run-make/wasm-panic-small/Makefile +++ b/tests/run-make/wasm-panic-small/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # only-wasm32-bare diff --git a/tests/run-make/wasm-spurious-import/Makefile b/tests/run-make/wasm-spurious-import/Makefile index 6f50e6e554e..ff9dfeac6d0 100644 --- a/tests/run-make/wasm-spurious-import/Makefile +++ b/tests/run-make/wasm-spurious-import/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # only-wasm32-bare diff --git a/tests/run-make/wasm-stringify-ints-small/Makefile b/tests/run-make/wasm-stringify-ints-small/Makefile index 2fa2c954d4a..f959dbd426b 100644 --- a/tests/run-make/wasm-stringify-ints-small/Makefile +++ b/tests/run-make/wasm-stringify-ints-small/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk ifeq ($(TARGET),wasm32-unknown-unknown) all: diff --git a/tests/run-make/wasm-symbols-different-module/Makefile b/tests/run-make/wasm-symbols-different-module/Makefile index 9e657222dea..0f86914c7b1 100644 --- a/tests/run-make/wasm-symbols-different-module/Makefile +++ b/tests/run-make/wasm-symbols-different-module/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # only-wasm32-bare diff --git a/tests/run-make/wasm-symbols-not-exported/Makefile b/tests/run-make/wasm-symbols-not-exported/Makefile index 60b0dee001f..024ad779748 100644 --- a/tests/run-make/wasm-symbols-not-exported/Makefile +++ b/tests/run-make/wasm-symbols-not-exported/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # only-wasm32-bare diff --git a/tests/run-make/wasm-symbols-not-imported/Makefile b/tests/run-make/wasm-symbols-not-imported/Makefile index dc7618c19a7..38440a8b025 100644 --- a/tests/run-make/wasm-symbols-not-imported/Makefile +++ b/tests/run-make/wasm-symbols-not-imported/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk # only-wasm32-bare diff --git a/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/Makefile b/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/Makefile index 84dcd239351..3c88ec34f43 100644 --- a/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/Makefile +++ b/tests/run-make/x86_64-fortanix-unknown-sgx-lvi/Makefile @@ -1,4 +1,4 @@ -include ../../run-make-fulldeps/tools.mk +include ../tools.mk #only-x86_64-fortanix-unknown-sgx From 8e214cbc0640c0a57db0f277d600da248135111c Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 30 Mar 2023 08:44:46 -0500 Subject: [PATCH 290/346] fix `sysroot-crates-are-unstable` for cross-compilation --- tests/run-make/sysroot-crates-are-unstable/test.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/run-make/sysroot-crates-are-unstable/test.py b/tests/run-make/sysroot-crates-are-unstable/test.py index cb77eb34fef..cab4faa4e64 100644 --- a/tests/run-make/sysroot-crates-are-unstable/test.py +++ b/tests/run-make/sysroot-crates-are-unstable/test.py @@ -43,6 +43,7 @@ def check_lib(lib): return True print('verifying if {} is an unstable crate'.format(lib['name'])) stdout, stderr = exec_command([os.environ['RUSTC'], '-', '--crate-type', 'rlib', + '--target', os.environ['TARGET'], '--extern', '{}={}'.format(lib['name'], lib['path'])], to_input=('extern crate {};'.format(lib['name'])).encode('utf-8')) if not 'use of unstable library feature' in '{}{}'.format(stdout, stderr): From 4851d5663cf74fafc1d753d68394ea0011cfde36 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 30 Mar 2023 08:46:31 -0500 Subject: [PATCH 291/346] ignore failing cross-compiled run-make tests `run-make-fulldeps` is never cross-compiled, so a lot of these tests never accounted for --target. Ignore them when cross-compiling for now. --- tests/run-make/a-b-a-linker-guard/Makefile | 1 + tests/run-make/allow-non-lint-warnings-cmdline/Makefile | 1 + tests/run-make/allow-warnings-cmdline-stability/Makefile | 1 + tests/run-make/archive-duplicate-names/Makefile | 1 + tests/run-make/arguments-non-c-like-enum/Makefile | 1 + tests/run-make/bare-outfile/Makefile | 1 + tests/run-make/c-dynamic-dylib/Makefile | 1 + tests/run-make/c-dynamic-rlib/Makefile | 1 + tests/run-make/c-link-to-rust-dylib/Makefile | 1 + tests/run-make/c-link-to-rust-staticlib/Makefile | 1 + tests/run-make/c-link-to-rust-va-list-fn/Makefile | 1 + tests/run-make/c-static-dylib/Makefile | 1 + tests/run-make/c-static-rlib/Makefile | 1 + tests/run-make/c-unwind-abi-catch-lib-panic/Makefile | 1 + tests/run-make/c-unwind-abi-catch-panic/Makefile | 1 + tests/run-make/cdylib-dylib-linkage/Makefile | 1 + tests/run-make/cdylib-fewer-symbols/Makefile | 1 + tests/run-make/cdylib/Makefile | 1 + tests/run-make/codegen-options-parsing/Makefile | 1 + tests/run-make/compile-stdin/Makefile | 1 + tests/run-make/crate-hash-rustc-version/Makefile | 1 + tests/run-make/crate-name-priority/Makefile | 1 + tests/run-make/debug-assertions/Makefile | 1 + tests/run-make/doctests-keep-binaries/Makefile | 1 + tests/run-make/dylib-chain/Makefile | 1 + tests/run-make/emit/Makefile | 1 + tests/run-make/exit-code/Makefile | 1 + tests/run-make/extern-diff-internal-name/Makefile | 1 + tests/run-make/extern-flag-disambiguates/Makefile | 1 + tests/run-make/extern-flag-fun/Makefile | 1 + tests/run-make/extern-flag-pathless/Makefile | 1 + tests/run-make/extern-fn-generic/Makefile | 1 + tests/run-make/extern-fn-mangle/Makefile | 1 + tests/run-make/extern-fn-reachable/Makefile | 1 + tests/run-make/extern-fn-struct-passing-abi/Makefile | 1 + tests/run-make/extern-fn-with-extern-types/Makefile | 1 + tests/run-make/extern-fn-with-packed-struct/Makefile | 1 + tests/run-make/extern-fn-with-union/Makefile | 1 + tests/run-make/extern-multiple-copies/Makefile | 1 + tests/run-make/extern-multiple-copies2/Makefile | 1 + tests/run-make/extern-overrides-distribution/Makefile | 1 + tests/run-make/extra-filename-with-temp-outputs/Makefile | 1 + tests/run-make/foreign-double-unwind/Makefile | 1 + tests/run-make/foreign-exceptions/Makefile | 1 + tests/run-make/foreign-rust-exceptions/Makefile | 1 + tests/run-make/fpic/Makefile | 1 + tests/run-make/glibc-staticlib-args/Makefile | 1 + tests/run-make/incr-add-rust-src-component/Makefile | 1 + tests/run-make/interdependent-c-libraries/Makefile | 1 + tests/run-make/issue-11908/Makefile | 1 + tests/run-make/issue-14500/Makefile | 2 ++ tests/run-make/issue-15460/Makefile | 1 + tests/run-make/issue-20626/Makefile | 1 + tests/run-make/issue-22131/Makefile | 1 + tests/run-make/issue-24445/Makefile | 1 + tests/run-make/issue-25581/Makefile | 1 + tests/run-make/issue-26006/Makefile | 1 + tests/run-make/issue-28595/Makefile | 1 + tests/run-make/issue-30063/Makefile | 1 + tests/run-make/issue-36710/Makefile | 1 + tests/run-make/issue-37839/Makefile | 1 + tests/run-make/issue-37893/Makefile | 1 + tests/run-make/issue-38237/Makefile | 1 + tests/run-make/issue-46239/Makefile | 1 + tests/run-make/issue-68794-textrel-on-minimal-lib/Makefile | 1 + tests/run-make/issue-69368/Makefile | 1 + tests/run-make/issue-97463-abi-param-passing/Makefile | 1 + tests/run-make/issue64319/Makefile | 1 + tests/run-make/libs-through-symlinks/Makefile | 1 + tests/run-make/libtest-json/Makefile | 1 + tests/run-make/link-cfg/Makefile | 1 + tests/run-make/link-path-order/Makefile | 1 + tests/run-make/linkage-attr-on-static/Makefile | 1 + tests/run-make/long-linker-command-lines-cmd-exe/Makefile | 1 + tests/run-make/long-linker-command-lines/Makefile | 1 + tests/run-make/longjmp-across-rust/Makefile | 1 + tests/run-make/ls-metadata/Makefile | 1 + tests/run-make/lto-dylib-dep/Makefile | 1 + tests/run-make/lto-empty/Makefile | 1 + tests/run-make/lto-no-link-whole-rlib/Makefile | 1 + tests/run-make/lto-readonly-lib/Makefile | 1 + tests/run-make/lto-smoke-c/Makefile | 1 + tests/run-make/lto-smoke/Makefile | 1 + tests/run-make/manual-link/Makefile | 1 + tests/run-make/metadata-flag-frobs-symbols/Makefile | 1 + tests/run-make/mixing-deps/Makefile | 1 + tests/run-make/mixing-formats/Makefile | 1 + tests/run-make/mixing-libs/Makefile | 1 + tests/run-make/msvc-opt-minsize/Makefile | 1 + tests/run-make/no-duplicate-libs/Makefile | 1 + tests/run-make/no-intermediate-extras/Makefile | 1 + tests/run-make/obey-crate-type-flag/Makefile | 1 + tests/run-make/output-filename-overwrites-input/Makefile | 1 + tests/run-make/output-type-permutations/Makefile | 1 + tests/run-make/output-with-hyphens/Makefile | 1 + tests/run-make/override-aliased-flags/Makefile | 1 + tests/run-make/pass-non-c-like-enum-to-c/Makefile | 1 + tests/run-make/prefer-dylib/Makefile | 1 + tests/run-make/prefer-rlib/Makefile | 1 + tests/run-make/prune-link-args/Makefile | 1 + tests/run-make/redundant-libs/Makefile | 1 + tests/run-make/relocation-model/Makefile | 1 + tests/run-make/relro-levels/Makefile | 1 + tests/run-make/reproducible-build-2/Makefile | 1 + tests/run-make/reproducible-build/Makefile | 1 + tests/run-make/return-non-c-like-enum-from-c/Makefile | 1 + tests/run-make/return-non-c-like-enum/Makefile | 1 + tests/run-make/rlib-chain/Makefile | 1 + tests/run-make/rustdoc-scrape-examples-macros/Makefile | 1 + tests/run-make/separate-link/Makefile | 1 + tests/run-make/share-generics-dylib/Makefile | 1 + tests/run-make/simple-dylib/Makefile | 1 + tests/run-make/simple-rlib/Makefile | 1 + tests/run-make/split-debuginfo/Makefile | 1 + tests/run-make/static-dylib-by-default/Makefile | 1 + tests/run-make/static-extern-type/Makefile | 1 + tests/run-make/static-unwinding/Makefile | 1 + tests/run-make/std-core-cycle/Makefile | 1 + tests/run-make/suspicious-library/Makefile | 1 + tests/run-make/symbol-visibility/Makefile | 1 + tests/run-make/symlinked-extern/Makefile | 1 + tests/run-make/symlinked-libraries/Makefile | 1 + tests/run-make/symlinked-rlib/Makefile | 1 + tests/run-make/test-harness/Makefile | 1 + tests/run-make/volatile-intrinsics/Makefile | 1 + tests/run-make/windows-subsystem/Makefile | 1 + 126 files changed, 127 insertions(+) diff --git a/tests/run-make/a-b-a-linker-guard/Makefile b/tests/run-make/a-b-a-linker-guard/Makefile index adc9e3d0916..43282eae09c 100644 --- a/tests/run-make/a-b-a-linker-guard/Makefile +++ b/tests/run-make/a-b-a-linker-guard/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # Test that if we build `b` against a version of `a` that has one set diff --git a/tests/run-make/allow-non-lint-warnings-cmdline/Makefile b/tests/run-make/allow-non-lint-warnings-cmdline/Makefile index 60d9c7c3745..78b9a7b9898 100644 --- a/tests/run-make/allow-non-lint-warnings-cmdline/Makefile +++ b/tests/run-make/allow-non-lint-warnings-cmdline/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # Test that -A warnings makes the 'empty trait list for derive' warning go away diff --git a/tests/run-make/allow-warnings-cmdline-stability/Makefile b/tests/run-make/allow-warnings-cmdline-stability/Makefile index 1ce8d0ec284..368a39af6bf 100644 --- a/tests/run-make/allow-warnings-cmdline-stability/Makefile +++ b/tests/run-make/allow-warnings-cmdline-stability/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # Test that -A warnings makes the 'empty trait list for derive' warning go away diff --git a/tests/run-make/archive-duplicate-names/Makefile b/tests/run-make/archive-duplicate-names/Makefile index bbdcd2a34fe..5433a42d252 100644 --- a/tests/run-make/archive-duplicate-names/Makefile +++ b/tests/run-make/archive-duplicate-names/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/arguments-non-c-like-enum/Makefile b/tests/run-make/arguments-non-c-like-enum/Makefile index 513311c8289..0c8d8bf3acc 100644 --- a/tests/run-make/arguments-non-c-like-enum/Makefile +++ b/tests/run-make/arguments-non-c-like-enum/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/bare-outfile/Makefile b/tests/run-make/bare-outfile/Makefile index 858466e942b..23b619ea0ba 100644 --- a/tests/run-make/bare-outfile/Makefile +++ b/tests/run-make/bare-outfile/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/c-dynamic-dylib/Makefile b/tests/run-make/c-dynamic-dylib/Makefile index ac68778922d..b5bfbc76539 100644 --- a/tests/run-make/c-dynamic-dylib/Makefile +++ b/tests/run-make/c-dynamic-dylib/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # ignore-macos diff --git a/tests/run-make/c-dynamic-rlib/Makefile b/tests/run-make/c-dynamic-rlib/Makefile index c65d648b929..0475bd8acae 100644 --- a/tests/run-make/c-dynamic-rlib/Makefile +++ b/tests/run-make/c-dynamic-rlib/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # ignore-macos diff --git a/tests/run-make/c-link-to-rust-dylib/Makefile b/tests/run-make/c-link-to-rust-dylib/Makefile index 2a371b54541..2763cb6ed1d 100644 --- a/tests/run-make/c-link-to-rust-dylib/Makefile +++ b/tests/run-make/c-link-to-rust-dylib/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: $(TMPDIR)/$(call BIN,bar) diff --git a/tests/run-make/c-link-to-rust-staticlib/Makefile b/tests/run-make/c-link-to-rust-staticlib/Makefile index d38bcef309a..e14775f5c18 100644 --- a/tests/run-make/c-link-to-rust-staticlib/Makefile +++ b/tests/run-make/c-link-to-rust-staticlib/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # ignore-freebsd diff --git a/tests/run-make/c-link-to-rust-va-list-fn/Makefile b/tests/run-make/c-link-to-rust-va-list-fn/Makefile index 9ce2a34e677..596c0fce3ce 100644 --- a/tests/run-make/c-link-to-rust-va-list-fn/Makefile +++ b/tests/run-make/c-link-to-rust-va-list-fn/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/c-static-dylib/Makefile b/tests/run-make/c-static-dylib/Makefile index 5b78005e3ee..4e23edb6c57 100644 --- a/tests/run-make/c-static-dylib/Makefile +++ b/tests/run-make/c-static-dylib/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: $(call NATIVE_STATICLIB,cfoo) diff --git a/tests/run-make/c-static-rlib/Makefile b/tests/run-make/c-static-rlib/Makefile index 11a3cf1940c..4e351127cb6 100644 --- a/tests/run-make/c-static-rlib/Makefile +++ b/tests/run-make/c-static-rlib/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: $(call NATIVE_STATICLIB,cfoo) diff --git a/tests/run-make/c-unwind-abi-catch-lib-panic/Makefile b/tests/run-make/c-unwind-abi-catch-lib-panic/Makefile index 134f000d453..9c41a5a717e 100644 --- a/tests/run-make/c-unwind-abi-catch-lib-panic/Makefile +++ b/tests/run-make/c-unwind-abi-catch-lib-panic/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: archive diff --git a/tests/run-make/c-unwind-abi-catch-panic/Makefile b/tests/run-make/c-unwind-abi-catch-panic/Makefile index e93ec99da2a..4398ac2ee24 100644 --- a/tests/run-make/c-unwind-abi-catch-panic/Makefile +++ b/tests/run-make/c-unwind-abi-catch-panic/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: $(call NATIVE_STATICLIB,add) diff --git a/tests/run-make/cdylib-dylib-linkage/Makefile b/tests/run-make/cdylib-dylib-linkage/Makefile index 5c9b2d1bb2f..51fbfef2d85 100644 --- a/tests/run-make/cdylib-dylib-linkage/Makefile +++ b/tests/run-make/cdylib-dylib-linkage/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk TARGET_SYSROOT := $(shell $(RUSTC) --print sysroot)/lib/rustlib/$(TARGET)/lib diff --git a/tests/run-make/cdylib-fewer-symbols/Makefile b/tests/run-make/cdylib-fewer-symbols/Makefile index 324791af8de..4e08f979c36 100644 --- a/tests/run-make/cdylib-fewer-symbols/Makefile +++ b/tests/run-make/cdylib-fewer-symbols/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile # Test that allocator-related symbols don't show up as exported from a cdylib as # they're internal to Rust and not part of the public ABI. diff --git a/tests/run-make/cdylib/Makefile b/tests/run-make/cdylib/Makefile index 47ec762b3e9..3c8b5269554 100644 --- a/tests/run-make/cdylib/Makefile +++ b/tests/run-make/cdylib/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: $(call RUN_BINFILE,foo) diff --git a/tests/run-make/codegen-options-parsing/Makefile b/tests/run-make/codegen-options-parsing/Makefile index b063593c9d9..56bb900b7d8 100644 --- a/tests/run-make/codegen-options-parsing/Makefile +++ b/tests/run-make/codegen-options-parsing/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/compile-stdin/Makefile b/tests/run-make/compile-stdin/Makefile index be15548690f..2a495281c24 100644 --- a/tests/run-make/compile-stdin/Makefile +++ b/tests/run-make/compile-stdin/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/crate-hash-rustc-version/Makefile b/tests/run-make/crate-hash-rustc-version/Makefile index cd5950e2bb3..f1d2a360410 100644 --- a/tests/run-make/crate-hash-rustc-version/Makefile +++ b/tests/run-make/crate-hash-rustc-version/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # Ensure that crates compiled with different rustc versions cannot diff --git a/tests/run-make/crate-name-priority/Makefile b/tests/run-make/crate-name-priority/Makefile index 08a07c325e3..4adaa75a71c 100644 --- a/tests/run-make/crate-name-priority/Makefile +++ b/tests/run-make/crate-name-priority/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/debug-assertions/Makefile b/tests/run-make/debug-assertions/Makefile index 73beb4b03ae..e83337c597f 100644 --- a/tests/run-make/debug-assertions/Makefile +++ b/tests/run-make/debug-assertions/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/doctests-keep-binaries/Makefile b/tests/run-make/doctests-keep-binaries/Makefile index 7bfff690b1f..6254e93d333 100644 --- a/tests/run-make/doctests-keep-binaries/Makefile +++ b/tests/run-make/doctests-keep-binaries/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # Check that valid binaries are persisted by running them, regardless of whether the --run or --no-run option is used. diff --git a/tests/run-make/dylib-chain/Makefile b/tests/run-make/dylib-chain/Makefile index 1139822f4ea..f1fea99c5ee 100644 --- a/tests/run-make/dylib-chain/Makefile +++ b/tests/run-make/dylib-chain/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/emit/Makefile b/tests/run-make/emit/Makefile index 78e68bd6111..b3ca0b79fb0 100644 --- a/tests/run-make/emit/Makefile +++ b/tests/run-make/emit/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/exit-code/Makefile b/tests/run-make/exit-code/Makefile index 3ffaafe9065..6458b71688f 100644 --- a/tests/run-make/exit-code/Makefile +++ b/tests/run-make/exit-code/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/extern-diff-internal-name/Makefile b/tests/run-make/extern-diff-internal-name/Makefile index 54596c2f029..250f82dfac0 100644 --- a/tests/run-make/extern-diff-internal-name/Makefile +++ b/tests/run-make/extern-diff-internal-name/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/extern-flag-disambiguates/Makefile b/tests/run-make/extern-flag-disambiguates/Makefile index a8f142a6402..e54a537ecd0 100644 --- a/tests/run-make/extern-flag-disambiguates/Makefile +++ b/tests/run-make/extern-flag-disambiguates/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # Attempt to build this dependency tree: diff --git a/tests/run-make/extern-flag-fun/Makefile b/tests/run-make/extern-flag-fun/Makefile index a0b7c15edb9..687cdfd7675 100644 --- a/tests/run-make/extern-flag-fun/Makefile +++ b/tests/run-make/extern-flag-fun/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/extern-flag-pathless/Makefile b/tests/run-make/extern-flag-pathless/Makefile index 0f23815b650..701bfcd28c8 100644 --- a/tests/run-make/extern-flag-pathless/Makefile +++ b/tests/run-make/extern-flag-pathless/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # Test mixing pathless --extern with paths. diff --git a/tests/run-make/extern-fn-generic/Makefile b/tests/run-make/extern-fn-generic/Makefile index 71746fb10cb..7dceea6cb88 100644 --- a/tests/run-make/extern-fn-generic/Makefile +++ b/tests/run-make/extern-fn-generic/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: $(call NATIVE_STATICLIB,test) diff --git a/tests/run-make/extern-fn-mangle/Makefile b/tests/run-make/extern-fn-mangle/Makefile index 4f5d026f213..3cbbf383996 100644 --- a/tests/run-make/extern-fn-mangle/Makefile +++ b/tests/run-make/extern-fn-mangle/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: $(call NATIVE_STATICLIB,test) diff --git a/tests/run-make/extern-fn-reachable/Makefile b/tests/run-make/extern-fn-reachable/Makefile index 05bdb8d65b7..3297251bfd1 100644 --- a/tests/run-make/extern-fn-reachable/Makefile +++ b/tests/run-make/extern-fn-reachable/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # ignore-windows-msvc diff --git a/tests/run-make/extern-fn-struct-passing-abi/Makefile b/tests/run-make/extern-fn-struct-passing-abi/Makefile index 4f5d026f213..3cbbf383996 100644 --- a/tests/run-make/extern-fn-struct-passing-abi/Makefile +++ b/tests/run-make/extern-fn-struct-passing-abi/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: $(call NATIVE_STATICLIB,test) diff --git a/tests/run-make/extern-fn-with-extern-types/Makefile b/tests/run-make/extern-fn-with-extern-types/Makefile index 1fa708950d4..07ec503aaae 100644 --- a/tests/run-make/extern-fn-with-extern-types/Makefile +++ b/tests/run-make/extern-fn-with-extern-types/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: $(call NATIVE_STATICLIB,ctest) diff --git a/tests/run-make/extern-fn-with-packed-struct/Makefile b/tests/run-make/extern-fn-with-packed-struct/Makefile index 4f5d026f213..3cbbf383996 100644 --- a/tests/run-make/extern-fn-with-packed-struct/Makefile +++ b/tests/run-make/extern-fn-with-packed-struct/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: $(call NATIVE_STATICLIB,test) diff --git a/tests/run-make/extern-fn-with-union/Makefile b/tests/run-make/extern-fn-with-union/Makefile index 40bae923e30..e6c8c993679 100644 --- a/tests/run-make/extern-fn-with-union/Makefile +++ b/tests/run-make/extern-fn-with-union/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: $(call NATIVE_STATICLIB,ctest) diff --git a/tests/run-make/extern-multiple-copies/Makefile b/tests/run-make/extern-multiple-copies/Makefile index 00668a6bc88..b0b84278eda 100644 --- a/tests/run-make/extern-multiple-copies/Makefile +++ b/tests/run-make/extern-multiple-copies/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/extern-multiple-copies2/Makefile b/tests/run-make/extern-multiple-copies2/Makefile index 84de2ebf34d..708b1c1b540 100644 --- a/tests/run-make/extern-multiple-copies2/Makefile +++ b/tests/run-make/extern-multiple-copies2/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/extern-overrides-distribution/Makefile b/tests/run-make/extern-overrides-distribution/Makefile index c57b062cd5d..bfd0dd6991b 100644 --- a/tests/run-make/extern-overrides-distribution/Makefile +++ b/tests/run-make/extern-overrides-distribution/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/extra-filename-with-temp-outputs/Makefile b/tests/run-make/extra-filename-with-temp-outputs/Makefile index 470448cf50c..64745bef5b8 100644 --- a/tests/run-make/extra-filename-with-temp-outputs/Makefile +++ b/tests/run-make/extra-filename-with-temp-outputs/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/foreign-double-unwind/Makefile b/tests/run-make/foreign-double-unwind/Makefile index ea2fe9ff881..f20fe3ce66e 100644 --- a/tests/run-make/foreign-double-unwind/Makefile +++ b/tests/run-make/foreign-double-unwind/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: foo diff --git a/tests/run-make/foreign-exceptions/Makefile b/tests/run-make/foreign-exceptions/Makefile index 38fe2773df2..a8e20ffb1f4 100644 --- a/tests/run-make/foreign-exceptions/Makefile +++ b/tests/run-make/foreign-exceptions/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: foo diff --git a/tests/run-make/foreign-rust-exceptions/Makefile b/tests/run-make/foreign-rust-exceptions/Makefile index 50fca7f24e6..0d007bf1c49 100644 --- a/tests/run-make/foreign-rust-exceptions/Makefile +++ b/tests/run-make/foreign-rust-exceptions/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile # ignore-i686-pc-windows-gnu # This test doesn't work on 32-bit MinGW as cdylib has its own copy of unwinder diff --git a/tests/run-make/fpic/Makefile b/tests/run-make/fpic/Makefile index 5986de3666f..c38dd8d6e8c 100644 --- a/tests/run-make/fpic/Makefile +++ b/tests/run-make/fpic/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # ignore-windows diff --git a/tests/run-make/glibc-staticlib-args/Makefile b/tests/run-make/glibc-staticlib-args/Makefile index 39e64bacf58..cad6c049e45 100644 --- a/tests/run-make/glibc-staticlib-args/Makefile +++ b/tests/run-make/glibc-staticlib-args/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile # only-gnu # only-linux diff --git a/tests/run-make/incr-add-rust-src-component/Makefile b/tests/run-make/incr-add-rust-src-component/Makefile index 5c1d953cc05..fd09c2299f9 100644 --- a/tests/run-make/incr-add-rust-src-component/Makefile +++ b/tests/run-make/incr-add-rust-src-component/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # rust-lang/rust#70924: Test that if we add rust-src component in between two diff --git a/tests/run-make/interdependent-c-libraries/Makefile b/tests/run-make/interdependent-c-libraries/Makefile index dc5b55a9925..53a696d82bf 100644 --- a/tests/run-make/interdependent-c-libraries/Makefile +++ b/tests/run-make/interdependent-c-libraries/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # The rust crate foo will link to the native library foo, while the rust crate diff --git a/tests/run-make/issue-11908/Makefile b/tests/run-make/issue-11908/Makefile index 47005537e41..38586662fc7 100644 --- a/tests/run-make/issue-11908/Makefile +++ b/tests/run-make/issue-11908/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile # This test ensures that if you have the same rlib or dylib at two locations # in the same path that you don't hit an assertion in the compiler. # diff --git a/tests/run-make/issue-14500/Makefile b/tests/run-make/issue-14500/Makefile index 52550e57018..eeab48de3b9 100644 --- a/tests/run-make/issue-14500/Makefile +++ b/tests/run-make/issue-14500/Makefile @@ -1,5 +1,7 @@ include ../tools.mk +# ignore-cross-compile + # Test to make sure that reachable extern fns are always available in final # productcs, including when LTO is used. In this test, the `foo` crate has a # reahable symbol, and is a dependency of the `bar` crate. When the `bar` crate diff --git a/tests/run-make/issue-15460/Makefile b/tests/run-make/issue-15460/Makefile index 1648d0c0c9b..a36a085fa6f 100644 --- a/tests/run-make/issue-15460/Makefile +++ b/tests/run-make/issue-15460/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: $(call NATIVE_STATICLIB,foo) diff --git a/tests/run-make/issue-20626/Makefile b/tests/run-make/issue-20626/Makefile index f76f31e794a..63eee910a9c 100644 --- a/tests/run-make/issue-20626/Makefile +++ b/tests/run-make/issue-20626/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # Test output to be four diff --git a/tests/run-make/issue-22131/Makefile b/tests/run-make/issue-22131/Makefile index 770f4b04ec3..4f33a4659cc 100644 --- a/tests/run-make/issue-22131/Makefile +++ b/tests/run-make/issue-22131/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: foo.rs diff --git a/tests/run-make/issue-24445/Makefile b/tests/run-make/issue-24445/Makefile index 2a12226a6c0..a13910aa73e 100644 --- a/tests/run-make/issue-24445/Makefile +++ b/tests/run-make/issue-24445/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # only-linux diff --git a/tests/run-make/issue-25581/Makefile b/tests/run-make/issue-25581/Makefile index 4f5d026f213..3cbbf383996 100644 --- a/tests/run-make/issue-25581/Makefile +++ b/tests/run-make/issue-25581/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: $(call NATIVE_STATICLIB,test) diff --git a/tests/run-make/issue-26006/Makefile b/tests/run-make/issue-26006/Makefile index 0ff07302002..b679c121530 100644 --- a/tests/run-make/issue-26006/Makefile +++ b/tests/run-make/issue-26006/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # ignore-windows diff --git a/tests/run-make/issue-28595/Makefile b/tests/run-make/issue-28595/Makefile index 30a1d9c560a..258f9788aaf 100644 --- a/tests/run-make/issue-28595/Makefile +++ b/tests/run-make/issue-28595/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: $(call NATIVE_STATICLIB,a) $(call NATIVE_STATICLIB,b) diff --git a/tests/run-make/issue-30063/Makefile b/tests/run-make/issue-30063/Makefile index e4ede598f7b..8a69ca79f51 100644 --- a/tests/run-make/issue-30063/Makefile +++ b/tests/run-make/issue-30063/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/issue-36710/Makefile b/tests/run-make/issue-36710/Makefile index c3de474fbbe..7b91107a234 100644 --- a/tests/run-make/issue-36710/Makefile +++ b/tests/run-make/issue-36710/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile # ignore-none no-std is not supported # ignore-wasm32 FIXME: don't attempt to compile C++ to WASM # ignore-wasm64 FIXME: don't attempt to compile C++ to WASM diff --git a/tests/run-make/issue-37839/Makefile b/tests/run-make/issue-37839/Makefile index de50bd71379..6bad27b7bdc 100644 --- a/tests/run-make/issue-37839/Makefile +++ b/tests/run-make/issue-37839/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/issue-37893/Makefile b/tests/run-make/issue-37893/Makefile index 33a60830e5d..44e4a321a30 100644 --- a/tests/run-make/issue-37893/Makefile +++ b/tests/run-make/issue-37893/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/issue-38237/Makefile b/tests/run-make/issue-38237/Makefile index 75121d04012..80dddc5bd13 100644 --- a/tests/run-make/issue-38237/Makefile +++ b/tests/run-make/issue-38237/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/issue-46239/Makefile b/tests/run-make/issue-46239/Makefile index a93ef321298..0006ced2515 100644 --- a/tests/run-make/issue-46239/Makefile +++ b/tests/run-make/issue-46239/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/issue-68794-textrel-on-minimal-lib/Makefile b/tests/run-make/issue-68794-textrel-on-minimal-lib/Makefile index 13983f4ffe0..6140b39c0e2 100644 --- a/tests/run-make/issue-68794-textrel-on-minimal-lib/Makefile +++ b/tests/run-make/issue-68794-textrel-on-minimal-lib/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile # Regression test for issue #68794 # # Verify that no text relocations are accidentally introduced by linking a diff --git a/tests/run-make/issue-69368/Makefile b/tests/run-make/issue-69368/Makefile index 41770475db0..b1229d1b07f 100644 --- a/tests/run-make/issue-69368/Makefile +++ b/tests/run-make/issue-69368/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # Test that previously triggered a linker failure with root cause diff --git a/tests/run-make/issue-97463-abi-param-passing/Makefile b/tests/run-make/issue-97463-abi-param-passing/Makefile index b4ff88d1957..7ce7aaeec57 100644 --- a/tests/run-make/issue-97463-abi-param-passing/Makefile +++ b/tests/run-make/issue-97463-abi-param-passing/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # ignore-msvc diff --git a/tests/run-make/issue64319/Makefile b/tests/run-make/issue64319/Makefile index f852fdf2d05..56346cbcc15 100644 --- a/tests/run-make/issue64319/Makefile +++ b/tests/run-make/issue64319/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # Different optimization levels imply different values for `-Zshare-generics`, diff --git a/tests/run-make/libs-through-symlinks/Makefile b/tests/run-make/libs-through-symlinks/Makefile index 45deaecb840..592eae663a4 100644 --- a/tests/run-make/libs-through-symlinks/Makefile +++ b/tests/run-make/libs-through-symlinks/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # ignore-windows diff --git a/tests/run-make/libtest-json/Makefile b/tests/run-make/libtest-json/Makefile index 37b6cb9e2d4..417637cf072 100644 --- a/tests/run-make/libtest-json/Makefile +++ b/tests/run-make/libtest-json/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # Test expected libtest's JSON output diff --git a/tests/run-make/link-cfg/Makefile b/tests/run-make/link-cfg/Makefile index 0b25ccded06..a4099701144 100644 --- a/tests/run-make/link-cfg/Makefile +++ b/tests/run-make/link-cfg/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: $(call DYLIB,return1) $(call DYLIB,return2) $(call NATIVE_STATICLIB,return3) diff --git a/tests/run-make/link-path-order/Makefile b/tests/run-make/link-path-order/Makefile index ed7c299e61a..a3831a63ac7 100644 --- a/tests/run-make/link-path-order/Makefile +++ b/tests/run-make/link-path-order/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # Verifies that the -L arguments given to the linker is in the same order diff --git a/tests/run-make/linkage-attr-on-static/Makefile b/tests/run-make/linkage-attr-on-static/Makefile index 7cc54e40a3a..ef50a7ef9f1 100644 --- a/tests/run-make/linkage-attr-on-static/Makefile +++ b/tests/run-make/linkage-attr-on-static/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: $(call NATIVE_STATICLIB,foo) diff --git a/tests/run-make/long-linker-command-lines-cmd-exe/Makefile b/tests/run-make/long-linker-command-lines-cmd-exe/Makefile index a38f4fe5dc5..e43aab7f8e0 100644 --- a/tests/run-make/long-linker-command-lines-cmd-exe/Makefile +++ b/tests/run-make/long-linker-command-lines-cmd-exe/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/long-linker-command-lines/Makefile b/tests/run-make/long-linker-command-lines/Makefile index 00199ca970d..f864ea74f4a 100644 --- a/tests/run-make/long-linker-command-lines/Makefile +++ b/tests/run-make/long-linker-command-lines/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/longjmp-across-rust/Makefile b/tests/run-make/longjmp-across-rust/Makefile index 848638d82dd..5fd2d4f855f 100644 --- a/tests/run-make/longjmp-across-rust/Makefile +++ b/tests/run-make/longjmp-across-rust/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: $(call NATIVE_STATICLIB,foo) diff --git a/tests/run-make/ls-metadata/Makefile b/tests/run-make/ls-metadata/Makefile index e0f916a248e..123dd64e15c 100644 --- a/tests/run-make/ls-metadata/Makefile +++ b/tests/run-make/ls-metadata/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/lto-dylib-dep/Makefile b/tests/run-make/lto-dylib-dep/Makefile index 41487b23c74..a9344597d08 100644 --- a/tests/run-make/lto-dylib-dep/Makefile +++ b/tests/run-make/lto-dylib-dep/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # Test that we don't run into an assertion when using a Rust dylib dependency diff --git a/tests/run-make/lto-empty/Makefile b/tests/run-make/lto-empty/Makefile index b4345ba1883..1b795c4b738 100644 --- a/tests/run-make/lto-empty/Makefile +++ b/tests/run-make/lto-empty/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: cdylib-fat cdylib-thin diff --git a/tests/run-make/lto-no-link-whole-rlib/Makefile b/tests/run-make/lto-no-link-whole-rlib/Makefile index e576ee37cf7..3e82322e72d 100644 --- a/tests/run-make/lto-no-link-whole-rlib/Makefile +++ b/tests/run-make/lto-no-link-whole-rlib/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: $(call NATIVE_STATICLIB,foo) $(call NATIVE_STATICLIB,bar) diff --git a/tests/run-make/lto-readonly-lib/Makefile b/tests/run-make/lto-readonly-lib/Makefile index a20ecea88ea..11d944e3e3d 100644 --- a/tests/run-make/lto-readonly-lib/Makefile +++ b/tests/run-make/lto-readonly-lib/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/lto-smoke-c/Makefile b/tests/run-make/lto-smoke-c/Makefile index 7c6ee3be849..f1ba3d95da2 100644 --- a/tests/run-make/lto-smoke-c/Makefile +++ b/tests/run-make/lto-smoke-c/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # Apparently older versions of GCC segfault if -g is passed... diff --git a/tests/run-make/lto-smoke/Makefile b/tests/run-make/lto-smoke/Makefile index 8bce708b44b..13a09fce734 100644 --- a/tests/run-make/lto-smoke/Makefile +++ b/tests/run-make/lto-smoke/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: noparam bool_true bool_false thin fat diff --git a/tests/run-make/manual-link/Makefile b/tests/run-make/manual-link/Makefile index 401f6eb440a..8dbf0460fff 100644 --- a/tests/run-make/manual-link/Makefile +++ b/tests/run-make/manual-link/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: $(TMPDIR)/libbar.a diff --git a/tests/run-make/metadata-flag-frobs-symbols/Makefile b/tests/run-make/metadata-flag-frobs-symbols/Makefile index dc6b10f4e9d..53d7d065769 100644 --- a/tests/run-make/metadata-flag-frobs-symbols/Makefile +++ b/tests/run-make/metadata-flag-frobs-symbols/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/mixing-deps/Makefile b/tests/run-make/mixing-deps/Makefile index 956e704ee16..c2a5a2a0abb 100644 --- a/tests/run-make/mixing-deps/Makefile +++ b/tests/run-make/mixing-deps/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/mixing-formats/Makefile b/tests/run-make/mixing-formats/Makefile index b27e54257f9..d01978a1599 100644 --- a/tests/run-make/mixing-formats/Makefile +++ b/tests/run-make/mixing-formats/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # Testing various mixings of rlibs and dylibs. Makes sure that it's possible to diff --git a/tests/run-make/mixing-libs/Makefile b/tests/run-make/mixing-libs/Makefile index 39cc0708ca1..e8262b28401 100644 --- a/tests/run-make/mixing-libs/Makefile +++ b/tests/run-make/mixing-libs/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/msvc-opt-minsize/Makefile b/tests/run-make/msvc-opt-minsize/Makefile index a5f019f244e..32e6e28018f 100644 --- a/tests/run-make/msvc-opt-minsize/Makefile +++ b/tests/run-make/msvc-opt-minsize/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/no-duplicate-libs/Makefile b/tests/run-make/no-duplicate-libs/Makefile index b05aff7826e..4be8c026294 100644 --- a/tests/run-make/no-duplicate-libs/Makefile +++ b/tests/run-make/no-duplicate-libs/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk ifdef IS_MSVC diff --git a/tests/run-make/no-intermediate-extras/Makefile b/tests/run-make/no-intermediate-extras/Makefile index 4116aac1b8f..83b5cedcf2a 100644 --- a/tests/run-make/no-intermediate-extras/Makefile +++ b/tests/run-make/no-intermediate-extras/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile # Regression test for issue #10973 include ../tools.mk diff --git a/tests/run-make/obey-crate-type-flag/Makefile b/tests/run-make/obey-crate-type-flag/Makefile index effcfc94cc5..ecbb2e620ed 100644 --- a/tests/run-make/obey-crate-type-flag/Makefile +++ b/tests/run-make/obey-crate-type-flag/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # check that rustc builds all crate_type attributes diff --git a/tests/run-make/output-filename-overwrites-input/Makefile b/tests/run-make/output-filename-overwrites-input/Makefile index 33069c06f5a..605b86b253e 100644 --- a/tests/run-make/output-filename-overwrites-input/Makefile +++ b/tests/run-make/output-filename-overwrites-input/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/output-type-permutations/Makefile b/tests/run-make/output-type-permutations/Makefile index 791606c643b..035033b9fdd 100644 --- a/tests/run-make/output-type-permutations/Makefile +++ b/tests/run-make/output-type-permutations/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/output-with-hyphens/Makefile b/tests/run-make/output-with-hyphens/Makefile index 365fb6e591a..846c9a66a89 100644 --- a/tests/run-make/output-with-hyphens/Makefile +++ b/tests/run-make/output-with-hyphens/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/override-aliased-flags/Makefile b/tests/run-make/override-aliased-flags/Makefile index 186b8c7c85e..db1ff1ff981 100644 --- a/tests/run-make/override-aliased-flags/Makefile +++ b/tests/run-make/override-aliased-flags/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # FIXME: it would be good to check that it's actually the rightmost flags diff --git a/tests/run-make/pass-non-c-like-enum-to-c/Makefile b/tests/run-make/pass-non-c-like-enum-to-c/Makefile index 42d3c977f75..bd441d321bf 100644 --- a/tests/run-make/pass-non-c-like-enum-to-c/Makefile +++ b/tests/run-make/pass-non-c-like-enum-to-c/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: $(call NATIVE_STATICLIB,test) diff --git a/tests/run-make/prefer-dylib/Makefile b/tests/run-make/prefer-dylib/Makefile index 3817ca195eb..cc26e70ae67 100644 --- a/tests/run-make/prefer-dylib/Makefile +++ b/tests/run-make/prefer-dylib/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/prefer-rlib/Makefile b/tests/run-make/prefer-rlib/Makefile index adc345d760d..2e86b9c1dd7 100644 --- a/tests/run-make/prefer-rlib/Makefile +++ b/tests/run-make/prefer-rlib/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/prune-link-args/Makefile b/tests/run-make/prune-link-args/Makefile index a359dc5aef1..c21ba6ace38 100644 --- a/tests/run-make/prune-link-args/Makefile +++ b/tests/run-make/prune-link-args/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # ignore-windows diff --git a/tests/run-make/redundant-libs/Makefile b/tests/run-make/redundant-libs/Makefile index b2dff05d163..0a48b2b2801 100644 --- a/tests/run-make/redundant-libs/Makefile +++ b/tests/run-make/redundant-libs/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # ignore-windows-msvc diff --git a/tests/run-make/relocation-model/Makefile b/tests/run-make/relocation-model/Makefile index a31dbfd9167..8cc5205ed51 100644 --- a/tests/run-make/relocation-model/Makefile +++ b/tests/run-make/relocation-model/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: others diff --git a/tests/run-make/relro-levels/Makefile b/tests/run-make/relro-levels/Makefile index 6176fc1a589..e0402f59f12 100644 --- a/tests/run-make/relro-levels/Makefile +++ b/tests/run-make/relro-levels/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # only-linux diff --git a/tests/run-make/reproducible-build-2/Makefile b/tests/run-make/reproducible-build-2/Makefile index 1df5e102ce3..68fcac8b47f 100644 --- a/tests/run-make/reproducible-build-2/Makefile +++ b/tests/run-make/reproducible-build-2/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # ignore-musl diff --git a/tests/run-make/reproducible-build/Makefile b/tests/run-make/reproducible-build/Makefile index 642a480815b..f5d17a234c0 100644 --- a/tests/run-make/reproducible-build/Makefile +++ b/tests/run-make/reproducible-build/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # ignore-musl diff --git a/tests/run-make/return-non-c-like-enum-from-c/Makefile b/tests/run-make/return-non-c-like-enum-from-c/Makefile index 42d3c977f75..bd441d321bf 100644 --- a/tests/run-make/return-non-c-like-enum-from-c/Makefile +++ b/tests/run-make/return-non-c-like-enum-from-c/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: $(call NATIVE_STATICLIB,test) diff --git a/tests/run-make/return-non-c-like-enum/Makefile b/tests/run-make/return-non-c-like-enum/Makefile index 513311c8289..0c8d8bf3acc 100644 --- a/tests/run-make/return-non-c-like-enum/Makefile +++ b/tests/run-make/return-non-c-like-enum/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/rlib-chain/Makefile b/tests/run-make/rlib-chain/Makefile index 236943a2a3b..7a1f887fa52 100644 --- a/tests/run-make/rlib-chain/Makefile +++ b/tests/run-make/rlib-chain/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/rustdoc-scrape-examples-macros/Makefile b/tests/run-make/rustdoc-scrape-examples-macros/Makefile index 3cc6dcac366..edc19d8cb5d 100644 --- a/tests/run-make/rustdoc-scrape-examples-macros/Makefile +++ b/tests/run-make/rustdoc-scrape-examples-macros/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../../run-make/tools.mk OUTPUT_DIR := "$(TMPDIR)/rustdoc" diff --git a/tests/run-make/separate-link/Makefile b/tests/run-make/separate-link/Makefile index 3ccdb6275d1..d01158d9f5f 100644 --- a/tests/run-make/separate-link/Makefile +++ b/tests/run-make/separate-link/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/share-generics-dylib/Makefile b/tests/run-make/share-generics-dylib/Makefile index 5fea91bb4c2..9d97eca80d3 100644 --- a/tests/run-make/share-generics-dylib/Makefile +++ b/tests/run-make/share-generics-dylib/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile # This test makes sure all generic instances get re-exported from Rust dylibs for use by # `-Zshare-generics`. There are two rlibs (`instance_provider_a` and `instance_provider_b`) # which both provide an instance of `Cell::set`. There is `instance_user_dylib` which is diff --git a/tests/run-make/simple-dylib/Makefile b/tests/run-make/simple-dylib/Makefile index 5dda5d66d1c..f3e1c1da88c 100644 --- a/tests/run-make/simple-dylib/Makefile +++ b/tests/run-make/simple-dylib/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: $(RUSTC) bar.rs --crate-type=dylib -C prefer-dynamic diff --git a/tests/run-make/simple-rlib/Makefile b/tests/run-make/simple-rlib/Makefile index d912b8a7bab..28df61a1547 100644 --- a/tests/run-make/simple-rlib/Makefile +++ b/tests/run-make/simple-rlib/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: $(RUSTC) bar.rs --crate-type=rlib diff --git a/tests/run-make/split-debuginfo/Makefile b/tests/run-make/split-debuginfo/Makefile index 44cda0d3d11..71e014c1f71 100644 --- a/tests/run-make/split-debuginfo/Makefile +++ b/tests/run-make/split-debuginfo/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: off packed unpacked diff --git a/tests/run-make/static-dylib-by-default/Makefile b/tests/run-make/static-dylib-by-default/Makefile index eedd0b32092..cdaab42d06c 100644 --- a/tests/run-make/static-dylib-by-default/Makefile +++ b/tests/run-make/static-dylib-by-default/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk TO_LINK := $(call DYLIB,bar) diff --git a/tests/run-make/static-extern-type/Makefile b/tests/run-make/static-extern-type/Makefile index e9aa95e63a0..77897154322 100644 --- a/tests/run-make/static-extern-type/Makefile +++ b/tests/run-make/static-extern-type/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: $(call NATIVE_STATICLIB,define-foo) diff --git a/tests/run-make/static-unwinding/Makefile b/tests/run-make/static-unwinding/Makefile index 9c755d4ab18..dec94fb16f4 100644 --- a/tests/run-make/static-unwinding/Makefile +++ b/tests/run-make/static-unwinding/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/std-core-cycle/Makefile b/tests/run-make/std-core-cycle/Makefile index 4f252863767..5ed6be905df 100644 --- a/tests/run-make/std-core-cycle/Makefile +++ b/tests/run-make/std-core-cycle/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk ifeq ($(UNAME),Darwin) diff --git a/tests/run-make/suspicious-library/Makefile b/tests/run-make/suspicious-library/Makefile index 2af9e85c228..3b5ab3c53a5 100644 --- a/tests/run-make/suspicious-library/Makefile +++ b/tests/run-make/suspicious-library/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/symbol-visibility/Makefile b/tests/run-make/symbol-visibility/Makefile index 17052ef4e63..9159af214ca 100644 --- a/tests/run-make/symbol-visibility/Makefile +++ b/tests/run-make/symbol-visibility/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # ignore-windows-msvc diff --git a/tests/run-make/symlinked-extern/Makefile b/tests/run-make/symlinked-extern/Makefile index 058f43e857a..28c764b84e8 100644 --- a/tests/run-make/symlinked-extern/Makefile +++ b/tests/run-make/symlinked-extern/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # ignore-windows diff --git a/tests/run-make/symlinked-libraries/Makefile b/tests/run-make/symlinked-libraries/Makefile index 576bf7e54be..fb0b6127e6f 100644 --- a/tests/run-make/symlinked-libraries/Makefile +++ b/tests/run-make/symlinked-libraries/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # ignore-windows diff --git a/tests/run-make/symlinked-rlib/Makefile b/tests/run-make/symlinked-rlib/Makefile index 49d3f220a35..a8565f683c3 100644 --- a/tests/run-make/symlinked-rlib/Makefile +++ b/tests/run-make/symlinked-rlib/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk # ignore-windows diff --git a/tests/run-make/test-harness/Makefile b/tests/run-make/test-harness/Makefile index 1fe059b07d2..ee8c9294f91 100644 --- a/tests/run-make/test-harness/Makefile +++ b/tests/run-make/test-harness/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/volatile-intrinsics/Makefile b/tests/run-make/volatile-intrinsics/Makefile index 2a78c7b9cfe..5672a045873 100644 --- a/tests/run-make/volatile-intrinsics/Makefile +++ b/tests/run-make/volatile-intrinsics/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: diff --git a/tests/run-make/windows-subsystem/Makefile b/tests/run-make/windows-subsystem/Makefile index 78c4e2ac1e8..e3cf9181de4 100644 --- a/tests/run-make/windows-subsystem/Makefile +++ b/tests/run-make/windows-subsystem/Makefile @@ -1,3 +1,4 @@ +# ignore-cross-compile include ../tools.mk all: From 1f9e2d0538bf7b4271498654df14a06b7ced8bdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrik=20K=C3=A5rlin?= Date: Thu, 30 Mar 2023 15:46:34 +0200 Subject: [PATCH 292/346] rustdoc: tidy excess whitespace --- tests/rustdoc-ui/issue-105742.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/rustdoc-ui/issue-105742.rs b/tests/rustdoc-ui/issue-105742.rs index dd79f0fac82..8f4172c0cbb 100644 --- a/tests/rustdoc-ui/issue-105742.rs +++ b/tests/rustdoc-ui/issue-105742.rs @@ -6,7 +6,7 @@ pub fn next<'a, T>(s: &'a mut dyn SVec) { //~| expected 1 generic argument //~| the trait `SVec` cannot be made into an object //~| `SVec` cannot be made into an object - //~| missing generics for associated type `SVec::Item` + //~| missing generics for associated type `SVec::Item` //~| missing generics for associated type `SVec::Item` let _ = s; } @@ -14,7 +14,7 @@ pub fn next<'a, T>(s: &'a mut dyn SVec) { pub trait SVec: Index< ::Item, //~^ expected 1 lifetime argument - //~| expected 1 generic argument + //~| expected 1 generic argument //~| missing generics for associated type `SVec::Item` //~| missing generics for associated type `SVec::Item` //~| missing generics for associated type `SVec::Item` @@ -22,14 +22,14 @@ pub trait SVec: Index< Output = ::Item, //~^ expected 1 lifetime argument //~| expected 1 generic argument - //~| missing generics for associated type `SVec::Item` + //~| missing generics for associated type `SVec::Item` //~| missing generics for associated type `SVec::Item` //~| missing generics for associated type `SVec::Item` //~| missing generics for associated type `SVec::Item` Output = ::Item> as SVec>::Item, //~^ expected 1 lifetime argument //~| expected 1 generic argument - //~| expected 1 lifetime argument + //~| expected 1 lifetime argument //~| missing generics for associated type `SVec::Item` //~| missing generics for associated type `SVec::Item` //~| missing generics for associated type `SVec::Item` From 177997e3833d48973e7856e14f2935340b1862f1 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 29 Mar 2023 23:36:27 +0000 Subject: [PATCH 293/346] Closures always implement FnOnce in new solver --- .../src/solve/trait_goals/structural_traits.rs | 17 ++++++++++++++--- .../new-solver/closure-inference-guidance.rs | 11 +++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 tests/ui/traits/new-solver/closure-inference-guidance.rs diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs index 9817186b874..fcb965dd725 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs @@ -214,9 +214,20 @@ pub(crate) fn extract_tupled_inputs_and_output_from_callable<'tcx>( ty::Closure(_, substs) => { let closure_substs = substs.as_closure(); match closure_substs.kind_ty().to_opt_closure_kind() { - Some(closure_kind) if closure_kind.extends(goal_kind) => {} - None => return Ok(None), - _ => return Err(NoSolution), + // If the closure's kind doesn't extend the goal kind, + // then the closure doesn't implement the trait. + Some(closure_kind) => { + if !closure_kind.extends(goal_kind) { + return Err(NoSolution); + } + } + // Closure kind is not yet determined, so we return ambiguity unless + // the expected kind is `FnOnce` as that is always implemented. + None => { + if goal_kind != ty::ClosureKind::FnOnce { + return Ok(None); + } + } } Ok(Some(closure_substs.sig().map_bound(|sig| (sig.inputs()[0], sig.output())))) } diff --git a/tests/ui/traits/new-solver/closure-inference-guidance.rs b/tests/ui/traits/new-solver/closure-inference-guidance.rs new file mode 100644 index 00000000000..d2ad0cc0316 --- /dev/null +++ b/tests/ui/traits/new-solver/closure-inference-guidance.rs @@ -0,0 +1,11 @@ +// compile-flags: -Ztrait-solver=next +// check-pass + +fn foo(i: isize) -> isize { i + 1 } + +fn apply(f: F, v: A) -> A where F: FnOnce(A) -> A { f(v) } + +pub fn main() { + let f = |i| foo(i); + assert_eq!(apply(f, 2), 3); +} From 4abb45552992da2c30df9626c1b522b3d10f789b Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Tue, 28 Mar 2023 23:32:25 -0700 Subject: [PATCH 294/346] Update `ty::VariantDef` to use `IndexVec` And while doing the updates for that, also uses `FieldIdx` in `ProjectionKind::Field` and `TypeckResults::field_indices`. There's more places that could use it (like `rustc_const_eval` and `LayoutS`), but I tried to keep this PR from exploding to *even more* places. Part 2/? of https://github.com/rust-lang/compiler-team/issues/606 --- .../rustc_borrowck/src/diagnostics/mod.rs | 2 +- compiler/rustc_borrowck/src/type_check/mod.rs | 5 +++-- .../src/value_and_place.rs | 3 ++- .../src/debuginfo/metadata/enums/mod.rs | 3 ++- .../src/const_eval/valtrees.rs | 3 ++- .../src/interpret/validity.rs | 10 +++++++--- .../src/transform/validate.rs | 2 +- .../rustc_hir_analysis/src/check/check.rs | 5 +++-- .../src/check/intrinsicck.rs | 3 ++- .../rustc_hir_analysis/src/check/wfcheck.rs | 4 ++-- .../src/coherence/builtin.rs | 3 +-- compiler/rustc_hir_typeck/src/cast.rs | 14 +++++++------ compiler/rustc_hir_typeck/src/demand.rs | 3 ++- compiler/rustc_hir_typeck/src/expr.rs | 20 +++++++++---------- .../rustc_hir_typeck/src/expr_use_visitor.rs | 4 ++-- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 3 ++- compiler/rustc_hir_typeck/src/intrinsicck.rs | 4 ++-- .../src/mem_categorization.rs | 12 ++++++----- .../rustc_hir_typeck/src/method/suggest.rs | 2 +- compiler/rustc_hir_typeck/src/pat.rs | 12 ++++++----- compiler/rustc_hir_typeck/src/upvar.rs | 6 +++--- .../src/infer/error_reporting/suggest.rs | 3 ++- compiler/rustc_lint/src/types.rs | 2 +- compiler/rustc_middle/src/hir/place.rs | 4 ++-- compiler/rustc_middle/src/mir/tcx.rs | 2 +- compiler/rustc_middle/src/thir.rs | 2 +- compiler/rustc_middle/src/ty/adjustment.rs | 3 ++- compiler/rustc_middle/src/ty/closure.rs | 8 ++++---- compiler/rustc_middle/src/ty/layout.rs | 6 +++--- compiler/rustc_middle/src/ty/mod.rs | 15 +++++++------- compiler/rustc_middle/src/ty/sty.rs | 4 ++-- .../rustc_middle/src/ty/typeck_results.rs | 11 +++++----- compiler/rustc_middle/src/ty/util.rs | 4 ++-- .../src/build/expr/as_place.rs | 2 +- compiler/rustc_mir_build/src/thir/cx/expr.rs | 6 +++--- .../rustc_mir_build/src/thir/pattern/mod.rs | 2 +- .../rustc_mir_dataflow/src/elaborate_drops.rs | 6 +++--- .../src/elaborate_box_derefs.rs | 5 +++-- compiler/rustc_mir_transform/src/inline.rs | 2 +- compiler/rustc_monomorphize/src/collector.rs | 3 ++- compiler/rustc_passes/src/dead.rs | 3 ++- compiler/rustc_privacy/src/lib.rs | 2 +- .../src/solve/project_goals.rs | 2 +- .../src/solve/trait_goals.rs | 1 + .../src/traits/select/confirmation.rs | 1 + compiler/rustc_ty_utils/src/layout.rs | 5 +++-- compiler/rustc_ty_utils/src/ty.rs | 4 ++-- 47 files changed, 127 insertions(+), 104 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 5827fa81cff..da0456856ac 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -350,7 +350,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if !including_tuple_field.0 && variant.ctor_kind() == Some(CtorKind::Fn) { return None; } - Some(variant.fields[field.index()].name.to_string()) + Some(variant.fields[field].name.to_string()) } ty::Tuple(_) => Some(field.index().to_string()), ty::Ref(_, ty, _) | ty::RawPtr(ty::TypeAndMut { ty, .. }) => { diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 04da6d6beff..10bbce37760 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -854,7 +854,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { }, }; - if let Some(field) = variant.fields.get(field.index()) { + if let Some(field) = variant.fields.get(field) { Ok(self.cx.normalize(field.ty(tcx, substs), location)) } else { Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() }) @@ -1725,7 +1725,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { AggregateKind::Adt(adt_did, variant_index, substs, _, active_field_index) => { let def = tcx.adt_def(adt_did); let variant = &def.variant(variant_index); - let adj_field_index = active_field_index.unwrap_or(field_index); + let adj_field_index = + FieldIdx::from_usize(active_field_index.unwrap_or(field_index)); if let Some(field) = variant.fields.get(adj_field_index) { Ok(self.normalize(field.ty(tcx, substs), location)) } else { diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs index ffe3ccb0eca..1b69862ce2c 100644 --- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs +++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs @@ -701,7 +701,8 @@ impl<'tcx> CPlace<'tcx> { }; } ty::Adt(adt_def, substs) if layout.ty.is_simd() => { - let f0_ty = adt_def.non_enum_variant().fields[0].ty(fx.tcx, substs); + let f0 = &adt_def.non_enum_variant().fields[FieldIdx::from_u32(0)]; + let f0_ty = f0.ty(fx.tcx, substs); match f0_ty.kind() { ty::Array(_, _) => { diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs index 3e4765fba57..c3439591b92 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs @@ -274,7 +274,8 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>( .map(|field_index| { let field_name = if variant_def.ctor_kind() != Some(CtorKind::Fn) { // Fields have names - Cow::from(variant_def.fields[field_index].name.as_str()) + let field = &variant_def.fields[FieldIdx::from_usize(field_index)]; + Cow::from(field.name.as_str()) } else { // Tuple-like super::tuple_field_name(field_index) diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index 8e4454d7cec..4d54c01830b 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -8,7 +8,7 @@ use crate::interpret::{ use crate::interpret::{MPlaceTy, Value}; use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt}; use rustc_span::source_map::DUMMY_SP; -use rustc_target::abi::{Align, VariantIdx, FIRST_VARIANT}; +use rustc_target::abi::{Align, FieldIdx, VariantIdx, FIRST_VARIANT}; #[instrument(skip(ecx), level = "debug")] fn branches<'tcx>( @@ -412,6 +412,7 @@ fn valtree_into_mplace<'tcx>( let inner_ty = match ty.kind() { ty::Adt(def, substs) => { + let i = FieldIdx::from_usize(i); def.variant(FIRST_VARIANT).fields[i].ty(tcx, substs) } ty::Tuple(inner_tys) => inner_tys[i], diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index f7881c50960..93b5273e1b1 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -16,7 +16,9 @@ use rustc_middle::mir::interpret::InterpError; use rustc_middle::ty; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; use rustc_span::symbol::{sym, Symbol}; -use rustc_target::abi::{Abi, Scalar as ScalarAbi, Size, VariantIdx, Variants, WrappingRange}; +use rustc_target::abi::{ + Abi, FieldIdx, Scalar as ScalarAbi, Size, VariantIdx, Variants, WrappingRange, +}; use std::hash::Hash; @@ -269,14 +271,16 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' match layout.variants { Variants::Single { index } => { // Inside a variant - PathElem::Field(def.variant(index).fields[field].name) + PathElem::Field(def.variant(index).fields[FieldIdx::from_usize(field)].name) } Variants::Multiple { .. } => bug!("we handled variants above"), } } // other ADTs - ty::Adt(def, _) => PathElem::Field(def.non_enum_variant().fields[field].name), + ty::Adt(def, _) => { + PathElem::Field(def.non_enum_variant().fields[FieldIdx::from_usize(field)].name) + } // arrays/slices ty::Array(..) | ty::Slice(..) => PathElem::ArrayElem(field), diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index 2be385d551e..cd5c92f7342 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -360,7 +360,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } ty::Adt(adt_def, substs) => { let var = parent_ty.variant_index.unwrap_or(FIRST_VARIANT); - let Some(field) = adt_def.variant(var).fields.get(f.as_usize()) else { + let Some(field) = adt_def.variant(var).fields.get(f) else { fail_out_of_bounds(self, location); return; }; diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index d8dda7a93be..8617bca0825 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -27,6 +27,7 @@ use rustc_middle::ty::{ use rustc_session::lint::builtin::{UNINHABITED_STATIC, UNSUPPORTED_CALLING_CONVENTIONS}; use rustc_span::symbol::sym; use rustc_span::{self, Span}; +use rustc_target::abi::FieldIdx; use rustc_target::spec::abi::Abi; use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplementedDirective; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; @@ -474,7 +475,7 @@ fn is_enum_of_nonnullable_ptr<'tcx>( let [var_one, var_two] = &adt_def.variants().raw[..] else { return false; }; - let (([], [field]) | ([field], [])) = (&var_one.fields[..], &var_two.fields[..]) else { + let (([], [field]) | ([field], [])) = (&var_one.fields.raw[..], &var_two.fields.raw[..]) else { return false; }; matches!(field.ty(tcx, substs).kind(), ty::FnPtr(..) | ty::Ref(..)) @@ -893,7 +894,7 @@ pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) { struct_span_err!(tcx.sess, sp, E0075, "SIMD vector cannot be empty").emit(); return; } - let e = fields[0].ty(tcx, substs); + let e = fields[FieldIdx::from_u32(0)].ty(tcx, substs); if !fields.iter().all(|f| f.ty(tcx, substs) == e) { struct_span_err!(tcx.sess, sp, E0076, "SIMD vector should be homogeneous") .span_label(sp, "SIMD elements must have the same type") diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index 172b84bafb2..0d482b53afe 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -5,6 +5,7 @@ use rustc_middle::ty::{self, Article, FloatTy, IntTy, Ty, TyCtxt, TypeVisitableE use rustc_session::lint; use rustc_span::def_id::LocalDefId; use rustc_span::{Symbol, DUMMY_SP}; +use rustc_target::abi::FieldIdx; use rustc_target::asm::{InlineAsmReg, InlineAsmRegClass, InlineAsmRegOrRegClass, InlineAsmType}; pub struct InlineAsmCtxt<'a, 'tcx> { @@ -82,7 +83,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { } ty::Adt(adt, substs) if adt.repr().simd() => { let fields = &adt.non_enum_variant().fields; - let elem_ty = fields[0].ty(self.tcx, substs); + let elem_ty = fields[FieldIdx::from_u32(0)].ty(self.tcx, substs); match elem_ty.kind() { ty::Never | ty::Error(_) => return None, ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => { diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index d126f7beb10..24cc58ee344 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1030,7 +1030,7 @@ fn check_type_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, all_sized: b // intermediate types must be sized. let needs_drop_copy = || { packed && { - let ty = tcx.type_of(variant.fields.last().unwrap().did).subst_identity(); + let ty = tcx.type_of(variant.fields.raw.last().unwrap().did).subst_identity(); let ty = tcx.erase_regions(ty); if ty.needs_infer() { tcx.sess @@ -1046,7 +1046,7 @@ fn check_type_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, all_sized: b let all_sized = all_sized || variant.fields.is_empty() || needs_drop_copy(); let unsized_len = if all_sized { 0 } else { 1 }; for (idx, field) in - variant.fields[..variant.fields.len() - unsized_len].iter().enumerate() + variant.fields.raw[..variant.fields.len() - unsized_len].iter().enumerate() { let last = idx == variant.fields.len() - 1; let field_id = field.did.expect_local(); diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 25d56ea45c1..ac7c68d9c4b 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -486,8 +486,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe // U` can be coerced to `*mut V` if `U: Unsize`. let fields = &def_a.non_enum_variant().fields; let diff_fields = fields - .iter() - .enumerate() + .iter_enumerated() .filter_map(|(i, f)| { let (a, b) = (f.ty(tcx, substs_a), f.ty(tcx, substs_b)); diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index d28b3b3ce7b..1481c038cfe 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -103,13 +103,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Ok(match *t.kind() { ty::Slice(_) | ty::Str => Some(PointerKind::Length), ty::Dynamic(ref tty, _, ty::Dyn) => Some(PointerKind::VTable(tty.principal_def_id())), - ty::Adt(def, substs) if def.is_struct() => match def.non_enum_variant().fields.last() { - None => Some(PointerKind::Thin), - Some(f) => { - let field_ty = self.field_ty(span, f, substs); - self.pointer_kind(field_ty, span)? + ty::Adt(def, substs) if def.is_struct() => { + match def.non_enum_variant().fields.raw.last() { + None => Some(PointerKind::Thin), + Some(f) => { + let field_ty = self.field_ty(span, f, substs); + self.pointer_kind(field_ty, span)? + } } - }, + } ty::Tuple(fields) => match fields.last() { None => Some(PointerKind::Thin), Some(&f) => self.pointer_kind(f, span)?, diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 4846579b980..30d307948a6 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -19,6 +19,7 @@ use rustc_middle::ty::relate::TypeRelation; use rustc_middle::ty::{self, Article, AssocItem, Ty, TypeAndMut, TypeVisitableExt}; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{BytePos, Span}; +use rustc_target::abi::FieldIdx; use rustc_trait_selection::infer::InferCtxtExt as _; use rustc_trait_selection::traits::error_reporting::method_chain::CollectAllMismatches; use rustc_trait_selection::traits::ObligationCause; @@ -850,7 +851,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { variant.fields.len() == 1 }) .filter_map(|variant| { - let sole_field = &variant.fields[0]; + let sole_field = &variant.fields[FieldIdx::from_u32(0)]; let field_is_local = sole_field.did.is_local(); let field_is_accessible = diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index fb7cb86d734..c17aae22ba5 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -50,6 +50,7 @@ use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::hygiene::DesugaringKind; use rustc_span::source_map::{Span, Spanned}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; +use rustc_target::abi::FieldIdx; use rustc_target::spec::abi::Abi::RustIntrinsic; use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::traits::{self, ObligationCauseCode}; @@ -1561,8 +1562,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut remaining_fields = variant .fields - .iter() - .enumerate() + .iter_enumerated() .map(|(i, field)| (field.ident(tcx).normalize_to_macros_2_0(), (i, field))) .collect::>(); @@ -1815,7 +1815,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, adt_ty: Ty<'tcx>, span: Span, - remaining_fields: FxHashMap, + remaining_fields: FxHashMap, variant: &'tcx ty::VariantDef, ast_fields: &'tcx [hir::ExprField<'tcx>], substs: SubstsRef<'tcx>, @@ -2209,11 +2209,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (ident, def_scope) = self.tcx.adjust_ident_and_get_scope(field, base_def.did(), body_hir_id); let fields = &base_def.non_enum_variant().fields; - if let Some(index) = fields - .iter() - .position(|f| f.ident(self.tcx).normalize_to_macros_2_0() == ident) + if let Some((index, field)) = fields + .iter_enumerated() + .find(|(_, f)| f.ident(self.tcx).normalize_to_macros_2_0() == ident) { - let field = &fields[index]; let field_ty = self.field_ty(expr.span, field, substs); // Save the index of all fields regardless of their visibility in case // of error recovery. @@ -2230,15 +2229,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } ty::Tuple(tys) => { - let fstr = field.as_str(); - if let Ok(index) = fstr.parse::() { - if fstr == index.to_string() { + if let Ok(index) = field.as_str().parse::() { + if field.name == sym::integer(index) { if let Some(&field_ty) = tys.get(index) { let adjustments = self.adjust_steps(&autoderef); self.apply_adjustments(base, adjustments); self.register_predicates(autoderef.into_obligations()); - self.write_field_index(expr.hir_id, index); + self.write_field_index(expr.hir_id, FieldIdx::from_usize(index)); return field_ty; } } diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 5ca4087cdd3..58902cd292c 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -539,7 +539,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { match with_place.place.ty().kind() { ty::Adt(adt, substs) if adt.is_struct() => { // Consume those fields of the with expression that are needed. - for (f_index, with_field) in adt.non_enum_variant().fields.iter().enumerate() { + for (f_index, with_field) in adt.non_enum_variant().fields.iter_enumerated() { let is_mentioned = fields .iter() .any(|f| self.mc.typeck_results.opt_field_index(f.hir_id) == Some(f_index)); @@ -548,7 +548,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { &*with_expr, with_place.clone(), with_field.ty(self.tcx(), substs), - ProjectionKind::Field(f_index as u32, FIRST_VARIANT), + ProjectionKind::Field(f_index, FIRST_VARIANT), ); self.delegate_consume(&field_place, field_place.hir_id); } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 50fc48f68a4..fdf178c3ea7 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -33,6 +33,7 @@ use rustc_span::def_id::LocalDefId; use rustc_span::hygiene::DesugaringKind; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Span; +use rustc_target::abi::FieldIdx; use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _; use rustc_trait_selection::traits::{self, NormalizeExt, ObligationCauseCode, ObligationCtxt}; @@ -147,7 +148,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub fn write_field_index(&self, hir_id: hir::HirId, index: usize) { + pub fn write_field_index(&self, hir_id: hir::HirId, index: FieldIdx) { self.typeck_results.borrow_mut().field_indices_mut().insert(hir_id, index); } diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs index 19d2befc438..901acffe1c8 100644 --- a/compiler/rustc_hir_typeck/src/intrinsicck.rs +++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs @@ -4,7 +4,7 @@ use rustc_hir as hir; use rustc_index::vec::Idx; use rustc_middle::ty::layout::{LayoutError, SizeSkeleton}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; -use rustc_target::abi::{Pointer, VariantIdx}; +use rustc_target::abi::{FieldIdx, Pointer, VariantIdx}; use super::FnCtxt; @@ -28,7 +28,7 @@ fn unpack_option_like<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { } if def.variant(data_idx).fields.len() == 1 { - return def.variant(data_idx).fields[0].ty(tcx, substs); + return def.variant(data_idx).fields[FieldIdx::from_u32(0)].ty(tcx, substs); } } diff --git a/compiler/rustc_hir_typeck/src/mem_categorization.rs b/compiler/rustc_hir_typeck/src/mem_categorization.rs index 19c4146de89..6c861b5930a 100644 --- a/compiler/rustc_hir_typeck/src/mem_categorization.rs +++ b/compiler/rustc_hir_typeck/src/mem_categorization.rs @@ -61,7 +61,7 @@ use rustc_hir::pat_util::EnumerateAndAdjustIterator; use rustc_hir::PatKind; use rustc_infer::infer::InferCtxt; use rustc_span::Span; -use rustc_target::abi::{VariantIdx, FIRST_VARIANT}; +use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT}; use rustc_trait_selection::infer::InferCtxtExt; pub(crate) trait HirNode { @@ -330,7 +330,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { expr, base, expr_ty, - ProjectionKind::Field(field_idx as u32, FIRST_VARIANT), + ProjectionKind::Field(field_idx, FIRST_VARIANT), )) } @@ -674,7 +674,8 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { for (i, subpat) in subpats.iter().enumerate_and_adjust(total_fields, dots_pos) { let subpat_ty = self.pat_ty_adjusted(subpat)?; - let projection_kind = ProjectionKind::Field(i as u32, FIRST_VARIANT); + let projection_kind = + ProjectionKind::Field(FieldIdx::from_usize(i), FIRST_VARIANT); let sub_place = self.cat_projection(pat, place_with_id.clone(), subpat_ty, projection_kind); self.cat_pattern_(sub_place, subpat, op)?; @@ -689,7 +690,8 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { for (i, subpat) in subpats.iter().enumerate_and_adjust(total_fields, dots_pos) { let subpat_ty = self.pat_ty_adjusted(subpat)?; - let projection_kind = ProjectionKind::Field(i as u32, variant_index); + let projection_kind = + ProjectionKind::Field(FieldIdx::from_usize(i), variant_index); let sub_place = self.cat_projection(pat, place_with_id.clone(), subpat_ty, projection_kind); self.cat_pattern_(sub_place, subpat, op)?; @@ -714,7 +716,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> { pat, place_with_id.clone(), field_ty, - ProjectionKind::Field(field_index as u32, variant_index), + ProjectionKind::Field(field_index, variant_index), ); self.cat_pattern_(field_place, fp.pat, op)?; } diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 95d1a7df698..5c50619f4c3 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1815,7 +1815,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .variants() .iter() .flat_map(|variant| { - let [field] = &variant.fields[..] else { return None; }; + let [field] = &variant.fields.raw[..] else { return None; }; let field_ty = field.ty(tcx, substs); // Skip `_`, since that'll just lead to ambiguity. diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 11ff65d0c37..241535b29c5 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -19,6 +19,7 @@ use rustc_span::hygiene::DesugaringKind; use rustc_span::source_map::{Span, Spanned}; use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::{BytePos, DUMMY_SP}; +use rustc_target::abi::FieldIdx; use rustc_trait_selection::traits::{ObligationCause, Pattern}; use ty::VariantDef; @@ -1091,11 +1092,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { bug!("unexpected pattern type {:?}", pat_ty); }; for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) { - let field_ty = self.field_ty(subpat.span, &variant.fields[i], substs); + let field = &variant.fields[FieldIdx::from_usize(i)]; + let field_ty = self.field_ty(subpat.span, field, substs); self.check_pat(subpat, field_ty, def_bm, ti); self.tcx.check_stability( - variant.fields[i].did, + variant.fields[FieldIdx::from_usize(i)].did, Some(pat.hir_id), subpat.span, None, @@ -1103,7 +1105,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } else { // Pattern has wrong number of fields. - let e = self.e0023(pat.span, res, qpath, subpats, &variant.fields, expected, had_err); + let e = + self.e0023(pat.span, res, qpath, subpats, &variant.fields.raw, expected, had_err); on_error(e); return tcx.ty_error(e); } @@ -1333,8 +1336,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Index the struct fields' types. let field_map = variant .fields - .iter() - .enumerate() + .iter_enumerated() .map(|(i, field)| (field.ident(self.tcx).normalize_to_macros_2_0(), (i, field))) .collect::>(); diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 8fe5a3cc789..504da7dc090 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -1405,7 +1405,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ProjectionKind::Field(..) )) ); - def.variants().get(FIRST_VARIANT).unwrap().fields.iter().enumerate().any( + def.variants().get(FIRST_VARIANT).unwrap().fields.iter_enumerated().any( |(i, field)| { let paths_using_field = captured_by_move_projs .iter() @@ -1413,7 +1413,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let ProjectionKind::Field(field_idx, _) = projs.first().unwrap().kind { - if (field_idx as usize) == i { Some(&projs[1..]) } else { None } + if field_idx == i { Some(&projs[1..]) } else { None } } else { unreachable!(); } @@ -1446,7 +1446,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .filter_map(|projs| { if let ProjectionKind::Field(field_idx, _) = projs.first().unwrap().kind { - if (field_idx as usize) == i { Some(&projs[1..]) } else { None } + if field_idx.index() == i { Some(&projs[1..]) } else { None } } else { unreachable!(); } diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs index ec122dc039f..8ad143247e8 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs @@ -10,6 +10,7 @@ use rustc_middle::traits::{ use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self as ty, IsSuggestable, Ty, TypeVisitableExt}; use rustc_span::{sym, BytePos, Span}; +use rustc_target::abi::FieldIdx; use crate::errors::{ ConsiderAddingAwait, SuggAddLetForLetChains, SuggestRemoveSemiOrReturnBinding, @@ -109,7 +110,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { variant.fields.len() == 1 && variant.ctor_kind() == Some(CtorKind::Fn) }) .filter_map(|variant| { - let sole_field = &variant.fields[0]; + let sole_field = &variant.fields[FieldIdx::from_u32(0)]; let sole_field_ty = sole_field.ty(self.tcx, substs); if self.same_type_modulo_infer(sole_field_ty, exp_found.found) { let variant_path = diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index f6bca7045c8..a6ba742201a 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -770,7 +770,7 @@ pub(crate) fn repr_nullable_ptr<'tcx>( debug!("is_repr_nullable_ptr(cx, ty = {:?})", ty); if let ty::Adt(ty_def, substs) = ty.kind() { let field_ty = match &ty_def.variants().raw[..] { - [var_one, var_two] => match (&var_one.fields[..], &var_two.fields[..]) { + [var_one, var_two] => match (&var_one.fields.raw[..], &var_two.fields.raw[..]) { ([], [field]) | ([field], []) => field.ty(cx.tcx, substs), _ => return None, }, diff --git a/compiler/rustc_middle/src/hir/place.rs b/compiler/rustc_middle/src/hir/place.rs index 83d3b0100b8..80b4c964ce4 100644 --- a/compiler/rustc_middle/src/hir/place.rs +++ b/compiler/rustc_middle/src/hir/place.rs @@ -2,7 +2,7 @@ use crate::ty; use crate::ty::Ty; use rustc_hir::HirId; -use rustc_target::abi::VariantIdx; +use rustc_target::abi::{FieldIdx, VariantIdx}; #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)] #[derive(TypeFoldable, TypeVisitable)] @@ -27,7 +27,7 @@ pub enum ProjectionKind { /// the field. The field is identified by which variant /// it appears in along with a field index. The variant /// is used for enums. - Field(u32, VariantIdx), + Field(FieldIdx, VariantIdx), /// Some index like `B[x]`, where `B` is the base /// expression. We don't preserve the index `x` because diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index 4a28aabf8a3..ac28ef5276c 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -43,7 +43,7 @@ impl<'tcx> PlaceTy<'tcx> { &adt_def.variant(variant_index) } }; - let field_def = &variant_def.fields[f.index()]; + let field_def = &variant_def.fields[f]; field_def.ty(tcx, substs) } ty::Tuple(tys) => tys[f.index()], diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 29e3055a4b8..82a7cf78517 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -784,7 +784,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> { if let PatKind::Wild = p.pattern.kind { continue; } - let name = variant.fields[p.field.index()].name; + let name = variant.fields[p.field].name; write!(f, "{}{}: {}", start_or_comma(), name, p.pattern)?; printed += 1; } diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs index 8ce06404de0..cd0f7e8daf1 100644 --- a/compiler/rustc_middle/src/ty/adjustment.rs +++ b/compiler/rustc_middle/src/ty/adjustment.rs @@ -3,6 +3,7 @@ use rustc_hir as hir; use rustc_hir::lang_items::LangItem; use rustc_macros::HashStable; use rustc_span::Span; +use rustc_target::abi::FieldIdx; #[derive(Clone, Copy, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)] pub enum PointerCast { @@ -208,5 +209,5 @@ pub struct CoerceUnsizedInfo { #[derive(Clone, Copy, TyEncodable, TyDecodable, Debug, HashStable)] pub enum CustomCoerceUnsized { /// Records the index of the field being coerced. - Struct(usize), + Struct(FieldIdx), } diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index dc2bd54b7fe..f29bf92b0ed 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -158,12 +158,12 @@ impl<'tcx> CapturedPlace<'tcx> { for proj in self.place.projections.iter() { match proj.kind { HirProjectionKind::Field(idx, variant) => match ty.kind() { - ty::Tuple(_) => write!(&mut symbol, "__{}", idx).unwrap(), + ty::Tuple(_) => write!(&mut symbol, "__{}", idx.index()).unwrap(), ty::Adt(def, ..) => { write!( &mut symbol, "__{}", - def.variant(variant).fields[idx as usize].name.as_str(), + def.variant(variant).fields[idx].name.as_str(), ) .unwrap(); } @@ -356,11 +356,11 @@ pub fn place_to_string_for_capture<'tcx>(tcx: TyCtxt<'tcx>, place: &HirPlace<'tc curr_string = format!( "{}.{}", curr_string, - def.variant(variant).fields[idx as usize].name.as_str() + def.variant(variant).fields[idx].name.as_str() ); } ty::Tuple(_) => { - curr_string = format!("{}.{}", curr_string, idx); + curr_string = format!("{}.{}", curr_string, idx.index()); } _ => { bug!( diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 42fb5d031bb..0f70b315aa6 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -5,7 +5,6 @@ use crate::ty::{self, ReprOptions, Ty, TyCtxt, TypeVisitableExt}; use rustc_errors::{DiagnosticBuilder, Handler, IntoDiagnostic}; use rustc_hir as hir; use rustc_hir::def_id::DefId; -use rustc_index::vec::Idx; use rustc_session::config::OptLevel; use rustc_span::symbol::{sym, Symbol}; use rustc_span::{Span, DUMMY_SP}; @@ -335,7 +334,7 @@ impl<'tcx> SizeSkeleton<'tcx> { // Get a zero-sized variant or a pointer newtype. let zero_or_ptr_variant = |i| { - let i = VariantIdx::new(i); + let i = VariantIdx::from_usize(i); let fields = def.variant(i).fields.iter().map(|field| { SizeSkeleton::compute(field.ty(tcx, substs), tcx, param_env) @@ -798,7 +797,8 @@ where ty::Adt(def, substs) => { match this.variants { Variants::Single { index } => { - TyMaybeWithLayout::Ty(def.variant(index).fields[i].ty(tcx, substs)) + let field = &def.variant(index).fields[FieldIdx::from_usize(i)]; + TyMaybeWithLayout::Ty(field.ty(tcx, substs)) } // Discriminant field for enums (where applicable). diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 7df90fab56f..800a230b654 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -50,7 +50,7 @@ pub use rustc_session::lint::RegisteredTools; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{ExpnId, ExpnKind, Span}; -use rustc_target::abi::{Align, Integer, IntegerType, VariantIdx}; +use rustc_target::abi::{Align, FieldIdx, Integer, IntegerType, VariantIdx}; pub use rustc_target::abi::{ReprFlags, ReprOptions}; use rustc_type_ir::WithCachedTypeInfo; pub use subst::*; @@ -1891,7 +1891,7 @@ pub struct VariantDef { /// Discriminant of this variant. pub discr: VariantDiscr, /// Fields of this variant. - pub fields: Vec, + pub fields: IndexVec, /// Flags of the variant (e.g. is field list non-exhaustive)? flags: VariantFlags, } @@ -1918,7 +1918,7 @@ impl VariantDef { variant_did: Option, ctor: Option<(CtorKind, DefId)>, discr: VariantDiscr, - fields: Vec, + fields: IndexVec, adt_kind: AdtKind, parent_did: DefId, recovered: bool, @@ -2270,11 +2270,10 @@ impl<'tcx> TyCtxt<'tcx> { } } - pub fn find_field_index(self, ident: Ident, variant: &VariantDef) -> Option { - variant - .fields - .iter() - .position(|field| self.hygienic_eq(ident, field.ident(self), variant.def_id)) + pub fn find_field_index(self, ident: Ident, variant: &VariantDef) -> Option { + variant.fields.iter_enumerated().find_map(|(i, field)| { + self.hygienic_eq(ident, field.ident(self), variant.def_id).then_some(i) + }) } /// Returns `true` if the impls are the same polarity and the trait either diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index d03cc324e51..5ea77833af2 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -22,7 +22,7 @@ use rustc_index::vec::Idx; use rustc_macros::HashStable; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; -use rustc_target::abi::{VariantIdx, FIRST_VARIANT}; +use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT}; use rustc_target::spec::abi::{self, Abi}; use std::borrow::Cow; use std::cmp::Ordering; @@ -1903,7 +1903,7 @@ impl<'tcx> Ty<'tcx> { Adt(def, substs) => { assert!(def.repr().simd(), "`simd_size_and_type` called on non-SIMD type"); let variant = def.non_enum_variant(); - let f0_ty = variant.fields[0].ty(tcx, substs); + let f0_ty = variant.fields[FieldIdx::from_u32(0)].ty(tcx, substs); match f0_ty.kind() { // If the first field is an array, we assume it is the only field and its diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index 2b0fb4dc2b7..47943b94c3b 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -25,6 +25,7 @@ use rustc_macros::HashStable; use rustc_middle::mir::FakeReadCause; use rustc_session::Session; use rustc_span::Span; +use rustc_target::abi::FieldIdx; use std::{collections::hash_map::Entry, hash::Hash, iter}; use super::RvalueScopes; @@ -42,7 +43,7 @@ pub struct TypeckResults<'tcx> { /// or patterns (`S { field }`). The index is often useful by itself, but to learn more /// about the field you also need definition of the variant to which the field /// belongs, but it may not exist if it's a tuple field (`tuple.0`). - field_indices: ItemLocalMap, + field_indices: ItemLocalMap, /// Stores the types for various nodes in the AST. Note that this table /// is not guaranteed to be populated outside inference. See @@ -313,19 +314,19 @@ impl<'tcx> TypeckResults<'tcx> { LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.type_dependent_defs } } - pub fn field_indices(&self) -> LocalTableInContext<'_, usize> { + pub fn field_indices(&self) -> LocalTableInContext<'_, FieldIdx> { LocalTableInContext { hir_owner: self.hir_owner, data: &self.field_indices } } - pub fn field_indices_mut(&mut self) -> LocalTableInContextMut<'_, usize> { + pub fn field_indices_mut(&mut self) -> LocalTableInContextMut<'_, FieldIdx> { LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.field_indices } } - pub fn field_index(&self, id: hir::HirId) -> usize { + pub fn field_index(&self, id: hir::HirId) -> FieldIdx { self.field_indices().get(id).cloned().expect("no index for a field") } - pub fn opt_field_index(&self, id: hir::HirId) -> Option { + pub fn opt_field_index(&self, id: hir::HirId) -> Option { self.field_indices().get(id).cloned() } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index e9c0552812b..d3565b28ae5 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -235,7 +235,7 @@ impl<'tcx> TyCtxt<'tcx> { if !def.is_struct() { break; } - match def.non_enum_variant().fields.last() { + match def.non_enum_variant().fields.raw.last() { Some(field) => { f(); ty = field.ty(self, substs); @@ -309,7 +309,7 @@ impl<'tcx> TyCtxt<'tcx> { (&ty::Adt(a_def, a_substs), &ty::Adt(b_def, b_substs)) if a_def == b_def && a_def.is_struct() => { - if let Some(f) = a_def.non_enum_variant().fields.last() { + if let Some(f) = a_def.non_enum_variant().fields.raw.last() { a = f.ty(self, a_substs); b = f.ty(self, b_substs); } else { diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs index 0fc99e57d12..fb775766c65 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -90,7 +90,7 @@ fn convert_to_hir_projections_and_truncate_for_capture( ProjectionElem::Deref => HirProjectionKind::Deref, ProjectionElem::Field(field, _) => { let variant = variant.unwrap_or(FIRST_VARIANT); - HirProjectionKind::Field(field.index() as u32, variant) + HirProjectionKind::Field(*field, variant) } ProjectionElem::Downcast(.., idx) => { // We don't expect to see multi-variant enums here, as earlier diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index 2a0b5d04733..8e2e92e6f6a 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -733,7 +733,7 @@ impl<'tcx> Cx<'tcx> { hir::ExprKind::Field(ref source, ..) => ExprKind::Field { lhs: self.mirror_expr(source), variant_index: FIRST_VARIANT, - name: FieldIdx::new(self.typeck_results.field_index(expr.hir_id)), + name: self.typeck_results.field_index(expr.hir_id), }, hir::ExprKind::Cast(ref source, ref cast_ty) => { // Check for a user-given type annotation on this `cast` @@ -1053,7 +1053,7 @@ impl<'tcx> Cx<'tcx> { HirProjectionKind::Field(field, variant_index) => ExprKind::Field { lhs: self.thir.exprs.push(captured_place_expr), variant_index, - name: FieldIdx::new(field as usize), + name: field, }, HirProjectionKind::Index | HirProjectionKind::Subslice => { // We don't capture these projections, so we can ignore them here @@ -1107,7 +1107,7 @@ impl<'tcx> Cx<'tcx> { fields .iter() .map(|field| FieldExpr { - name: FieldIdx::new(self.typeck_results.field_index(field.hir_id)), + name: self.typeck_results.field_index(field.hir_id), expr: self.mirror_expr(field.expr), }) .collect() diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 72b4041aa1b..9ac92f6e0a6 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -357,7 +357,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { let subpatterns = fields .iter() .map(|field| FieldPat { - field: FieldIdx::new(self.typeck_results.field_index(field.hir_id)), + field: self.typeck_results.field_index(field.hir_id), pattern: self.lower_pattern(&field.pat), }) .collect(); diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index 37787d99c2d..c8661bbcc44 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -411,9 +411,9 @@ where fn open_drop_for_box(&mut self, adt: ty::AdtDef<'tcx>, substs: SubstsRef<'tcx>) -> BasicBlock { // drop glue is sent straight to codegen // box cannot be directly dereferenced - let unique_ty = adt.non_enum_variant().fields[0].ty(self.tcx(), substs); - let nonnull_ty = - unique_ty.ty_adt_def().unwrap().non_enum_variant().fields[0].ty(self.tcx(), substs); + let unique_ty = adt.non_enum_variant().fields[FieldIdx::new(0)].ty(self.tcx(), substs); + let unique_variant = unique_ty.ty_adt_def().unwrap().non_enum_variant(); + let nonnull_ty = unique_variant.fields[FieldIdx::from_u32(0)].ty(self.tcx(), substs); let ptr_ty = self.tcx().mk_imm_ptr(substs[0].expect_ty()); let unique_place = self.tcx().mk_place_field(self.place, FieldIdx::new(0), unique_ty); diff --git a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs index 58bc083280a..85623499439 100644 --- a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs +++ b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs @@ -92,13 +92,14 @@ pub struct ElaborateBoxDerefs; impl<'tcx> MirPass<'tcx> for ElaborateBoxDerefs { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { if let Some(def_id) = tcx.lang_items().owned_box() { - let unique_did = tcx.adt_def(def_id).non_enum_variant().fields[0].did; + let unique_did = + tcx.adt_def(def_id).non_enum_variant().fields[FieldIdx::from_u32(0)].did; let Some(nonnull_def) = tcx.type_of(unique_did).subst_identity().ty_adt_def() else { span_bug!(tcx.def_span(unique_did), "expected Box to contain Unique") }; - let nonnull_did = nonnull_def.non_enum_variant().fields[0].did; + let nonnull_did = nonnull_def.non_enum_variant().fields[FieldIdx::from_u32(0)].did; let patch = MirPatch::new(body); diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 98d2df71978..15b31d38394 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -907,7 +907,7 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> { } ty::Adt(adt_def, substs) => { let var = parent_ty.variant_index.unwrap_or(FIRST_VARIANT); - let Some(field) = adt_def.variant(var).fields.get(f.as_usize()) else { + let Some(field) = adt_def.variant(var).fields.get(f) else { self.validation = Err("malformed MIR"); return; }; diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index af0222c8172..3f07126d244 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1119,7 +1119,8 @@ fn find_vtable_types_for_unsizing<'tcx>( let target_fields = &target_adt_def.non_enum_variant().fields; assert!( - coerce_index < source_fields.len() && source_fields.len() == target_fields.len() + coerce_index.index() < source_fields.len() + && source_fields.len() == target_fields.len() ); find_vtable_types_for_unsizing( diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 75ce446e6b4..91483fe3de7 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -16,6 +16,7 @@ use rustc_middle::ty::query::Providers; use rustc_middle::ty::{self, TyCtxt}; use rustc_session::lint; use rustc_span::symbol::{sym, Symbol}; +use rustc_target::abi::FieldIdx; use std::mem; use crate::errors::{ @@ -232,7 +233,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { if let PatKind::Wild = pat.kind { continue; } - self.insert_def_id(variant.fields[idx].did); + self.insert_def_id(variant.fields[FieldIdx::from_usize(idx)].did); } } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 3be0160d561..fed9dfa5c67 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -1082,7 +1082,7 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> { // If the expression uses FRU we need to make sure all the unmentioned fields // are checked for privacy (RFC 736). Rather than computing the set of // unmentioned fields, just check them all. - for (vf_index, variant_field) in variant.fields.iter().enumerate() { + for (vf_index, variant_field) in variant.fields.iter_enumerated() { let field = fields .iter() .find(|f| self.typeck_results().field_index(f.hir_id) == vf_index); diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index 48f7d3e3e40..90d28c620ea 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -351,7 +351,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { } ty::Adt(def, substs) if def.is_struct() => { - match def.non_enum_variant().fields.last() { + match def.non_enum_variant().fields.raw.last() { None => tcx.types.unit, Some(field_def) => { let self_ty = field_def.ty(tcx, substs); diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs index f522a8f7e65..ce3db83d33d 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs @@ -407,6 +407,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> { let tail_field = a_def .non_enum_variant() .fields + .raw .last() .expect("expected unsized ADT to have a tail field"); let tail_field_ty = tcx.type_of(tail_field.did); diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index eb354bc3f50..5e60bc01bb6 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -1078,6 +1078,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let tail_field = def .non_enum_variant() .fields + .raw .last() .expect("expected unsized ADT to have a tail field"); let tail_field_ty = tcx.type_of(tail_field.did); diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 380931742e3..73f86f74d14 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -320,7 +320,7 @@ fn layout_of_uncached<'tcx>( } // Type of the first ADT field: - let f0_ty = def.non_enum_variant().fields[0].ty(tcx, substs); + let f0_ty = def.non_enum_variant().fields[FieldIdx::from_u32(0)].ty(tcx, substs); // Heterogeneous SIMD vectors are not supported: // (should be caught by typeck) @@ -456,7 +456,8 @@ fn layout_of_uncached<'tcx>( { let param_env = tcx.param_env(def.did()); def.is_struct() - && match def.variants().iter().next().and_then(|x| x.fields.last()) { + && match def.variants().iter().next().and_then(|x| x.fields.raw.last()) + { Some(last_field) => tcx .type_of(last_field.did) .subst_identity() diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 50aeb7f440f..cb06c7acff0 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -107,7 +107,7 @@ fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> &[Ty<'_>] { let result = tcx.mk_type_list_from_iter( def.variants() .iter() - .flat_map(|v| v.fields.last()) + .filter_map(|v| v.fields.raw.last()) .flat_map(|f| sized_constraint_for_ty(tcx, def, tcx.type_of(f.did).subst_identity())), ); @@ -542,7 +542,7 @@ fn unsizing_params_for_adt<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> BitSet Date: Thu, 30 Mar 2023 18:30:56 +0200 Subject: [PATCH 295/346] Update gccjit and remove libc 0.1 dependency --- compiler/rustc_codegen_gcc/Cargo.lock | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_codegen_gcc/Cargo.lock b/compiler/rustc_codegen_gcc/Cargo.lock index 80e57418940..0f2e152f8ce 100644 --- a/compiler/rustc_codegen_gcc/Cargo.lock +++ b/compiler/rustc_codegen_gcc/Cargo.lock @@ -35,7 +35,7 @@ dependencies = [ [[package]] name = "gccjit" version = "1.0.0" -source = "git+https://github.com/antoyo/gccjit.rs#eefb8c662d61477f34b7c32d26bcda5f1ef08432" +source = "git+https://github.com/antoyo/gccjit.rs#fe242b7eb26980e6c78859d51c8d4cc1e43381a3" dependencies = [ "gccjit_sys", ] @@ -43,9 +43,9 @@ dependencies = [ [[package]] name = "gccjit_sys" version = "0.0.1" -source = "git+https://github.com/antoyo/gccjit.rs#eefb8c662d61477f34b7c32d26bcda5f1ef08432" +source = "git+https://github.com/antoyo/gccjit.rs#fe242b7eb26980e6c78859d51c8d4cc1e43381a3" dependencies = [ - "libc 0.1.12", + "libc", ] [[package]] @@ -64,7 +64,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" dependencies = [ "cfg-if", - "libc 0.2.112", + "libc", "wasi", ] @@ -74,7 +74,7 @@ version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ - "libc 0.2.112", + "libc", ] [[package]] @@ -85,7 +85,7 @@ checksum = "96bd995a092cac79868250589869b5a5d656b02a02bd74c8ebdc566dc7203090" dependencies = [ "fm", "getopts", - "libc 0.2.112", + "libc", "num_cpus", "termcolor", "threadpool", @@ -93,12 +93,6 @@ dependencies = [ "walkdir", ] -[[package]] -name = "libc" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e32a70cf75e5846d53a673923498228bbec6a8624708a9ea5645f075d6276122" - [[package]] name = "libc" version = "0.2.112" @@ -118,7 +112,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" dependencies = [ "hermit-abi", - "libc 0.2.112", + "libc", ] [[package]] @@ -133,7 +127,7 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" dependencies = [ - "libc 0.2.112", + "libc", "rand_chacha", "rand_core", "rand_hc", @@ -234,7 +228,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" dependencies = [ "cfg-if", - "libc 0.2.112", + "libc", "rand", "redox_syscall", "remove_dir_all", @@ -271,7 +265,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" dependencies = [ - "libc 0.2.112", + "libc", ] [[package]] From e6989d2959ee8ecc81c2e6fb3622d91108772a99 Mon Sep 17 00:00:00 2001 From: Jynn Nelson Date: Thu, 30 Mar 2023 13:36:40 -0400 Subject: [PATCH 296/346] Update contributing links for rustc-dev-guide changes - Remove unused reference link in CONTRIBUTING.md - Change the contributing_url for triagebot to the getting started page --- CONTRIBUTING.md | 1 - triagebot.toml | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d732075fb2d..dfaa70bb9db 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -33,7 +33,6 @@ find a mentor! You can learn more about asking questions and getting help in the Did a compiler error message tell you to come here? If you want to create an ICE report, refer to [this section][contributing-bug-reports] and [open an issue][issue template]. -[Contributing to Rust]: https://rustc-dev-guide.rust-lang.org/contributing.html#contributing-to-rust [rustc-dev-guide]: https://rustc-dev-guide.rust-lang.org/ [std-dev-guide]: https://std-dev-guide.rust-lang.org/ [contributing-bug-reports]: https://rustc-dev-guide.rust-lang.org/contributing.html#bug-reports diff --git a/triagebot.toml b/triagebot.toml index c86c1613fa9..20a8be283b9 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -482,7 +482,7 @@ message = "This PR changes src/bootstrap/defaults/config.codegen.toml. If approp [assign] warn_non_default_branch = true -contributing_url = "https://rustc-dev-guide.rust-lang.org/contributing.html" +contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html" [assign.adhoc_groups] compiler-team = [ From 408e2ac3bb35a54529ea0647a024fb817a27a8c2 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Thu, 30 Mar 2023 11:19:38 -0700 Subject: [PATCH 297/346] Add `IndexSlice` to go with `IndexVec` Moves the methods that don't need full `IndexVec`-ness over to `IndexSlice`, and have `IndexVec` deref to `IndexSlice` so everything keeps working. --- compiler/rustc_index/src/vec.rs | 236 ++++++++++++++++++++++---------- 1 file changed, 163 insertions(+), 73 deletions(-) diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs index acf883fe90c..596849bd456 100644 --- a/compiler/rustc_index/src/vec.rs +++ b/compiler/rustc_index/src/vec.rs @@ -5,7 +5,7 @@ use std::fmt; use std::fmt::Debug; use std::hash::Hash; use std::marker::PhantomData; -use std::ops::{Index, IndexMut, RangeBounds}; +use std::ops::{Deref, DerefMut, Index, IndexMut, RangeBounds}; use std::slice; use std::vec; @@ -52,15 +52,27 @@ impl Idx for u32 { } #[derive(Clone, PartialEq, Eq, Hash)] +#[repr(transparent)] pub struct IndexVec { pub raw: Vec, _marker: PhantomData, } +#[derive(PartialEq, Eq, Hash)] +#[repr(transparent)] +pub struct IndexSlice { + _marker: PhantomData, + pub raw: [T], +} + // Whether `IndexVec` is `Send` depends only on the data, // not the phantom data. unsafe impl Send for IndexVec where T: Send {} +// Whether `IndexSlice` is `Send` depends only on the data, +// not the phantom data. +unsafe impl Send for IndexSlice where T: Send {} + #[cfg(feature = "rustc_serialize")] impl> Encodable for IndexVec { fn encode(&self, s: &mut S) { @@ -122,6 +134,16 @@ impl IndexVec { Self::from_raw(indices.map(func).collect()) } + #[inline] + pub fn as_slice(&self) -> &IndexSlice { + IndexSlice::from_raw(&self.raw) + } + + #[inline] + pub fn as_mut_slice(&mut self) -> &mut IndexSlice { + IndexSlice::from_raw_mut(&mut self.raw) + } + #[inline] pub fn push(&mut self, d: T) -> I { let idx = I::new(self.len()); @@ -134,23 +156,6 @@ impl IndexVec { self.raw.pop() } - #[inline] - pub fn len(&self) -> usize { - self.raw.len() - } - - /// Gives the next index that will be assigned when `push` is - /// called. - #[inline] - pub fn next_index(&self) -> I { - I::new(self.len()) - } - - #[inline] - pub fn is_empty(&self) -> bool { - self.raw.is_empty() - } - #[inline] pub fn into_iter(self) -> vec::IntoIter { self.raw.into_iter() @@ -163,6 +168,110 @@ impl IndexVec { self.raw.into_iter().enumerate().map(|(n, t)| (I::new(n), t)) } + #[inline] + pub fn drain<'a, R: RangeBounds>( + &'a mut self, + range: R, + ) -> impl Iterator + 'a { + self.raw.drain(range) + } + + #[inline] + pub fn drain_enumerated<'a, R: RangeBounds>( + &'a mut self, + range: R, + ) -> impl Iterator + 'a { + let begin = match range.start_bound() { + std::ops::Bound::Included(i) => *i, + std::ops::Bound::Excluded(i) => i.checked_add(1).unwrap(), + std::ops::Bound::Unbounded => 0, + }; + self.raw.drain(range).enumerate().map(move |(n, t)| (I::new(begin + n), t)) + } + + #[inline] + pub fn shrink_to_fit(&mut self) { + self.raw.shrink_to_fit() + } + + #[inline] + pub fn truncate(&mut self, a: usize) { + self.raw.truncate(a) + } + + pub fn convert_index_type(self) -> IndexVec { + IndexVec { raw: self.raw, _marker: PhantomData } + } + + /// Grows the index vector so that it contains an entry for + /// `elem`; if that is already true, then has no + /// effect. Otherwise, inserts new values as needed by invoking + /// `fill_value`. + #[inline] + pub fn ensure_contains_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) { + let min_new_len = elem.index() + 1; + if self.len() < min_new_len { + self.raw.resize_with(min_new_len, fill_value); + } + } + + #[inline] + pub fn resize_to_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) { + let min_new_len = elem.index() + 1; + self.raw.resize_with(min_new_len, fill_value); + } +} + +impl Deref for IndexVec { + type Target = IndexSlice; + + #[inline] + fn deref(&self) -> &Self::Target { + self.as_slice() + } +} + +impl DerefMut for IndexVec { + #[inline] + fn deref_mut(&mut self) -> &mut Self::Target { + self.as_mut_slice() + } +} + +impl IndexSlice { + #[inline] + pub fn from_raw(raw: &[T]) -> &Self { + let ptr: *const [T] = raw; + // SAFETY: `IndexSlice` is `repr(transparent)` over a normal slice + unsafe { &*(ptr as *const Self) } + } + + #[inline] + pub fn from_raw_mut(raw: &mut [T]) -> &mut Self { + let ptr: *mut [T] = raw; + // SAFETY: `IndexSlice` is `repr(transparent)` over a normal slice + unsafe { &mut *(ptr as *mut Self) } + } + + #[inline] + pub fn len(&self) -> usize { + self.raw.len() + } + + /// Gives the next index that will be assigned when `push` is called. + /// + /// Manual bounds checks can be done using `idx < slice.next_index()` + /// (as opposed to `idx.index() < slice.len()`). + #[inline] + pub fn next_index(&self) -> I { + I::new(self.len()) + } + + #[inline] + pub fn is_empty(&self) -> bool { + self.raw.is_empty() + } + #[inline] pub fn iter(&self) -> slice::Iter<'_, T> { self.raw.iter() @@ -194,47 +303,16 @@ impl IndexVec { self.raw.iter_mut().enumerate().map(|(n, t)| (I::new(n), t)) } - #[inline] - pub fn drain<'a, R: RangeBounds>( - &'a mut self, - range: R, - ) -> impl Iterator + 'a { - self.raw.drain(range) - } - - #[inline] - pub fn drain_enumerated<'a, R: RangeBounds>( - &'a mut self, - range: R, - ) -> impl Iterator + 'a { - let begin = match range.start_bound() { - std::ops::Bound::Included(i) => *i, - std::ops::Bound::Excluded(i) => i.checked_add(1).unwrap(), - std::ops::Bound::Unbounded => 0, - }; - self.raw.drain(range).enumerate().map(move |(n, t)| (I::new(begin + n), t)) - } - #[inline] pub fn last_index(&self) -> Option { self.len().checked_sub(1).map(I::new) } - #[inline] - pub fn shrink_to_fit(&mut self) { - self.raw.shrink_to_fit() - } - #[inline] pub fn swap(&mut self, a: I, b: I) { self.raw.swap(a.index(), b.index()) } - #[inline] - pub fn truncate(&mut self, a: usize) { - self.raw.truncate(a) - } - #[inline] pub fn get(&self, index: I) -> Option<&T> { self.raw.get(index.index()) @@ -274,28 +352,6 @@ impl IndexVec { let ptr = self.raw.as_mut_ptr(); unsafe { (&mut *ptr.add(ai), &mut *ptr.add(bi), &mut *ptr.add(ci)) } } - - pub fn convert_index_type(self) -> IndexVec { - IndexVec { raw: self.raw, _marker: PhantomData } - } - - /// Grows the index vector so that it contains an entry for - /// `elem`; if that is already true, then has no - /// effect. Otherwise, inserts new values as needed by invoking - /// `fill_value`. - #[inline] - pub fn ensure_contains_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) { - let min_new_len = elem.index() + 1; - if self.len() < min_new_len { - self.raw.resize_with(min_new_len, fill_value); - } - } - - #[inline] - pub fn resize_to_elem(&mut self, elem: I, fill_value: impl FnMut() -> T) { - let min_new_len = elem.index() + 1; - self.raw.resize_with(min_new_len, fill_value); - } } /// `IndexVec` is often used as a map, so it provides some map-like APIs. @@ -336,7 +392,7 @@ impl IndexVec { } } -impl Index for IndexVec { +impl Index for IndexSlice { type Output = T; #[inline] @@ -345,7 +401,7 @@ impl Index for IndexVec { } } -impl IndexMut for IndexVec { +impl IndexMut for IndexSlice { #[inline] fn index_mut(&mut self, index: I) -> &mut T { &mut self.raw[index.index()] @@ -359,6 +415,20 @@ impl Default for IndexVec { } } +impl Default for &IndexSlice { + #[inline] + fn default() -> Self { + IndexSlice::from_raw(Default::default()) + } +} + +impl Default for &mut IndexSlice { + #[inline] + fn default() -> Self { + IndexSlice::from_raw_mut(Default::default()) + } +} + impl Extend for IndexVec { #[inline] fn extend>(&mut self, iter: J) { @@ -418,5 +488,25 @@ impl<'a, I: Idx, T> IntoIterator for &'a mut IndexVec { } } +impl<'a, I: Idx, T> IntoIterator for &'a IndexSlice { + type Item = &'a T; + type IntoIter = slice::Iter<'a, T>; + + #[inline] + fn into_iter(self) -> slice::Iter<'a, T> { + self.raw.iter() + } +} + +impl<'a, I: Idx, T> IntoIterator for &'a mut IndexSlice { + type Item = &'a mut T; + type IntoIter = slice::IterMut<'a, T>; + + #[inline] + fn into_iter(self) -> slice::IterMut<'a, T> { + self.raw.iter_mut() + } +} + #[cfg(test)] mod tests; From 8d1bf505ff256a36be34f5f8ce676182ee0e5145 Mon Sep 17 00:00:00 2001 From: beetrees Date: Thu, 30 Mar 2023 15:15:42 +0100 Subject: [PATCH 298/346] Refactor glibc time64 support, riscv32 always has 64-bit `time_t` --- library/std/src/sys/unix/time.rs | 50 +++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/library/std/src/sys/unix/time.rs b/library/std/src/sys/unix/time.rs index 0f11de8f5b8..6f53583409d 100644 --- a/library/std/src/sys/unix/time.rs +++ b/library/std/src/sys/unix/time.rs @@ -174,6 +174,34 @@ impl From for Timespec { } } +#[cfg(all( + target_os = "linux", + target_env = "gnu", + target_pointer_width = "32", + not(target_arch = "riscv32") +))] +#[repr(C)] +pub(in crate::sys::unix) struct __timespec64 { + pub(in crate::sys::unix) tv_sec: i64, + #[cfg(target_endian = "big")] + _padding: i32, + pub(in crate::sys::unix) tv_nsec: i32, + #[cfg(target_endian = "little")] + _padding: i32, +} + +#[cfg(all( + target_os = "linux", + target_env = "gnu", + target_pointer_width = "32", + not(target_arch = "riscv32") +))] +impl From<__timespec64> for Timespec { + fn from(t: __timespec64) -> Timespec { + Timespec::new(t.tv_sec, t.tv_nsec.into()) + } +} + #[cfg(any( all(target_os = "macos", any(not(target_arch = "aarch64"))), target_os = "ios", @@ -352,29 +380,23 @@ mod inner { impl Timespec { pub fn now(clock: libc::clockid_t) -> Timespec { // Try to use 64-bit time in preparation for Y2038. - #[cfg(all(target_os = "linux", target_env = "gnu", target_pointer_width = "32"))] + #[cfg(all( + target_os = "linux", + target_env = "gnu", + target_pointer_width = "32", + not(target_arch = "riscv32") + ))] { use crate::sys::weak::weak; // __clock_gettime64 was added to 32-bit arches in glibc 2.34, // and it handles both vDSO calls and ENOSYS fallbacks itself. - weak!(fn __clock_gettime64(libc::clockid_t, *mut __timespec64) -> libc::c_int); - - #[repr(C)] - struct __timespec64 { - tv_sec: i64, - #[cfg(target_endian = "big")] - _padding: i32, - tv_nsec: i32, - #[cfg(target_endian = "little")] - _padding: i32, - } + weak!(fn __clock_gettime64(libc::clockid_t, *mut super::__timespec64) -> libc::c_int); if let Some(clock_gettime64) = __clock_gettime64.get() { let mut t = MaybeUninit::uninit(); cvt(unsafe { clock_gettime64(clock, t.as_mut_ptr()) }).unwrap(); - let t = unsafe { t.assume_init() }; - return Timespec::new(t.tv_sec, t.tv_nsec as i64); + return Timespec::from(unsafe { t.assume_init() }); } } From bdb0c7f427c2be88e77b28cf21452cefc847b009 Mon Sep 17 00:00:00 2001 From: Lukas Markeffsky <@> Date: Thu, 30 Mar 2023 22:19:28 +0200 Subject: [PATCH 299/346] add comment to `impl !Error for &str` --- library/core/src/str/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 2b23f64732b..04169429949 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -2655,5 +2655,6 @@ impl_fn_for_zst! { }; } +// This is required to make `impl From<&str> for Box` and `impl From for Box` not overlap. #[stable(feature = "rust1", since = "1.0.0")] impl !crate::error::Error for &str {} From f40aa598e97465feb753abbb18268a368ef0118e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 21 Mar 2023 16:43:51 +0100 Subject: [PATCH 300/346] Rename doc(primitive) into rustc_doc_primitive --- compiler/rustc_feature/src/active.rs | 2 +- compiler/rustc_feature/src/builtin_attrs.rs | 4 ++++ compiler/rustc_passes/messages.ftl | 3 --- compiler/rustc_passes/src/check_attr.rs | 11 ----------- compiler/rustc_passes/src/errors.rs | 4 ---- compiler/rustc_span/src/symbol.rs | 1 + 6 files changed, 6 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index b7d280b8751..b62da63644d 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -225,7 +225,7 @@ declare_features! ( (active, rustc_allow_const_fn_unstable, "1.49.0", Some(69399), None), /// Allows using compiler's own crates. (active, rustc_private, "1.0.0", Some(27812), None), - /// Allows using internal rustdoc features like `doc(primitive)` or `doc(keyword)`. + /// Allows using internal rustdoc features like `doc(keyword)`. (active, rustdoc_internals, "1.58.0", Some(90418), None), /// Allows using the `rustdoc::missing_doc_code_examples` lint (active, rustdoc_missing_doc_code_examples, "1.31.0", Some(101730), None), diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 493a9cd89e3..c77292fdd16 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -778,6 +778,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ definition of a trait, it's currently in experimental form and should be changed before \ being exposed outside of the std" ), + rustc_attr!( + rustc_doc_primitive, Normal, template!(NameValueStr: "primitive name"), ErrorFollowing, + r#"`rustc_doc_primitive` is a rustc internal attribute"#, + ), // ========================================================================== // Internal attributes, Testing: diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index d063b51c8b8..b354dca7cc4 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -148,9 +148,6 @@ passes_doc_test_unknown = passes_doc_test_takes_list = `#[doc(test(...)]` takes a list of attributes -passes_doc_primitive = - `doc(primitive)` should never have been stable - passes_doc_cfg_hide_takes_list = `#[doc(cfg_hide(...)]` takes a list of attributes diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 1c459edabb8..80a93da2b45 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1109,17 +1109,6 @@ impl CheckAttrVisitor<'_> { } } - sym::primitive => { - if !self.tcx.features().rustdoc_internals { - self.tcx.emit_spanned_lint( - INVALID_DOC_ATTRIBUTES, - hir_id, - i_meta.span, - errors::DocPrimitive, - ); - } - } - _ => { let path = rustc_ast_pretty::pprust::path_to_string(&i_meta.path); if i_meta.has_name(sym::spotlight) { diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 1b0cd5d91ab..139ba8c9677 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -288,10 +288,6 @@ pub struct DocTestTakesList; #[diag(passes_doc_cfg_hide_takes_list)] pub struct DocCfgHideTakesList; -#[derive(LintDiagnostic)] -#[diag(passes_doc_primitive)] -pub struct DocPrimitive; - #[derive(LintDiagnostic)] #[diag(passes_doc_test_unknown_any)] pub struct DocTestUnknownAny { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 0ed99353145..f08f84a2a12 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1245,6 +1245,7 @@ symbols! { rustc_diagnostic_macros, rustc_dirty, rustc_do_not_const_check, + rustc_doc_primitive, rustc_dummy, rustc_dump_env_program_clauses, rustc_dump_program_clauses, From 3ef8d2d6075bcac4975b271684ebc6e67c20c83e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 21 Mar 2023 16:44:06 +0100 Subject: [PATCH 301/346] Update tests for rustc_doc_primitive --- .../impls/local_for_local_primitive.rs | 4 ++-- tests/rustdoc-json/primitives/local_primitive.rs | 2 +- tests/rustdoc-json/primitives/primitive_impls.rs | 2 +- .../primitives/primitive_overloading.rs | 4 ++-- tests/rustdoc-json/primitives/use_primitive.rs | 4 ++-- tests/rustdoc-ui/coverage/exotic.rs | 3 ++- tests/rustdoc/auto-impl-primitive.rs | 4 ++-- tests/rustdoc/auxiliary/issue-15318.rs | 3 ++- tests/rustdoc/auxiliary/primitive-doc.rs | 3 ++- tests/rustdoc/check-source-code-urls-to-def.rs | 4 ++-- tests/rustdoc/intra-doc/auxiliary/my-core.rs | 2 +- tests/rustdoc/intra-doc/no-doc-primitive.rs | 2 +- tests/rustdoc/intra-doc/prim-methods-local.rs | 2 +- tests/rustdoc/intra-doc/prim-self.rs | 2 +- tests/rustdoc/issue-15318-3.rs | 4 ++-- tests/rustdoc/issue-23511.rs | 2 +- .../doc-notable_trait-mut_t_is_not_an_iterator.rs | 4 ++-- .../doc-notable_trait-mut_t_is_not_ref_t.rs | 4 ++-- tests/rustdoc/primitive-reference.rs | 4 ++-- tests/rustdoc/primitive-slice-auto-trait.rs | 4 ++-- tests/rustdoc/primitive-tuple-auto-trait.rs | 4 ++-- tests/rustdoc/primitive-unit-auto-trait.rs | 4 ++-- tests/rustdoc/primitive/primitive-generic-impl.rs | 4 ++-- tests/rustdoc/primitive/primitive.rs | 6 +++--- tests/rustdoc/sidebar-all-page.rs | 4 ++-- tests/rustdoc/tab_title.rs | 3 ++- tests/rustdoc/titles.rs | 4 ++-- tests/ui/rustdoc/feature-gate-doc_primitive.rs | 6 ++---- .../ui/rustdoc/feature-gate-doc_primitive.stderr | 15 +++++++-------- 29 files changed, 57 insertions(+), 56 deletions(-) diff --git a/tests/rustdoc-json/impls/local_for_local_primitive.rs b/tests/rustdoc-json/impls/local_for_local_primitive.rs index 38e7e2658df..8383dcc0482 100644 --- a/tests/rustdoc-json/impls/local_for_local_primitive.rs +++ b/tests/rustdoc-json/impls/local_for_local_primitive.rs @@ -1,5 +1,5 @@ #![feature(no_core)] -#![feature(rustdoc_internals)] +#![feature(rustc_attrs)] #![no_core] // @set Local = "$.index[*][?(@.name=='Local')].id" @@ -16,6 +16,6 @@ impl Local for bool {} // FIXME(#101695): Test bool's `impls` include "Local for bool" // @has "$.index[*][?(@.name=='bool')]" -#[doc(primitive = "bool")] +#[rustc_doc_primitive = "bool"] /// Boolean docs mod prim_bool {} diff --git a/tests/rustdoc-json/primitives/local_primitive.rs b/tests/rustdoc-json/primitives/local_primitive.rs index f27e6a2adec..0cf479faf29 100644 --- a/tests/rustdoc-json/primitives/local_primitive.rs +++ b/tests/rustdoc-json/primitives/local_primitive.rs @@ -8,7 +8,7 @@ //! Link to [i32][prim@i32] [i64][prim@i64] -#[doc(primitive = "i32")] +#[rustc_doc_primitive = "i32"] mod prim_i32 {} // @set local_i32 = "$.index[*][?(@.name=='i32')].id" diff --git a/tests/rustdoc-json/primitives/primitive_impls.rs b/tests/rustdoc-json/primitives/primitive_impls.rs index 1fc9374065f..85d179ee45f 100644 --- a/tests/rustdoc-json/primitives/primitive_impls.rs +++ b/tests/rustdoc-json/primitives/primitive_impls.rs @@ -25,7 +25,7 @@ pub trait Trait {} impl Trait for i32 {} /// i32 -#[doc(primitive = "i32")] +#[rustc_doc_primitive = "i32"] mod prim_i32 {} // @set i32 = "$.index[*][?(@.docs=='i32')].id" diff --git a/tests/rustdoc-json/primitives/primitive_overloading.rs b/tests/rustdoc-json/primitives/primitive_overloading.rs index 56b35cd14c0..81e0acdc6e9 100644 --- a/tests/rustdoc-json/primitives/primitive_overloading.rs +++ b/tests/rustdoc-json/primitives/primitive_overloading.rs @@ -2,7 +2,7 @@ // Regression test for . -#![feature(rustdoc_internals)] +#![feature(rustc_attrs)] #![feature(no_core)] #![no_core] @@ -10,7 +10,7 @@ // @has "$.index[*][?(@.name=='usize')]" // @has "$.index[*][?(@.name=='prim')]" -#[doc(primitive = "usize")] +#[rustc_doc_primitive = "usize"] /// This is the built-in type `usize`. mod prim { } diff --git a/tests/rustdoc-json/primitives/use_primitive.rs b/tests/rustdoc-json/primitives/use_primitive.rs index e2292737462..5180a804f07 100644 --- a/tests/rustdoc-json/primitives/use_primitive.rs +++ b/tests/rustdoc-json/primitives/use_primitive.rs @@ -1,8 +1,8 @@ // edition:2018 -#![feature(rustdoc_internals)] +#![feature(rustc_attrs)] -#[doc(primitive = "usize")] +#[rustc_doc_primitive = "usize"] mod usize {} // @set local_crate_id = "$.index[*][?(@.name=='use_primitive')].crate_id" diff --git a/tests/rustdoc-ui/coverage/exotic.rs b/tests/rustdoc-ui/coverage/exotic.rs index 72b70d6980b..f45405fbf5d 100644 --- a/tests/rustdoc-ui/coverage/exotic.rs +++ b/tests/rustdoc-ui/coverage/exotic.rs @@ -2,12 +2,13 @@ // check-pass #![feature(rustdoc_internals)] +#![feature(rustc_attrs)] //! the features only used in std also have entries in the table, so make sure those get pulled out //! properly as well /// woo, check it out, we can write our own primitive docs lol -#[doc(primitive="unit")] +#[rustc_doc_primitive = "unit"] mod prim_unit {} /// keywords? sure, pile them on diff --git a/tests/rustdoc/auto-impl-primitive.rs b/tests/rustdoc/auto-impl-primitive.rs index 172333d445d..a6db93dbc33 100644 --- a/tests/rustdoc/auto-impl-primitive.rs +++ b/tests/rustdoc/auto-impl-primitive.rs @@ -1,10 +1,10 @@ -#![feature(rustdoc_internals)] +#![feature(rustc_attrs)] #![crate_name = "foo"] pub use std::fs::File; // @has 'foo/primitive.i16.html' '//h2[@id="synthetic-implementations"]' 'Auto Trait Implementation' -#[doc(primitive = "i16")] +#[rustc_doc_primitive = "i16"] /// I love poneys! mod prim {} diff --git a/tests/rustdoc/auxiliary/issue-15318.rs b/tests/rustdoc/auxiliary/issue-15318.rs index 695fa58ef1d..a2f426c6352 100644 --- a/tests/rustdoc/auxiliary/issue-15318.rs +++ b/tests/rustdoc/auxiliary/issue-15318.rs @@ -2,6 +2,7 @@ // compile-flags: -Cmetadata=aux #![crate_type = "rlib"] #![doc(html_root_url = "http://example.com/")] +#![feature(rustc_attrs)] #![feature(lang_items)] #![no_std] @@ -12,5 +13,5 @@ fn foo() {} fn bar(_: &core::panic::PanicInfo) -> ! { loop {} } /// dox -#[doc(primitive = "pointer")] +#[rustc_doc_primitive = "pointer"] pub mod ptr {} diff --git a/tests/rustdoc/auxiliary/primitive-doc.rs b/tests/rustdoc/auxiliary/primitive-doc.rs index e8da852a57e..d1785e42391 100644 --- a/tests/rustdoc/auxiliary/primitive-doc.rs +++ b/tests/rustdoc/auxiliary/primitive-doc.rs @@ -1,9 +1,10 @@ // compile-flags: --crate-type lib --edition 2018 +#![feature(rustc_attrs)] #![feature(no_core)] #![no_core] -#[doc(primitive = "usize")] +#[rustc_doc_primitive = "usize"] /// This is the built-in type `usize`. mod usize { } diff --git a/tests/rustdoc/check-source-code-urls-to-def.rs b/tests/rustdoc/check-source-code-urls-to-def.rs index 5959f9c7c59..41b9d41fa44 100644 --- a/tests/rustdoc/check-source-code-urls-to-def.rs +++ b/tests/rustdoc/check-source-code-urls-to-def.rs @@ -2,7 +2,7 @@ // aux-build:source_code.rs // build-aux-docs -#![feature(rustdoc_internals)] +#![feature(rustc_attrs)] #![crate_name = "foo"] @@ -65,5 +65,5 @@ pub fn foo4() { } // @has - '//pre[@class="rust"]//a[@href="../../foo/primitive.bool.html"]' 'bool' -#[doc(primitive = "bool")] +#[rustc_doc_primitive = "bool"] mod whatever {} diff --git a/tests/rustdoc/intra-doc/auxiliary/my-core.rs b/tests/rustdoc/intra-doc/auxiliary/my-core.rs index e22feb03ae6..c050929db96 100644 --- a/tests/rustdoc/intra-doc/auxiliary/my-core.rs +++ b/tests/rustdoc/intra-doc/auxiliary/my-core.rs @@ -3,7 +3,7 @@ #![rustc_coherence_is_core] #![crate_type="rlib"] -#[doc(primitive = "char")] +#[rustc_doc_primitive = "char"] /// Some char docs mod char {} diff --git a/tests/rustdoc/intra-doc/no-doc-primitive.rs b/tests/rustdoc/intra-doc/no-doc-primitive.rs index e5eba1d8d48..711ac09ba9a 100644 --- a/tests/rustdoc/intra-doc/no-doc-primitive.rs +++ b/tests/rustdoc/intra-doc/no-doc-primitive.rs @@ -1,4 +1,4 @@ -// Crate tree without a `doc(primitive)` module for primitive type linked to by a doc link. +// Crate tree without a `rustc_doc_primitive` module for primitive type linked to by a doc link. #![deny(rustdoc::broken_intra_doc_links)] #![feature(no_core, lang_items, rustc_attrs)] diff --git a/tests/rustdoc/intra-doc/prim-methods-local.rs b/tests/rustdoc/intra-doc/prim-methods-local.rs index 79d8df04515..6de4ec1802f 100644 --- a/tests/rustdoc/intra-doc/prim-methods-local.rs +++ b/tests/rustdoc/intra-doc/prim-methods-local.rs @@ -10,7 +10,7 @@ //! A [prim@`char`] and its [`char::len_utf8`]. -#[doc(primitive = "char")] +#[rustc_doc_primitive = "char"] mod char {} impl char { diff --git a/tests/rustdoc/intra-doc/prim-self.rs b/tests/rustdoc/intra-doc/prim-self.rs index c7ce71b15f3..d13858a53cf 100644 --- a/tests/rustdoc/intra-doc/prim-self.rs +++ b/tests/rustdoc/intra-doc/prim-self.rs @@ -25,7 +25,7 @@ impl usize { pub type ME = usize; } -#[doc(primitive = "usize")] +#[rustc_doc_primitive = "usize"] /// This has some docs. mod usize {} diff --git a/tests/rustdoc/issue-15318-3.rs b/tests/rustdoc/issue-15318-3.rs index 2fadc26b006..2dab8f94883 100644 --- a/tests/rustdoc/issue-15318-3.rs +++ b/tests/rustdoc/issue-15318-3.rs @@ -1,7 +1,7 @@ -#![feature(rustdoc_internals)] +#![feature(rustc_attrs)] // @has issue_15318_3/primitive.pointer.html /// dox -#[doc(primitive = "pointer")] +#[rustc_doc_primitive = "pointer"] pub mod ptr {} diff --git a/tests/rustdoc/issue-23511.rs b/tests/rustdoc/issue-23511.rs index 7576ebb0305..21d02842431 100644 --- a/tests/rustdoc/issue-23511.rs +++ b/tests/rustdoc/issue-23511.rs @@ -3,7 +3,7 @@ #![no_std] pub mod str { - #![doc(primitive = "str")] + #![rustc_doc_primitive = "str"] impl str { // @hasraw search-index.js foo diff --git a/tests/rustdoc/notable-trait/doc-notable_trait-mut_t_is_not_an_iterator.rs b/tests/rustdoc/notable-trait/doc-notable_trait-mut_t_is_not_an_iterator.rs index bfce46cf444..5af5f7616b5 100644 --- a/tests/rustdoc/notable-trait/doc-notable_trait-mut_t_is_not_an_iterator.rs +++ b/tests/rustdoc/notable-trait/doc-notable_trait-mut_t_is_not_an_iterator.rs @@ -6,10 +6,10 @@ //! //! [#80737]: https://github.com/rust-lang/rust/issues/80737 -#![feature(rustdoc_internals)] +#![feature(rustc_attrs)] #![no_std] -#[doc(primitive = "reference")] +#[rustc_doc_primitive = "reference"] /// Some useless docs, wouhou! /// /// We need to put this in here, because notable traits diff --git a/tests/rustdoc/notable-trait/doc-notable_trait-mut_t_is_not_ref_t.rs b/tests/rustdoc/notable-trait/doc-notable_trait-mut_t_is_not_ref_t.rs index b359dcea0ff..6c980aaa2b1 100644 --- a/tests/rustdoc/notable-trait/doc-notable_trait-mut_t_is_not_ref_t.rs +++ b/tests/rustdoc/notable-trait/doc-notable_trait-mut_t_is_not_ref_t.rs @@ -5,9 +5,9 @@ //! //! [#78160]: https://github.com/rust-lang/rust/issues/78160 -#![feature(rustdoc_internals)] +#![feature(rustc_attrs)] -#[doc(primitive = "reference")] +#[rustc_doc_primitive = "reference"] /// Some useless docs, wouhou! /// /// We need to put this in here, because notable traits diff --git a/tests/rustdoc/primitive-reference.rs b/tests/rustdoc/primitive-reference.rs index 10efbefd2b1..6f034224df5 100644 --- a/tests/rustdoc/primitive-reference.rs +++ b/tests/rustdoc/primitive-reference.rs @@ -1,6 +1,6 @@ #![crate_name = "foo"] -#![feature(rustdoc_internals)] +#![feature(rustc_attrs)] // @has foo/index.html // @has - '//h2[@id="primitives"]' 'Primitive Types' @@ -16,7 +16,7 @@ // @count - '//*[@class="impl"]' 1 // @has - '//*[@id="impl-Foo%3C%26A%3E-for-%26B"]/*[@class="code-header"]' \ // 'impl Foo<&A> for &B' -#[doc(primitive = "reference")] +#[rustc_doc_primitive = "reference"] /// this is a test! mod reference {} diff --git a/tests/rustdoc/primitive-slice-auto-trait.rs b/tests/rustdoc/primitive-slice-auto-trait.rs index 77922414676..ba15a73ca1d 100644 --- a/tests/rustdoc/primitive-slice-auto-trait.rs +++ b/tests/rustdoc/primitive-slice-auto-trait.rs @@ -1,7 +1,7 @@ // compile-flags: --crate-type lib --edition 2018 #![crate_name = "foo"] -#![feature(rustdoc_internals)] +#![feature(rustc_attrs)] // @has foo/primitive.slice.html '//a[@class="primitive"]' 'slice' // @has - '//h1' 'Primitive Type slice' @@ -9,6 +9,6 @@ // @has - '//h2[@id="synthetic-implementations"]' 'Auto Trait Implementations' // @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl Send for [T]where T: Send' // @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl Sync for [T]where T: Sync' -#[doc(primitive = "slice")] +#[rustc_doc_primitive = "slice"] /// this is a test! mod slice_prim {} diff --git a/tests/rustdoc/primitive-tuple-auto-trait.rs b/tests/rustdoc/primitive-tuple-auto-trait.rs index 4344d24f986..2b407b586a3 100644 --- a/tests/rustdoc/primitive-tuple-auto-trait.rs +++ b/tests/rustdoc/primitive-tuple-auto-trait.rs @@ -1,7 +1,7 @@ // compile-flags: --crate-type lib --edition 2018 #![crate_name = "foo"] -#![feature(rustdoc_internals)] +#![feature(rustc_attrs)] // @has foo/primitive.tuple.html '//a[@class="primitive"]' 'tuple' // @has - '//h1' 'Primitive Type tuple' @@ -9,7 +9,7 @@ // @has - '//h2[@id="synthetic-implementations"]' 'Auto Trait Implementations' // @has - '//div[@id="synthetic-implementations-list"]//h3' 'Send' // @has - '//div[@id="synthetic-implementations-list"]//h3' 'Sync' -#[doc(primitive = "tuple")] +#[rustc_doc_primitive = "tuple"] /// this is a test! /// // Hardcoded anchor to header written in library/core/src/primitive_docs.rs diff --git a/tests/rustdoc/primitive-unit-auto-trait.rs b/tests/rustdoc/primitive-unit-auto-trait.rs index 61850e2462d..5a56f1fd83b 100644 --- a/tests/rustdoc/primitive-unit-auto-trait.rs +++ b/tests/rustdoc/primitive-unit-auto-trait.rs @@ -1,7 +1,7 @@ // compile-flags: --crate-type lib --edition 2018 #![crate_name = "foo"] -#![feature(rustdoc_internals)] +#![feature(rustc_attrs)] // @has foo/primitive.unit.html '//a[@class="primitive"]' 'unit' // @has - '//h1' 'Primitive Type unit' @@ -9,6 +9,6 @@ // @has - '//h2[@id="synthetic-implementations"]' 'Auto Trait Implementations' // @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl Send for ()' // @has - '//div[@id="synthetic-implementations-list"]//h3' 'impl Sync for ()' -#[doc(primitive = "unit")] +#[rustc_doc_primitive = "unit"] /// this is a test! mod unit_prim {} diff --git a/tests/rustdoc/primitive/primitive-generic-impl.rs b/tests/rustdoc/primitive/primitive-generic-impl.rs index 7b336b39810..2da8ae6ff38 100644 --- a/tests/rustdoc/primitive/primitive-generic-impl.rs +++ b/tests/rustdoc/primitive/primitive-generic-impl.rs @@ -1,8 +1,8 @@ -#![feature(rustdoc_internals)] +#![feature(rustc_attrs)] #![crate_name = "foo"] // @has foo/primitive.i32.html '//*[@id="impl-ToString-for-i32"]//h3[@class="code-header"]' 'impl ToString for T' -#[doc(primitive = "i32")] +#[rustc_doc_primitive = "i32"] /// Some useless docs, wouhou! mod i32 {} diff --git a/tests/rustdoc/primitive/primitive.rs b/tests/rustdoc/primitive/primitive.rs index 516c7c0c6fe..32af2636c18 100644 --- a/tests/rustdoc/primitive/primitive.rs +++ b/tests/rustdoc/primitive/primitive.rs @@ -1,6 +1,6 @@ #![crate_name = "foo"] -#![feature(rustdoc_internals)] +#![feature(rustc_attrs)] // @has foo/index.html '//h2[@id="primitives"]' 'Primitive Types' // @has foo/index.html '//a[@href="primitive.i32.html"]' 'i32' @@ -11,11 +11,11 @@ // @has foo/primitive.i32.html '//section[@id="main-content"]//div[@class="docblock"]//p' 'this is a test!' // @has foo/index.html '//a/@href' '../foo/index.html' // @!has foo/index.html '//span' '🔒' -#[doc(primitive = "i32")] +#[rustc_doc_primitive = "i32"] /// this is a test! mod i32{} // @has foo/primitive.bool.html '//section[@id="main-content"]//div[@class="docblock"]//p' 'hello' -#[doc(primitive = "bool")] +#[rustc_doc_primitive = "bool"] /// hello mod bool {} diff --git a/tests/rustdoc/sidebar-all-page.rs b/tests/rustdoc/sidebar-all-page.rs index e74b981de64..45a6ba8ed2e 100644 --- a/tests/rustdoc/sidebar-all-page.rs +++ b/tests/rustdoc/sidebar-all-page.rs @@ -1,6 +1,6 @@ #![crate_name = "foo"] -#![feature(rustdoc_internals)] +#![feature(rustc_attrs)] // @has 'foo/all.html' // @has - '//*[@class="sidebar-elems"]//li' 'Structs' @@ -31,5 +31,5 @@ macro_rules! foo { pub type Type = u8; pub const FOO: u8 = 0; pub static BAR: u8 = 0; -#[doc(primitive = "u8")] +#[rustc_doc_primitive = "u8"] mod u8 {} diff --git a/tests/rustdoc/tab_title.rs b/tests/rustdoc/tab_title.rs index 0cc4f147e1c..8d781b40e46 100644 --- a/tests/rustdoc/tab_title.rs +++ b/tests/rustdoc/tab_title.rs @@ -1,4 +1,5 @@ #![crate_name = "foo"] +#![feature(rustc_attrs)] #![feature(rustdoc_internals)] // tests for the html element @@ -39,6 +40,6 @@ mod continue_keyword {} // @has foo/primitive.u8.html '//head/title' 'u8 - Rust' // @!has - '//head/title' 'foo' -#[doc(primitive = "u8")] +#[rustc_doc_primitive = "u8"] /// `u8` docs mod u8 {} diff --git a/tests/rustdoc/titles.rs b/tests/rustdoc/titles.rs index 69e8b856b0a..e1feb1cd64f 100644 --- a/tests/rustdoc/titles.rs +++ b/tests/rustdoc/titles.rs @@ -1,5 +1,5 @@ #![crate_name = "foo"] -#![feature(rustdoc_internals)] +#![feature(rustc_attrs)] // @matches 'foo/index.html' '//h1' 'Crate foo' // @matches 'foo/index.html' '//h2[@class="location"]' 'Crate foo' @@ -41,7 +41,7 @@ macro_rules! foo_macro { } // @matches 'foo/primitive.bool.html' '//h1' 'Primitive Type bool' -#[doc(primitive = "bool")] +#[rustc_doc_primitive = "bool"] mod bool {} // @matches 'foo/static.FOO_STATIC.html' '//h1' 'Static foo::FOO_STATIC' diff --git a/tests/ui/rustdoc/feature-gate-doc_primitive.rs b/tests/ui/rustdoc/feature-gate-doc_primitive.rs index 18e99e72f8b..78fcd90752e 100644 --- a/tests/ui/rustdoc/feature-gate-doc_primitive.rs +++ b/tests/ui/rustdoc/feature-gate-doc_primitive.rs @@ -1,7 +1,5 @@ -// check-pass -#[doc(primitive = "usize")] -//~^ WARNING `doc(primitive)` should never have been stable -//~| WARNING hard error in a future release +#[rustc_doc_primitive = "usize"] +//~^ ERROR `rustc_doc_primitive` is a rustc internal attribute /// Some docs mod usize {} diff --git a/tests/ui/rustdoc/feature-gate-doc_primitive.stderr b/tests/ui/rustdoc/feature-gate-doc_primitive.stderr index 194b2d87db2..5920880675d 100644 --- a/tests/ui/rustdoc/feature-gate-doc_primitive.stderr +++ b/tests/ui/rustdoc/feature-gate-doc_primitive.stderr @@ -1,12 +1,11 @@ -warning: `doc(primitive)` should never have been stable - --> $DIR/feature-gate-doc_primitive.rs:2:7 +error[E0658]: `rustc_doc_primitive` is a rustc internal attribute + --> $DIR/feature-gate-doc_primitive.rs:1:1 | -LL | #[doc(primitive = "usize")] - | ^^^^^^^^^^^^^^^^^^^ +LL | #[rustc_doc_primitive = "usize"] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> - = note: `#[warn(invalid_doc_attributes)]` on by default + = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable -warning: 1 warning emitted +error: aborting due to previous error +For more information about this error, try `rustc --explain E0658`. From 364e961417c4308f8a1d3b7ec69ead9d98af2a01 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez <guillaume.gomez@huawei.com> Date: Tue, 21 Mar 2023 16:52:59 +0100 Subject: [PATCH 302/346] Replace doc(primitive) with rustc_doc_primitive --- library/core/src/primitive_docs.rs | 75 ++++++++++++------- library/std/src/primitive_docs.rs | 75 ++++++++++++------- src/librustdoc/clean/types.rs | 37 +++++---- src/librustdoc/json/conversions.rs | 4 +- src/librustdoc/json/mod.rs | 2 +- .../passes/collect_intra_doc_links.rs | 6 +- 6 files changed, 123 insertions(+), 76 deletions(-) diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs index e12a3e378a6..bf8339335dd 100644 --- a/library/core/src/primitive_docs.rs +++ b/library/core/src/primitive_docs.rs @@ -1,7 +1,8 @@ // `library/{std,core}/src/primitive_docs.rs` should have the same contents. // These are different files so that relative links work properly without // having to have `CARGO_PKG_NAME` set, but conceptually they should always be the same. -#[doc(primitive = "bool")] +#[cfg_attr(bootstrap, doc(primitive = "bool"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "bool")] #[doc(alias = "true")] #[doc(alias = "false")] /// The boolean type. @@ -63,7 +64,8 @@ #[stable(feature = "rust1", since = "1.0.0")] mod prim_bool {} -#[doc(primitive = "never")] +#[cfg_attr(bootstrap, doc(primitive = "never"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "never")] #[doc(alias = "!")] // /// The `!` type, also called "never". @@ -274,7 +276,8 @@ mod prim_bool {} #[unstable(feature = "never_type", issue = "35121")] mod prim_never {} -#[doc(primitive = "char")] +#[cfg_attr(bootstrap, doc(primitive = "char"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "char")] #[allow(rustdoc::invalid_rust_codeblocks)] /// A character type. /// @@ -398,7 +401,8 @@ mod prim_never {} #[stable(feature = "rust1", since = "1.0.0")] mod prim_char {} -#[doc(primitive = "unit")] +#[cfg_attr(bootstrap, doc(primitive = "unit"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "unit")] #[doc(alias = "(")] #[doc(alias = ")")] #[doc(alias = "()")] @@ -460,7 +464,8 @@ impl Copy for () { // empty } -#[doc(primitive = "pointer")] +#[cfg_attr(bootstrap, doc(primitive = "pointer"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "pointer")] #[doc(alias = "ptr")] #[doc(alias = "*")] #[doc(alias = "*const")] @@ -577,7 +582,8 @@ impl Copy for () { #[stable(feature = "rust1", since = "1.0.0")] mod prim_pointer {} -#[doc(primitive = "array")] +#[cfg_attr(bootstrap, doc(primitive = "array"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "array")] #[doc(alias = "[]")] #[doc(alias = "[T;N]")] // unfortunately, rustdoc doesn't have fuzzy search for aliases #[doc(alias = "[T; N]")] @@ -778,7 +784,8 @@ mod prim_pointer {} #[stable(feature = "rust1", since = "1.0.0")] mod prim_array {} -#[doc(primitive = "slice")] +#[cfg_attr(bootstrap, doc(primitive = "slice"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "slice")] #[doc(alias = "[")] #[doc(alias = "]")] #[doc(alias = "[]")] @@ -870,7 +877,8 @@ mod prim_array {} #[stable(feature = "rust1", since = "1.0.0")] mod prim_slice {} -#[doc(primitive = "str")] +#[cfg_attr(bootstrap, doc(primitive = "str"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "str")] /// String slices. /// /// *[See also the `std::str` module](crate::str).* @@ -937,7 +945,8 @@ mod prim_slice {} #[stable(feature = "rust1", since = "1.0.0")] mod prim_str {} -#[doc(primitive = "tuple")] +#[cfg_attr(bootstrap, doc(primitive = "tuple"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "tuple")] #[doc(alias = "(")] #[doc(alias = ")")] #[doc(alias = "()")] @@ -1081,7 +1090,8 @@ impl<T: Copy> Copy for (T,) { // empty } -#[doc(primitive = "f32")] +#[cfg_attr(bootstrap, doc(primitive = "f32"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "f32")] /// A 32-bit floating point type (specifically, the "binary32" type defined in IEEE 754-2008). /// /// This type can represent a wide range of decimal numbers, like `3.5`, `27`, @@ -1147,7 +1157,8 @@ impl<T: Copy> Copy for (T,) { #[stable(feature = "rust1", since = "1.0.0")] mod prim_f32 {} -#[doc(primitive = "f64")] +#[cfg_attr(bootstrap, doc(primitive = "f64"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "f64")] /// A 64-bit floating point type (specifically, the "binary64" type defined in IEEE 754-2008). /// /// This type is very similar to [`f32`], but has increased @@ -1162,67 +1173,78 @@ mod prim_f32 {} #[stable(feature = "rust1", since = "1.0.0")] mod prim_f64 {} -#[doc(primitive = "i8")] +#[cfg_attr(bootstrap, doc(primitive = "i8"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "i8")] // /// The 8-bit signed integer type. #[stable(feature = "rust1", since = "1.0.0")] mod prim_i8 {} -#[doc(primitive = "i16")] +#[cfg_attr(bootstrap, doc(primitive = "i16"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "i16")] // /// The 16-bit signed integer type. #[stable(feature = "rust1", since = "1.0.0")] mod prim_i16 {} -#[doc(primitive = "i32")] +#[cfg_attr(bootstrap, doc(primitive = "i32"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "i32")] // /// The 32-bit signed integer type. #[stable(feature = "rust1", since = "1.0.0")] mod prim_i32 {} -#[doc(primitive = "i64")] +#[cfg_attr(bootstrap, doc(primitive = "i64"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "i64")] // /// The 64-bit signed integer type. #[stable(feature = "rust1", since = "1.0.0")] mod prim_i64 {} -#[doc(primitive = "i128")] +#[cfg_attr(bootstrap, doc(primitive = "i128"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "i128")] // /// The 128-bit signed integer type. #[stable(feature = "i128", since = "1.26.0")] mod prim_i128 {} -#[doc(primitive = "u8")] +#[cfg_attr(bootstrap, doc(primitive = "u8"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "u8")] // /// The 8-bit unsigned integer type. #[stable(feature = "rust1", since = "1.0.0")] mod prim_u8 {} -#[doc(primitive = "u16")] +#[cfg_attr(bootstrap, doc(primitive = "u16"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "u16")] // /// The 16-bit unsigned integer type. #[stable(feature = "rust1", since = "1.0.0")] mod prim_u16 {} -#[doc(primitive = "u32")] +#[cfg_attr(bootstrap, doc(primitive = "u32"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "u32")] // /// The 32-bit unsigned integer type. #[stable(feature = "rust1", since = "1.0.0")] mod prim_u32 {} -#[doc(primitive = "u64")] +#[cfg_attr(bootstrap, doc(primitive = "u64"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "u64")] // /// The 64-bit unsigned integer type. #[stable(feature = "rust1", since = "1.0.0")] mod prim_u64 {} -#[doc(primitive = "u128")] +#[cfg_attr(bootstrap, doc(primitive = "u128"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "u128")] // /// The 128-bit unsigned integer type. #[stable(feature = "i128", since = "1.26.0")] mod prim_u128 {} -#[doc(primitive = "isize")] +#[cfg_attr(bootstrap, doc(primitive = "isize"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "isize")] // /// The pointer-sized signed integer type. /// @@ -1232,7 +1254,8 @@ mod prim_u128 {} #[stable(feature = "rust1", since = "1.0.0")] mod prim_isize {} -#[doc(primitive = "usize")] +#[cfg_attr(bootstrap, doc(primitive = "usize"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "usize")] // /// The pointer-sized unsigned integer type. /// @@ -1242,7 +1265,8 @@ mod prim_isize {} #[stable(feature = "rust1", since = "1.0.0")] mod prim_usize {} -#[doc(primitive = "reference")] +#[cfg_attr(bootstrap, doc(primitive = "reference"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "reference")] #[doc(alias = "&")] #[doc(alias = "&mut")] // @@ -1373,7 +1397,8 @@ mod prim_usize {} #[stable(feature = "rust1", since = "1.0.0")] mod prim_ref {} -#[doc(primitive = "fn")] +#[cfg_attr(bootstrap, doc(primitive = "fn"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "fn")] // /// Function pointers, like `fn(usize) -> bool`. /// diff --git a/library/std/src/primitive_docs.rs b/library/std/src/primitive_docs.rs index e12a3e378a6..bf8339335dd 100644 --- a/library/std/src/primitive_docs.rs +++ b/library/std/src/primitive_docs.rs @@ -1,7 +1,8 @@ // `library/{std,core}/src/primitive_docs.rs` should have the same contents. // These are different files so that relative links work properly without // having to have `CARGO_PKG_NAME` set, but conceptually they should always be the same. -#[doc(primitive = "bool")] +#[cfg_attr(bootstrap, doc(primitive = "bool"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "bool")] #[doc(alias = "true")] #[doc(alias = "false")] /// The boolean type. @@ -63,7 +64,8 @@ #[stable(feature = "rust1", since = "1.0.0")] mod prim_bool {} -#[doc(primitive = "never")] +#[cfg_attr(bootstrap, doc(primitive = "never"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "never")] #[doc(alias = "!")] // /// The `!` type, also called "never". @@ -274,7 +276,8 @@ mod prim_bool {} #[unstable(feature = "never_type", issue = "35121")] mod prim_never {} -#[doc(primitive = "char")] +#[cfg_attr(bootstrap, doc(primitive = "char"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "char")] #[allow(rustdoc::invalid_rust_codeblocks)] /// A character type. /// @@ -398,7 +401,8 @@ mod prim_never {} #[stable(feature = "rust1", since = "1.0.0")] mod prim_char {} -#[doc(primitive = "unit")] +#[cfg_attr(bootstrap, doc(primitive = "unit"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "unit")] #[doc(alias = "(")] #[doc(alias = ")")] #[doc(alias = "()")] @@ -460,7 +464,8 @@ impl Copy for () { // empty } -#[doc(primitive = "pointer")] +#[cfg_attr(bootstrap, doc(primitive = "pointer"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "pointer")] #[doc(alias = "ptr")] #[doc(alias = "*")] #[doc(alias = "*const")] @@ -577,7 +582,8 @@ impl Copy for () { #[stable(feature = "rust1", since = "1.0.0")] mod prim_pointer {} -#[doc(primitive = "array")] +#[cfg_attr(bootstrap, doc(primitive = "array"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "array")] #[doc(alias = "[]")] #[doc(alias = "[T;N]")] // unfortunately, rustdoc doesn't have fuzzy search for aliases #[doc(alias = "[T; N]")] @@ -778,7 +784,8 @@ mod prim_pointer {} #[stable(feature = "rust1", since = "1.0.0")] mod prim_array {} -#[doc(primitive = "slice")] +#[cfg_attr(bootstrap, doc(primitive = "slice"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "slice")] #[doc(alias = "[")] #[doc(alias = "]")] #[doc(alias = "[]")] @@ -870,7 +877,8 @@ mod prim_array {} #[stable(feature = "rust1", since = "1.0.0")] mod prim_slice {} -#[doc(primitive = "str")] +#[cfg_attr(bootstrap, doc(primitive = "str"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "str")] /// String slices. /// /// *[See also the `std::str` module](crate::str).* @@ -937,7 +945,8 @@ mod prim_slice {} #[stable(feature = "rust1", since = "1.0.0")] mod prim_str {} -#[doc(primitive = "tuple")] +#[cfg_attr(bootstrap, doc(primitive = "tuple"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "tuple")] #[doc(alias = "(")] #[doc(alias = ")")] #[doc(alias = "()")] @@ -1081,7 +1090,8 @@ impl<T: Copy> Copy for (T,) { // empty } -#[doc(primitive = "f32")] +#[cfg_attr(bootstrap, doc(primitive = "f32"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "f32")] /// A 32-bit floating point type (specifically, the "binary32" type defined in IEEE 754-2008). /// /// This type can represent a wide range of decimal numbers, like `3.5`, `27`, @@ -1147,7 +1157,8 @@ impl<T: Copy> Copy for (T,) { #[stable(feature = "rust1", since = "1.0.0")] mod prim_f32 {} -#[doc(primitive = "f64")] +#[cfg_attr(bootstrap, doc(primitive = "f64"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "f64")] /// A 64-bit floating point type (specifically, the "binary64" type defined in IEEE 754-2008). /// /// This type is very similar to [`f32`], but has increased @@ -1162,67 +1173,78 @@ mod prim_f32 {} #[stable(feature = "rust1", since = "1.0.0")] mod prim_f64 {} -#[doc(primitive = "i8")] +#[cfg_attr(bootstrap, doc(primitive = "i8"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "i8")] // /// The 8-bit signed integer type. #[stable(feature = "rust1", since = "1.0.0")] mod prim_i8 {} -#[doc(primitive = "i16")] +#[cfg_attr(bootstrap, doc(primitive = "i16"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "i16")] // /// The 16-bit signed integer type. #[stable(feature = "rust1", since = "1.0.0")] mod prim_i16 {} -#[doc(primitive = "i32")] +#[cfg_attr(bootstrap, doc(primitive = "i32"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "i32")] // /// The 32-bit signed integer type. #[stable(feature = "rust1", since = "1.0.0")] mod prim_i32 {} -#[doc(primitive = "i64")] +#[cfg_attr(bootstrap, doc(primitive = "i64"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "i64")] // /// The 64-bit signed integer type. #[stable(feature = "rust1", since = "1.0.0")] mod prim_i64 {} -#[doc(primitive = "i128")] +#[cfg_attr(bootstrap, doc(primitive = "i128"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "i128")] // /// The 128-bit signed integer type. #[stable(feature = "i128", since = "1.26.0")] mod prim_i128 {} -#[doc(primitive = "u8")] +#[cfg_attr(bootstrap, doc(primitive = "u8"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "u8")] // /// The 8-bit unsigned integer type. #[stable(feature = "rust1", since = "1.0.0")] mod prim_u8 {} -#[doc(primitive = "u16")] +#[cfg_attr(bootstrap, doc(primitive = "u16"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "u16")] // /// The 16-bit unsigned integer type. #[stable(feature = "rust1", since = "1.0.0")] mod prim_u16 {} -#[doc(primitive = "u32")] +#[cfg_attr(bootstrap, doc(primitive = "u32"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "u32")] // /// The 32-bit unsigned integer type. #[stable(feature = "rust1", since = "1.0.0")] mod prim_u32 {} -#[doc(primitive = "u64")] +#[cfg_attr(bootstrap, doc(primitive = "u64"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "u64")] // /// The 64-bit unsigned integer type. #[stable(feature = "rust1", since = "1.0.0")] mod prim_u64 {} -#[doc(primitive = "u128")] +#[cfg_attr(bootstrap, doc(primitive = "u128"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "u128")] // /// The 128-bit unsigned integer type. #[stable(feature = "i128", since = "1.26.0")] mod prim_u128 {} -#[doc(primitive = "isize")] +#[cfg_attr(bootstrap, doc(primitive = "isize"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "isize")] // /// The pointer-sized signed integer type. /// @@ -1232,7 +1254,8 @@ mod prim_u128 {} #[stable(feature = "rust1", since = "1.0.0")] mod prim_isize {} -#[doc(primitive = "usize")] +#[cfg_attr(bootstrap, doc(primitive = "usize"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "usize")] // /// The pointer-sized unsigned integer type. /// @@ -1242,7 +1265,8 @@ mod prim_isize {} #[stable(feature = "rust1", since = "1.0.0")] mod prim_usize {} -#[doc(primitive = "reference")] +#[cfg_attr(bootstrap, doc(primitive = "reference"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "reference")] #[doc(alias = "&")] #[doc(alias = "&mut")] // @@ -1373,7 +1397,8 @@ mod prim_usize {} #[stable(feature = "rust1", since = "1.0.0")] mod prim_ref {} -#[doc(primitive = "fn")] +#[cfg_attr(bootstrap, doc(primitive = "fn"))] +#[cfg_attr(not(bootstrap), rustc_doc_primitive = "fn")] // /// Function pointers, like `fn(usize) -> bool`. /// diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 909e0a07e4c..fe4186babfd 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -249,13 +249,13 @@ impl ExternalCrate { // // Note that this loop only searches the top-level items of the crate, // and this is intentional. If we were to search the entire crate for an - // item tagged with `#[doc(primitive)]` then we would also have to + // item tagged with `#[rustc_doc_primitive]` then we would also have to // search the entirety of external modules for items tagged - // `#[doc(primitive)]`, which is a pretty inefficient process (decoding + // `#[rustc_doc_primitive]`, which is a pretty inefficient process (decoding // all that metadata unconditionally). // // In order to keep the metadata load under control, the - // `#[doc(primitive)]` feature is explicitly designed to only allow the + // `#[rustc_doc_primitive]` feature is explicitly designed to only allow the // primitive tags to show up as the top level items in a crate. // // Also note that this does not attempt to deal with modules tagged @@ -264,18 +264,13 @@ impl ExternalCrate { let as_primitive = |res: Res<!>| { if let Res::Def(DefKind::Mod, def_id) = res { let mut prim = None; - let meta_items = tcx - .get_attrs(def_id, sym::doc) - .flat_map(|attr| attr.meta_item_list().unwrap_or_default()); - for meta in meta_items { - if let Some(v) = meta.value_str() { - if meta.has_name(sym::primitive) { - prim = PrimitiveType::from_symbol(v); - if prim.is_some() { - break; - } - // FIXME: should warn on unknown primitives? + for attr in tcx.get_attrs(def_id, sym::rustc_doc_primitive) { + if let Some(v) = attr.value_str() { + prim = PrimitiveType::from_symbol(v); + if prim.is_some() { + break; } + // FIXME: should warn on unknown primitives? } } return prim.map(|p| (def_id, p)); @@ -1829,13 +1824,17 @@ impl PrimitiveType { } } - /// Returns the DefId of the module with `doc(primitive)` for this primitive type. + /// Returns the DefId of the module with `rustc_doc_primitive` for this primitive type. /// Panics if there is no such module. /// - /// This gives precedence to primitives defined in the current crate, and deprioritizes primitives defined in `core`, - /// but otherwise, if multiple crates define the same primitive, there is no guarantee of which will be picked. - /// In particular, if a crate depends on both `std` and another crate that also defines `doc(primitive)`, then - /// it's entirely random whether `std` or the other crate is picked. (no_std crates are usually fine unless multiple dependencies define a primitive.) + /// This gives precedence to primitives defined in the current crate, and deprioritizes + /// primitives defined in `core`, + /// but otherwise, if multiple crates define the same primitive, there is no guarantee of which + /// will be picked. + /// + /// In particular, if a crate depends on both `std` and another crate that also defines + /// `rustc_doc_primitive`, then it's entirely random whether `std` or the other crate is picked. + /// (no_std crates are usually fine unless multiple dependencies define a primitive.) pub(crate) fn primitive_locations(tcx: TyCtxt<'_>) -> &FxHashMap<PrimitiveType, DefId> { static PRIMITIVE_LOCATIONS: OnceCell<FxHashMap<PrimitiveType, DefId>> = OnceCell::new(); PRIMITIVE_LOCATIONS.get_or_init(|| { diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 59d67f27b30..c39caf73a93 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -249,9 +249,7 @@ pub(crate) fn id_from_item_inner( // instead, we directly get the primitive symbol and convert it to u32 to // generate the ID. if matches!(tcx.def_kind(def_id), DefKind::Mod) && - let Some(prim) = tcx.get_attrs(*def_id, sym::doc) - .flat_map(|attr| attr.meta_item_list().unwrap_or_default()) - .filter(|attr| attr.has_name(sym::primitive)) + let Some(prim) = tcx.get_attrs(*def_id, sym::rustc_doc_primitive) .find_map(|attr| attr.value_str()) { format!(":{}", prim.as_u32()) } else { diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index 08bceb59cfd..d6da6e09938 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -78,7 +78,7 @@ impl<'tcx> JsonRenderer<'tcx> { // HACK(hkmatsumoto): For impls of primitive types, we index them // regardless of whether they're local. This is because users can // document primitive items in an arbitrary crate by using - // `doc(primitive)`. + // `rustc_doc_primitive`. let mut is_primitive_impl = false; if let clean::types::ItemKind::ImplItem(ref impl_) = *item.kind && impl_.trait_.is_none() && diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index d98cf251e97..48f69029dbb 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -433,8 +433,8 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { })?; // FIXME(#83862): this arbitrarily gives precedence to primitives over modules to support - // links to primitives when `#[doc(primitive)]` is present. It should give an ambiguity - // error instead and special case *only* modules with `#[doc(primitive)]`, not all + // links to primitives when `#[rustc_doc_primitive]` is present. It should give an ambiguity + // error instead and special case *only* modules with `#[rustc_doc_primitive]`, not all // primitives. resolve_primitive(&path_root, TypeNS) .or_else(|| self.resolve_path(&path_root, TypeNS, item_id, module_id)) @@ -1102,7 +1102,7 @@ impl LinkCollector<'_, '_> { } } - // item can be non-local e.g. when using #[doc(primitive = "pointer")] + // item can be non-local e.g. when using `#[rustc_doc_primitive = "pointer"]` if let Some((src_id, dst_id)) = id.as_local().and_then(|dst_id| { item.item_id.expect_def_id().as_local().map(|src_id| (src_id, dst_id)) }) { From 48f7148fcab44e030882d3c0a7a93e66a92f2ba4 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez <guillaume.gomez@huawei.com> Date: Tue, 21 Mar 2023 16:53:12 +0100 Subject: [PATCH 303/346] Update documentation for rustc_doc_primitive --- src/doc/rustdoc/src/unstable-features.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index b8b5014ab42..960c1de1782 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -177,9 +177,9 @@ Book][unstable-masked] and [its tracking issue][issue-masked]. This is for Rust compiler internal use only. Since primitive types are defined in the compiler, there's no place to attach documentation -attributes. The `#[doc(primitive)]` attribute is used by the standard library to provide a way -to generate documentation for primitive types, and requires `#![feature(rustdoc_internals)]` to -enable. +attributes. The `#[rustc_doc_primitive = "..."]` attribute is used by the standard library to +provide a way to generate documentation for primitive types, and requires `#![feature(rustc_attrs)]` +to enable. ### Document keywords From fa2824aef4541230c1cd0c39e307a789bd0820a8 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez <guillaume.gomez@huawei.com> Date: Tue, 21 Mar 2023 16:59:16 +0100 Subject: [PATCH 304/346] Add test to ensure doc(primitive) is not recognized anymore --- tests/ui/rustdoc/doc-primitive.rs | 8 ++++++++ tests/ui/rustdoc/doc-primitive.stderr | 16 ++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 tests/ui/rustdoc/doc-primitive.rs create mode 100644 tests/ui/rustdoc/doc-primitive.stderr diff --git a/tests/ui/rustdoc/doc-primitive.rs b/tests/ui/rustdoc/doc-primitive.rs new file mode 100644 index 00000000000..4336961e3b5 --- /dev/null +++ b/tests/ui/rustdoc/doc-primitive.rs @@ -0,0 +1,8 @@ +#![deny(invalid_doc_attributes)] + +#[doc(primitive = "foo")] +//~^ ERROR unknown `doc` attribute `primitive` +//~| WARN +mod bar {} + +fn main() {} diff --git a/tests/ui/rustdoc/doc-primitive.stderr b/tests/ui/rustdoc/doc-primitive.stderr new file mode 100644 index 00000000000..d61eb381647 --- /dev/null +++ b/tests/ui/rustdoc/doc-primitive.stderr @@ -0,0 +1,16 @@ +error: unknown `doc` attribute `primitive` + --> $DIR/doc-primitive.rs:3:7 + | +LL | #[doc(primitive = "foo")] + | ^^^^^^^^^^^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730> +note: the lint level is defined here + --> $DIR/doc-primitive.rs:1:9 + | +LL | #![deny(invalid_doc_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + From bcf8a8b58ccdced38a3b7e9d1f3f219df782cf07 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez <guillaume.gomez@huawei.com> Date: Thu, 30 Mar 2023 17:59:35 +0200 Subject: [PATCH 305/346] Improve code --- src/librustdoc/clean/types.rs | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index fe4186babfd..ffa13ebb77c 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -262,20 +262,11 @@ impl ExternalCrate { // duplicately for the same primitive. This is handled later on when // rendering by delegating everything to a hash map. let as_primitive = |res: Res<!>| { - if let Res::Def(DefKind::Mod, def_id) = res { - let mut prim = None; - for attr in tcx.get_attrs(def_id, sym::rustc_doc_primitive) { - if let Some(v) = attr.value_str() { - prim = PrimitiveType::from_symbol(v); - if prim.is_some() { - break; - } - // FIXME: should warn on unknown primitives? - } - } - return prim.map(|p| (def_id, p)); - } - None + let Res::Def(DefKind::Mod, def_id) = res else { return None }; + tcx.get_attrs(def_id, sym::rustc_doc_primitive).find_map(|attr| { + // FIXME: should warn on unknown primitives? + Some((def_id, PrimitiveType::from_symbol(attr.value_str()?)?)) + }) }; if root.is_local() { From f6035fb0fa68de45befc032e35bb68592ce1d029 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez <guillaume.gomez@huawei.com> Date: Fri, 31 Mar 2023 00:04:24 +0200 Subject: [PATCH 306/346] Update doc(primitive) in rustc_resolve --- compiler/rustc_resolve/src/rustdoc.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs index 44a27bbc175..9eae99be2e9 100644 --- a/compiler/rustc_resolve/src/rustdoc.rs +++ b/compiler/rustc_resolve/src/rustdoc.rs @@ -339,12 +339,14 @@ pub fn inner_docs(attrs: &[ast::Attribute]) -> bool { attrs.iter().find(|a| a.doc_str().is_some()).map_or(true, |a| a.style == ast::AttrStyle::Inner) } -/// Has `#[doc(primitive)]` or `#[doc(keyword)]`. +/// Has `#[rustc_doc_primitive]` or `#[doc(keyword)]`. pub fn has_primitive_or_keyword_docs(attrs: &[ast::Attribute]) -> bool { for attr in attrs { - if attr.has_name(sym::doc) && let Some(items) = attr.meta_item_list() { + if attr.has_name(sym::rustc_doc_primitive) { + return true; + } else if attr.has_name(sym::doc) && let Some(items) = attr.meta_item_list() { for item in items { - if item.has_name(sym::primitive) || item.has_name(sym::keyword) { + if item.has_name(sym::keyword) { return true; } } From f24983222d207096851344f7551f0f4ec5cc2a61 Mon Sep 17 00:00:00 2001 From: est31 <MTest31@outlook.com> Date: Fri, 31 Mar 2023 03:04:09 +0200 Subject: [PATCH 307/346] Use std::fs::read_to_file in fluent_messages macro --- compiler/rustc_macros/src/diagnostics/fluent.rs | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_macros/src/diagnostics/fluent.rs b/compiler/rustc_macros/src/diagnostics/fluent.rs index 3b2f5cfdc73..42a1fc147f7 100644 --- a/compiler/rustc_macros/src/diagnostics/fluent.rs +++ b/compiler/rustc_macros/src/diagnostics/fluent.rs @@ -15,8 +15,7 @@ use proc_macro2::TokenStream; use quote::quote; use std::{ collections::{HashMap, HashSet}, - fs::File, - io::Read, + fs::read_to_string, path::{Path, PathBuf}, }; use syn::{parse_macro_input, Ident, LitStr}; @@ -95,8 +94,8 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok // As this macro also outputs an `include_str!` for this file, the macro will always be // re-executed when the file changes. - let mut resource_file = match File::open(absolute_ftl_path) { - Ok(resource_file) => resource_file, + let resource_contents = match read_to_string(absolute_ftl_path) { + Ok(resource_contents) => resource_contents, Err(e) => { Diagnostic::spanned(resource_span, Level::Error, "could not open Fluent resource") .note(e.to_string()) @@ -104,13 +103,6 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok return failed(&crate_name); } }; - let mut resource_contents = String::new(); - if let Err(e) = resource_file.read_to_string(&mut resource_contents) { - Diagnostic::spanned(resource_span, Level::Error, "could not read Fluent resource") - .note(e.to_string()) - .emit(); - return failed(&crate_name); - } let mut bad = false; for esc in ["\\n", "\\\"", "\\'"] { for _ in resource_contents.matches(esc) { From 97fb15d9508da0712aa6a5b194251e90315105fb Mon Sep 17 00:00:00 2001 From: est31 <MTest31@outlook.com> Date: Fri, 31 Mar 2023 03:48:35 +0200 Subject: [PATCH 308/346] Don't emit the OS error in a note This makes it possible to make the normalization of the error message more precise, allowing us to not normalize all notes away. --- compiler/rustc_macros/src/diagnostics/fluent.rs | 9 ++++++--- tests/ui-fulldeps/fluent-messages/test.rs | 2 +- tests/ui-fulldeps/fluent-messages/test.stderr | 14 +++++--------- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_macros/src/diagnostics/fluent.rs b/compiler/rustc_macros/src/diagnostics/fluent.rs index 42a1fc147f7..9f96a041487 100644 --- a/compiler/rustc_macros/src/diagnostics/fluent.rs +++ b/compiler/rustc_macros/src/diagnostics/fluent.rs @@ -97,9 +97,12 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok let resource_contents = match read_to_string(absolute_ftl_path) { Ok(resource_contents) => resource_contents, Err(e) => { - Diagnostic::spanned(resource_span, Level::Error, "could not open Fluent resource") - .note(e.to_string()) - .emit(); + Diagnostic::spanned( + resource_span, + Level::Error, + format!("could not open Fluent resource: {}", e.to_string()), + ) + .emit(); return failed(&crate_name); } }; diff --git a/tests/ui-fulldeps/fluent-messages/test.rs b/tests/ui-fulldeps/fluent-messages/test.rs index 1ee7227a8e9..6ba13387b04 100644 --- a/tests/ui-fulldeps/fluent-messages/test.rs +++ b/tests/ui-fulldeps/fluent-messages/test.rs @@ -1,4 +1,4 @@ -// normalize-stderr-test "note.*" -> "note: os-specific message" +// normalize-stderr-test "could not open Fluent resource:.*" -> "could not open Fluent resource: os-specific message" #![feature(rustc_private)] #![crate_type = "lib"] diff --git a/tests/ui-fulldeps/fluent-messages/test.stderr b/tests/ui-fulldeps/fluent-messages/test.stderr index 8a6a4a91cc2..2affe621c11 100644 --- a/tests/ui-fulldeps/fluent-messages/test.stderr +++ b/tests/ui-fulldeps/fluent-messages/test.stderr @@ -1,18 +1,14 @@ -error: could not open Fluent resource +error: could not open Fluent resource: os-specific message --> $DIR/test.rs:24:24 | LL | fluent_messages! { "/definitely_does_not_exist.ftl" } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: os-specific message -error: could not open Fluent resource +error: could not open Fluent resource: os-specific message --> $DIR/test.rs:31:24 | LL | fluent_messages! { "../definitely_does_not_exist.ftl" } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: os-specific message error: could not parse Fluent resource --> $DIR/test.rs:38:24 @@ -89,7 +85,7 @@ error: invalid escape `\n` in Fluent resource LL | fluent_messages! { "./invalid-escape.ftl" } | ^^^^^^^^^^^^^^^^^^^^^^ | - = note: os-specific message + = note: Fluent does not interpret these escape sequences (<https://projectfluent.org/fluent/guide/special.html>) error: invalid escape `\"` in Fluent resource --> $DIR/test.rs:99:24 @@ -97,7 +93,7 @@ error: invalid escape `\"` in Fluent resource LL | fluent_messages! { "./invalid-escape.ftl" } | ^^^^^^^^^^^^^^^^^^^^^^ | - = note: os-specific message + = note: Fluent does not interpret these escape sequences (<https://projectfluent.org/fluent/guide/special.html>) error: invalid escape `\'` in Fluent resource --> $DIR/test.rs:99:24 @@ -105,7 +101,7 @@ error: invalid escape `\'` in Fluent resource LL | fluent_messages! { "./invalid-escape.ftl" } | ^^^^^^^^^^^^^^^^^^^^^^ | - = note: os-specific message + = note: Fluent does not interpret these escape sequences (<https://projectfluent.org/fluent/guide/special.html>) error: aborting due to 13 previous errors From 1a54144349cf461e6cb6767607e90cc7e73a6e1c Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy <alimjalnasrawy@gmail.com> Date: Fri, 31 Mar 2023 03:27:51 +0000 Subject: [PATCH 309/346] add test for normalization in implied bounds query See https://github.com/rust-lang/rust/issues/109799. --- .../normalization-nested.lifetime.stderr | 18 +++++++++ .../ui/implied-bounds/normalization-nested.rs | 39 +++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 tests/ui/implied-bounds/normalization-nested.lifetime.stderr create mode 100644 tests/ui/implied-bounds/normalization-nested.rs diff --git a/tests/ui/implied-bounds/normalization-nested.lifetime.stderr b/tests/ui/implied-bounds/normalization-nested.lifetime.stderr new file mode 100644 index 00000000000..898e5e9511e --- /dev/null +++ b/tests/ui/implied-bounds/normalization-nested.lifetime.stderr @@ -0,0 +1,18 @@ +error[E0759]: `fn` parameter has lifetime `'x` but it needs to satisfy a `'static` lifetime requirement + --> $DIR/normalization-nested.rs:35:20 + | +LL | pub fn test<'x>(_: Map<Vec<&'x ()>>, s: &'x str) -> &'static str { + | ^^^^^^^^^^^^^^^^ + | | + | this data with lifetime `'x`... + | ...is used and required to live as long as `'static` here + | +note: `'static` lifetime requirement introduced by this bound + --> $DIR/normalization-nested.rs:33:14 + | +LL | I::Item: 'static; + | ^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0759`. diff --git a/tests/ui/implied-bounds/normalization-nested.rs b/tests/ui/implied-bounds/normalization-nested.rs new file mode 100644 index 00000000000..5f1cbb3f697 --- /dev/null +++ b/tests/ui/implied-bounds/normalization-nested.rs @@ -0,0 +1,39 @@ +// Test for normalization of projections that appear in the item bounds +// (versus those that appear directly in the input types). +// Both revisions should pass. `lifetime` revision is a bug. +// +// revisions: param_ty lifetime +// [param_ty] check-pass +// [lifetime] check-fail +// [lifetime] known-bug: #109799 + +pub trait Iter { + type Item; +} + +#[cfg(param_ty)] +impl<X, I> Iter for I +where + I: IntoIterator<Item = X>, +{ + type Item = X; +} + +#[cfg(lifetime)] +impl<'x, I> Iter for I +where + I: IntoIterator<Item = &'x ()>, +{ + type Item = &'x (); +} + +pub struct Map<I>(I) +where + I: Iter, + I::Item: 'static; + +pub fn test<'x>(_: Map<Vec<&'x ()>>, s: &'x str) -> &'static str { + s +} + +fn main() {} From 750707801b42c0da6beeccd587925130ba2bad99 Mon Sep 17 00:00:00 2001 From: Ben Kimock <kimockb@gmail.com> Date: Thu, 30 Mar 2023 23:46:44 -0400 Subject: [PATCH 310/346] Disable the ui panic test on wasm32-bare --- tests/ui/mir/mir_alignment_check.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/ui/mir/mir_alignment_check.rs b/tests/ui/mir/mir_alignment_check.rs index 6c964c78bd1..68a5384b30d 100644 --- a/tests/ui/mir/mir_alignment_check.rs +++ b/tests/ui/mir/mir_alignment_check.rs @@ -1,4 +1,5 @@ // run-fail +// ignore-wasm32-bare: No panic messages // compile-flags: -C debug-assertions // error-pattern: misaligned pointer dereference: address must be a multiple of 0x4 but is From f049d5df10fc169d12ae825b5a5e78e47a0195bd Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote <n.nethercote@gmail.com> Date: Fri, 31 Mar 2023 15:06:08 +1100 Subject: [PATCH 311/346] Remove an unnecessary use of `with_session_globals`. We can easily pass in the source map. --- compiler/rustc_expand/src/proc_macro.rs | 10 +++++++--- compiler/rustc_span/src/profiling.rs | 16 +++++----------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs index ddba1441719..26bc216f678 100644 --- a/compiler/rustc_expand/src/proc_macro.rs +++ b/compiler/rustc_expand/src/proc_macro.rs @@ -54,7 +54,7 @@ impl base::BangProcMacro for BangProcMacro { ) -> Result<TokenStream, ErrorGuaranteed> { let _timer = ecx.sess.prof.generic_activity_with_arg_recorder("expand_proc_macro", |recorder| { - recorder.record_arg_with_span(ecx.expansion_descr(), span); + recorder.record_arg_with_span(ecx.sess.source_map(), ecx.expansion_descr(), span); }); let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace; @@ -85,7 +85,7 @@ impl base::AttrProcMacro for AttrProcMacro { ) -> Result<TokenStream, ErrorGuaranteed> { let _timer = ecx.sess.prof.generic_activity_with_arg_recorder("expand_proc_macro", |recorder| { - recorder.record_arg_with_span(ecx.expansion_descr(), span); + recorder.record_arg_with_span(ecx.sess.source_map(), ecx.expansion_descr(), span); }); let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace; @@ -134,7 +134,11 @@ impl MultiItemModifier for DeriveProcMacro { let stream = { let _timer = ecx.sess.prof.generic_activity_with_arg_recorder("expand_proc_macro", |recorder| { - recorder.record_arg_with_span(ecx.expansion_descr(), span); + recorder.record_arg_with_span( + ecx.sess.source_map(), + ecx.expansion_descr(), + span, + ); }); let proc_macro_backtrace = ecx.ecfg.proc_macro_backtrace; let strategy = exec_strategy(ecx); diff --git a/compiler/rustc_span/src/profiling.rs b/compiler/rustc_span/src/profiling.rs index 0ab890b9f01..66e5369da3a 100644 --- a/compiler/rustc_span/src/profiling.rs +++ b/compiler/rustc_span/src/profiling.rs @@ -1,3 +1,5 @@ +use crate::source_map::SourceMap; + use std::borrow::Borrow; use rustc_data_structures::profiling::EventArgRecorder; @@ -11,25 +13,17 @@ pub trait SpannedEventArgRecorder { /// /// Note: when self-profiling with costly event arguments, at least one argument /// needs to be recorded. A panic will be triggered if that doesn't happen. - fn record_arg_with_span<A>(&mut self, event_arg: A, span: crate::Span) + fn record_arg_with_span<A>(&mut self, source_map: &SourceMap, event_arg: A, span: crate::Span) where A: Borrow<str> + Into<String>; } impl SpannedEventArgRecorder for EventArgRecorder<'_> { - fn record_arg_with_span<A>(&mut self, event_arg: A, span: crate::Span) + fn record_arg_with_span<A>(&mut self, source_map: &SourceMap, event_arg: A, span: crate::Span) where A: Borrow<str> + Into<String>, { self.record_arg(event_arg); - - let span_arg = crate::with_session_globals(|session_globals| { - if let Some(source_map) = &*session_globals.source_map.borrow() { - source_map.span_to_embeddable_string(span) - } else { - format!("{span:?}") - } - }); - self.record_arg(span_arg); + self.record_arg(source_map.span_to_embeddable_string(span)); } } From 4e63ab6fc11ab942052c485ed121a606f0a7d319 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote <n.nethercote@gmail.com> Date: Fri, 31 Mar 2023 14:54:25 +1100 Subject: [PATCH 312/346] Improve `with_source_map`. Rename `with_source_map` as `set_source_map`. Because `with` functions (e.g. `with_session_globals`, `scoped_tls::ScopedKey::with`) are for *getting* a value for the duration of a closure, and `set` functions (e.g. `set_session_globals_then` `scoped_tls::ScopedKey::with`) are for *setting* a value for the duration of a closure. Also fix up the comment, which is wrong: - The bit about `TyCtxt` is wrong. - `span_debug1` doesn't exist any more. - There's only one level of fallback, not two. (This is effectively a follow-up to the changes in #93936.) Also add a comment explaining that `SessionGlobals::source_map` should only be used when absolutely necessary. --- compiler/rustc_interface/src/interface.rs | 2 +- compiler/rustc_span/src/lib.rs | 23 +++++++++++++---------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index 5e38ca034ac..be7fa9378ca 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -292,7 +292,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se override_queries: config.override_queries, }; - rustc_span::with_source_map(compiler.sess.parse_sess.clone_source_map(), move || { + rustc_span::set_source_map(compiler.sess.parse_sess.clone_source_map(), move || { let r = { let _sess_abort_error = OnDrop(|| { compiler.sess.finish_diagnostics(registry); diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 02cffc762be..e14760aa018 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -87,6 +87,14 @@ pub struct SessionGlobals { symbol_interner: symbol::Interner, span_interner: Lock<span_encoding::SpanInterner>, hygiene_data: Lock<hygiene::HygieneData>, + + /// A reference to the source map in the `Session`. It's an `Option` + /// because it can't be initialized until `Session` is created, which + /// happens after `SessionGlobals`. `set_source_map` does the + /// initialization. + /// + /// This field should only be used in places where the `Session` is truly + /// not available, such as `<Span as Debug>::fmt`. source_map: Lock<Option<Lrc<SourceMap>>>, } @@ -1013,16 +1021,9 @@ impl<D: Decoder> Decodable<D> for Span { } } -/// Calls the provided closure, using the provided `SourceMap` to format -/// any spans that are debug-printed during the closure's execution. -/// -/// Normally, the global `TyCtxt` is used to retrieve the `SourceMap` -/// (see `rustc_interface::callbacks::span_debug1`). However, some parts -/// of the compiler (e.g. `rustc_parse`) may debug-print `Span`s before -/// a `TyCtxt` is available. In this case, we fall back to -/// the `SourceMap` provided to this function. If that is not available, -/// we fall back to printing the raw `Span` field values. -pub fn with_source_map<T, F: FnOnce() -> T>(source_map: Lrc<SourceMap>, f: F) -> T { +/// Insert `source_map` into the session globals for the duration of the +/// closure's execution. +pub fn set_source_map<T, F: FnOnce() -> T>(source_map: Lrc<SourceMap>, f: F) -> T { with_session_globals(|session_globals| { *session_globals.source_map.borrow_mut() = Some(source_map); }); @@ -1041,6 +1042,8 @@ pub fn with_source_map<T, F: FnOnce() -> T>(source_map: Lrc<SourceMap>, f: F) -> impl fmt::Debug for Span { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // Use the global `SourceMap` to print the span. If that's not + // available, fall back to printing the raw values. with_session_globals(|session_globals| { if let Some(source_map) = &*session_globals.source_map.borrow() { write!(f, "{} ({:?})", source_map.span_to_diagnostic_string(*self), self.ctxt()) From aab9e320946427fdf8fa4fa7ce2cd00e43fa690c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez <guillaume.gomez@huawei.com> Date: Fri, 31 Mar 2023 16:02:22 +0200 Subject: [PATCH 313/346] Update browser-ui-test version to 0.14.6 --- .../docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version index 6fd113fcfd8..66fb941ea37 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version +++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version @@ -1 +1 @@ -0.14.5 \ No newline at end of file +0.14.6 \ No newline at end of file From efad057eed692f2fc8c243707abebe02932fa223 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez <guillaume.gomez@huawei.com> Date: Fri, 31 Mar 2023 16:51:50 +0200 Subject: [PATCH 314/346] Add tests to check that collapsed content is expanded when jumping to it --- tests/rustdoc-gui/go-to-collapsed-elem.goml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 tests/rustdoc-gui/go-to-collapsed-elem.goml diff --git a/tests/rustdoc-gui/go-to-collapsed-elem.goml b/tests/rustdoc-gui/go-to-collapsed-elem.goml new file mode 100644 index 00000000000..279048e37c1 --- /dev/null +++ b/tests/rustdoc-gui/go-to-collapsed-elem.goml @@ -0,0 +1,21 @@ +// This test ensures that when clicking on a link which leads to an item inside a collapsed element, +// the collapsed element will be expanded. +goto: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html" +// We check that the implementors block is expanded. +assert-property: ("#implementations-list .implementors-toggle", {"open": "true"}) +// We now collapse the implementors block. +property: ("#implementations-list .implementors-toggle", {"open": "false"}) +// And now we click on the link to the method to ensure it'll expand the implementors block. +click: "//*[@class='sidebar']//a[@href='#method.must_use']" +assert-property: ("#implementations-list .implementors-toggle", {"open": "true"}) + +// Now we do the same through search result. +// First we reload the page without the anchor in the URL. +goto: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html" +// Then we collapse the section again... +property: ("#implementations-list .implementors-toggle", {"open": "false"}) +// Then we run the search. +write: (".search-input", "foo::must_use") +wait-for: "//*[@id='search']//a[@href='../test_docs/struct.Foo.html#method.must_use']" +click: "//*[@id='search']//a[@href='../test_docs/struct.Foo.html#method.must_use']" +assert-property: ("#implementations-list .implementors-toggle", {"open": "true"}) From a42cbdb16575d5c955e9bd3b434026758de789bf Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy <alimjalnasrawy@gmail.com> Date: Wed, 15 Mar 2023 15:51:34 +0300 Subject: [PATCH 315/346] allow ReError in CanonicalUserTypeAnnotation --- .../src/infer/canonical/canonicalizer.rs | 4 +-- .../region-error-ice-109072.rs | 14 ++++++++++ .../region-error-ice-109072.stderr | 26 +++++++++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 tests/ui/nll/user-annotations/region-error-ice-109072.rs create mode 100644 tests/ui/nll/user-annotations/region-error-ice-109072.stderr diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 96a5f6532fe..3bbd01f8273 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -230,9 +230,9 @@ impl CanonicalizeMode for CanonicalizeUserTypeAnnotation { r: ty::Region<'tcx>, ) -> ty::Region<'tcx> { match *r { - ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReErased | ty::ReStatic => r, + ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReErased | ty::ReStatic | ty::ReError(_) => r, ty::ReVar(_) => canonicalizer.canonical_var_for_region_in_root_universe(r), - _ => { + ty::RePlaceholder(..) | ty::ReLateBound(..) => { // We only expect region names that the user can type. bug!("unexpected region in query response: `{:?}`", r) } diff --git a/tests/ui/nll/user-annotations/region-error-ice-109072.rs b/tests/ui/nll/user-annotations/region-error-ice-109072.rs new file mode 100644 index 00000000000..3f2ad3ccbf5 --- /dev/null +++ b/tests/ui/nll/user-annotations/region-error-ice-109072.rs @@ -0,0 +1,14 @@ +// Regression test for #109072. +// Check that we don't ICE when canonicalizing user annotation. + +trait Lt<'a> { + type T; +} + +impl Lt<'missing> for () { //~ ERROR undeclared lifetime + type T = &'missing (); //~ ERROR undeclared lifetime +} + +fn main() { + let _: <() as Lt<'_>>::T = &(); +} diff --git a/tests/ui/nll/user-annotations/region-error-ice-109072.stderr b/tests/ui/nll/user-annotations/region-error-ice-109072.stderr new file mode 100644 index 00000000000..d90971bed25 --- /dev/null +++ b/tests/ui/nll/user-annotations/region-error-ice-109072.stderr @@ -0,0 +1,26 @@ +error[E0261]: use of undeclared lifetime name `'missing` + --> $DIR/region-error-ice-109072.rs:8:9 + | +LL | impl Lt<'missing> for () { + | - ^^^^^^^^ undeclared lifetime + | | + | help: consider introducing lifetime `'missing` here: `<'missing>` + +error[E0261]: use of undeclared lifetime name `'missing` + --> $DIR/region-error-ice-109072.rs:9:15 + | +LL | type T = &'missing (); + | ^^^^^^^^ undeclared lifetime + | +help: consider introducing lifetime `'missing` here + | +LL | type T<'missing> = &'missing (); + | ++++++++++ +help: consider introducing lifetime `'missing` here + | +LL | impl<'missing> Lt<'missing> for () { + | ++++++++++ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0261`. From 54ef3a47861ef1babfbd1948ea9a476a30bd8b10 Mon Sep 17 00:00:00 2001 From: Michael Howell <michael@notriddle.com> Date: Fri, 31 Mar 2023 10:18:44 -0700 Subject: [PATCH 316/346] rustdoc-search: update docs for comma in `?` help popover --- src/librustdoc/html/static/js/main.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 1487ebf9b0a..45c0360a49e 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -1016,9 +1016,7 @@ function preLoadCss(cssUrl) { <code>enum</code>, <code>trait</code>, <code>type</code>, <code>macro</code>, \ and <code>const</code>.", "Search functions by type signature (e.g., <code>vec -> usize</code> or \ - <code>-> vec</code>)", - "Search multiple things at once by splitting your query with comma (e.g., \ - <code>str,u8</code> or <code>String,struct:Vec,test</code>)", + <code>-> vec</code> or <code>String, enum:Cow -> bool</code>)", "You can look for items with an exact name by putting double quotes around \ your request: <code>\"string\"</code>", "Look for items inside another one by searching for a path: <code>vec::Vec</code>", From 1f3ee276e5d6d286fef62e968680df2a3962360e Mon Sep 17 00:00:00 2001 From: klensy <klensy@users.noreply.github.com> Date: Sat, 1 Apr 2023 17:54:52 +0300 Subject: [PATCH 317/346] bootstrap replace atty with is-terminal, dedupe few deps --- src/bootstrap/Cargo.lock | 72 +++++++++++++++++++++------------------- src/bootstrap/Cargo.toml | 2 +- src/bootstrap/config.rs | 6 ++-- 3 files changed, 42 insertions(+), 38 deletions(-) diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock index 27236e191fd..965dfa5f398 100644 --- a/src/bootstrap/Cargo.lock +++ b/src/bootstrap/Cargo.lock @@ -11,17 +11,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -47,7 +36,6 @@ dependencies = [ name = "bootstrap" version = "0.0.0" dependencies = [ - "atty", "build_helper", "cc", "cmake", @@ -56,6 +44,7 @@ dependencies = [ "getopts", "hex", "ignore", + "is-terminal", "libc", "object", "once_cell", @@ -212,13 +201,13 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" [[package]] name = "errno" -version = "0.2.8" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +checksum = "50d6a0976c999d473fe89ad888d5a284e55366d9dc9038b1ba2aa15128c4afa0" dependencies = [ "errno-dragonfly", "libc", - "winapi", + "windows-sys", ] [[package]] @@ -233,9 +222,9 @@ dependencies = [ [[package]] name = "fd-lock" -version = "3.0.8" +version = "3.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb21c69b9fea5e15dbc1049e4b77145dd0ba1c84019c488102de0dc4ea4b0a27" +checksum = "9799aefb4a2e4a01cc47610b1dd47c18ab13d991f27bbcaed9296f5a53d5cbad" dependencies = [ "cfg-if", "rustix", @@ -301,6 +290,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hermit-abi" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" + [[package]] name = "hex" version = "0.4.3" @@ -327,14 +322,27 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "1.0.1" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7d367024b3f3414d8e01f437f704f41a9f64ab36f9067fa73e526ad4c763c87" +checksum = "09270fd4fa1111bc614ed2246c7ef56239a3063d5be0d1ec3b589c505d400aeb" dependencies = [ + "hermit-abi 0.3.1", "libc", "windows-sys", ] +[[package]] +name = "is-terminal" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "256017f749ab3117e93acb91063009e1f1bb56d03965b14c2c8df4eb02c524d8" +dependencies = [ + "hermit-abi 0.3.1", + "io-lifetimes", + "rustix", + "windows-sys", +] + [[package]] name = "itoa" version = "1.0.2" @@ -349,15 +357,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.137" +version = "0.2.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89" +checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" [[package]] name = "linux-raw-sys" -version = "0.1.3" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f9f08d8963a6c613f4b1a78f4f4a4dbfadf8e6545b2d72861731e4858b8b47f" +checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" [[package]] name = "log" @@ -409,7 +417,7 @@ version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" dependencies = [ - "hermit-abi", + "hermit-abi 0.1.19", "libc", ] @@ -540,9 +548,9 @@ checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" [[package]] name = "rustix" -version = "0.36.3" +version = "0.37.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b1fbb4dfc4eb1d390c02df47760bb19a84bb80b301ecc947ab5406394d8223e" +checksum = "d097081ed288dfe45699b72f5b5d648e5f15d64d900c7080273baa20c16a6849" dependencies = [ "bitflags", "errno", @@ -753,17 +761,11 @@ dependencies = [ [[package]] name = "windows-sys" -version = "0.42.0" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows-targets", ] [[package]] diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 5c659800bdb..2fbe7aa57aa 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -30,7 +30,7 @@ path = "bin/sccache-plus-cl.rs" test = false [dependencies] -atty = "0.2.14" +is-terminal = "0.4" build_helper = { path = "../tools/build_helper" } cmake = "0.1.38" filetime = "0.2" diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 0eba18c3a63..b8b6b7b2d4e 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -808,6 +808,8 @@ define_config! { impl Config { pub fn default_opts() -> Config { + use is_terminal::IsTerminal; + let mut config = Config::default(); config.llvm_optimize = true; config.ninja_in_file = true; @@ -828,8 +830,8 @@ impl Config { config.dist_include_mingw_linker = true; config.dist_compression_profile = "fast".into(); - config.stdout_is_tty = atty::is(atty::Stream::Stdout); - config.stderr_is_tty = atty::is(atty::Stream::Stderr); + config.stdout_is_tty = std::io::stdout().is_terminal(); + config.stderr_is_tty = std::io::stderr().is_terminal(); // set by build.rs config.build = TargetSelection::from_user(&env!("BUILD_TRIPLE")); From fe42150801ec143cf1943d5c361d38b0cff9638f Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Sat, 1 Apr 2023 17:11:48 +0200 Subject: [PATCH 318/346] Add Nilstrieb to mailmap I saw that I'm on https://thanks.rust-lang.org/ twice (once as `Nilstrieb` and once as `nils`). This is because I've contributed as both `Nilstrieb` (locally) and `nils` (on github). So I've mailmapped them both to `Nilstrieb` (the less ambiguous of the two). --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index 9148b79e980..b8a9fc27eb7 100644 --- a/.mailmap +++ b/.mailmap @@ -415,6 +415,7 @@ Nick Platt <platt.nicholas@gmail.com> Niclas Schwarzlose <15schnic@gmail.com> Nicolas Abram <abramlujan@gmail.com> Nicole Mazzuca <npmazzuca@gmail.com> +Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> nils <48135649+Nilstrieb@users.noreply.github.com> Nif Ward <nif.ward@gmail.com> Nika Layzell <nika@thelayzells.com> <michael@thelayzells.com> NODA Kai <nodakai@gmail.com> From 6e29862fd29605625bb64c2f2d38a342967ea693 Mon Sep 17 00:00:00 2001 From: Eric Huss <eric@huss.org> Date: Sat, 1 Apr 2023 08:49:20 -0700 Subject: [PATCH 319/346] Update cargo --- Cargo.lock | 112 +++++++++++++++++++++++++++++++++++++----------- src/tools/cargo | 2 +- 2 files changed, 88 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 561f29abec4..d9e9ef9fb0f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -98,6 +98,46 @@ dependencies = [ "winapi", ] +[[package]] +name = "anstream" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "342258dd14006105c2b75ab1bd7543a03bdf0cfc94383303ac212a04939dff6f" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-wincon", + "concolor-override", + "concolor-query 0.3.3", + "is-terminal", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23ea9e81bd02e310c216d080f6223c179012256e5151c41db88d12c88a1684d2" + +[[package]] +name = "anstyle-parse" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7d1bb534e9efed14f3e5f44e7dd1a4f709384023a4165199a4241e18dff0116" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-wincon" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3127af6145b149f3287bb9a0d10ad9c5692dba8c53ad48285e5bec4063834fa" +dependencies = [ + "anstyle", + "windows-sys 0.45.0", +] + [[package]] name = "anyhow" version = "1.0.65" @@ -362,7 +402,7 @@ dependencies = [ "cargo-test-macro", "cargo-test-support", "cargo-util", - "clap 4.1.4", + "clap 4.2.1", "crates-io", "curl", "curl-sys", @@ -398,6 +438,7 @@ dependencies = [ "pasetors", "pathdiff", "pretty_env_logger", + "rand", "rustc-workspace-hack", "rustfix", "same-file", @@ -669,17 +710,27 @@ dependencies = [ [[package]] name = "clap" -version = "4.1.4" +version = "4.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f13b9c79b5d1dd500d20ef541215a6423c75829ef43117e1b4d17fd8af0b5d76" +checksum = "046ae530c528f252094e4a77886ee1374437744b2bff1497aa898bbddbbb29b3" dependencies = [ + "clap_builder", + "clap_derive 4.2.0", + "once_cell", +] + +[[package]] +name = "clap_builder" +version = "4.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "223163f58c9a40c3b0a43e1c4b50a9ce09f007ea2cb1ec258a687945b4b7929f" +dependencies = [ + "anstream", + "anstyle", "bitflags", - "clap_derive 4.1.0", - "clap_lex 0.3.0", - "is-terminal", + "clap_lex 0.4.1", "once_cell", "strsim", - "termcolor", "terminal_size", ] @@ -689,7 +740,7 @@ version = "4.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10861370d2ba66b0f5989f83ebf35db6421713fd92351790e7fdd6c36774c56b" dependencies = [ - "clap 4.1.4", + "clap 4.2.1", ] [[package]] @@ -707,15 +758,14 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.1.0" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "684a277d672e91966334af371f1a7b5833f9aa00b07c84e92fbce95e00208ce8" +checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4" dependencies = [ "heck", - "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.102", + "syn 2.0.8", ] [[package]] @@ -729,18 +779,15 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.3.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" -dependencies = [ - "os_str_bytes", -] +checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" [[package]] name = "clippy" version = "0.1.70" dependencies = [ - "clap 4.1.4", + "clap 4.2.1", "clippy_lints", "clippy_utils", "compiletest_rs", @@ -771,7 +818,7 @@ name = "clippy_dev" version = "0.0.1" dependencies = [ "aho-corasick", - "clap 4.1.4", + "clap 4.2.1", "indoc", "itertools", "opener", @@ -932,15 +979,30 @@ checksum = "b90f9dcd9490a97db91a85ccd79e38a87e14323f0bb824659ee3274e9143ba37" dependencies = [ "atty", "bitflags", - "concolor-query", + "concolor-query 0.1.0", ] +[[package]] +name = "concolor-override" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a855d4a1978dc52fb0536a04d384c2c0c1aa273597f08b77c8c4d3b2eec6037f" + [[package]] name = "concolor-query" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82a90734b3d5dcf656e7624cca6bce9c3a90ee11f900e80141a7427ccfb3d317" +[[package]] +name = "concolor-query" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88d11d52c3d7ca2e6d0040212be9e4dbbcd78b6447f535b6b561f449427944cf" +dependencies = [ + "windows-sys 0.45.0", +] + [[package]] name = "const-oid" version = "0.9.1" @@ -2844,7 +2906,7 @@ name = "jsondoclint" version = "0.1.0" dependencies = [ "anyhow", - "clap 4.1.4", + "clap 4.2.1", "fs-err", "rustc-hash", "rustdoc-json-types", @@ -3110,7 +3172,7 @@ dependencies = [ "ammonia", "anyhow", "chrono", - "clap 4.1.4", + "clap 4.2.1", "clap_complete", "elasticlunr-rs", "env_logger 0.10.0", @@ -4115,7 +4177,7 @@ dependencies = [ name = "rustbook" version = "0.1.0" dependencies = [ - "clap 4.1.4", + "clap 4.2.1", "env_logger 0.7.1", "mdbook", ] @@ -6748,9 +6810,9 @@ checksum = "05e42f7c18b8f902290b009cde6d651262f956c98bc51bca4cd1d511c9cd85c7" [[package]] name = "utf8parse" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936e4b492acfd135421d8dca4b1aa80a7bfc26e702ef3af710e0752684df5372" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "uuid" diff --git a/src/tools/cargo b/src/tools/cargo index 145219a9f08..0e474cfd7b1 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 145219a9f089f8b57c09f40525374fbade1e34ae +Subproject commit 0e474cfd7b16b018cf46e95da3f6a5b2f1f6a9e7 From ec71feb98465c27319a42d31befc6150a2c2798a Mon Sep 17 00:00:00 2001 From: Shawn M Moore <code@sartak.org> Date: Sat, 1 Apr 2023 12:57:22 -0400 Subject: [PATCH 320/346] Improve grammar of Iterator.partition_in_place b9535c0b7d6 Auto merge of #109801 - aliemjay:test-implied-normalization, r=petrochenkov --- library/core/src/iter/traits/iterator.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs index 080330fa41e..36cf7defd6d 100644 --- a/library/core/src/iter/traits/iterator.rs +++ b/library/core/src/iter/traits/iterator.rs @@ -2120,8 +2120,8 @@ pub trait Iterator { /// /// # Current implementation /// - /// Current algorithms tries finding the first element for which the predicate evaluates - /// to false, and the last element for which it evaluates to true and repeatedly swaps them. + /// The current algorithm tries to find the first element for which the predicate evaluates + /// to false and the last element for which it evaluates to true, and repeatedly swaps them. /// /// Time complexity: *O*(*n*) /// From 455a9601da16a51d6e68d31145533fed5429c55b Mon Sep 17 00:00:00 2001 From: Taiki Endo <te316e89@gmail.com> Date: Sun, 2 Apr 2023 02:14:37 +0900 Subject: [PATCH 321/346] Fix typo in std/src/os/fd/owned.rs --- library/std/src/os/fd/owned.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs index 99a4e0b5106..a40d39c5e44 100644 --- a/library/std/src/os/fd/owned.rs +++ b/library/std/src/os/fd/owned.rs @@ -268,7 +268,7 @@ impl AsFd for OwnedFd { #[inline] fn as_fd(&self) -> BorrowedFd<'_> { // Safety: `OwnedFd` and `BorrowedFd` have the same validity - // invariants, and the `BorrowdFd` is bounded by the lifetime + // invariants, and the `BorrowedFd` is bounded by the lifetime // of `&self`. unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) } } From 46f7d3deb701df13095d547110ada84d89ab4543 Mon Sep 17 00:00:00 2001 From: clubby789 <jamie@hill-daniel.co.uk> Date: Sat, 1 Apr 2023 16:49:42 +0100 Subject: [PATCH 322/346] Fix `non_exhaustive_omitted_patterns` on arguments --- .../src/thir/pattern/usefulness.rs | 3 +++ .../rfc-2008-non-exhaustive/omitted-patterns.rs | 16 ++++++++++++++++ .../omitted-patterns.stderr | 17 ++++++++++++++++- 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs index be66d0d4765..9edd7967e7a 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/usefulness.rs @@ -300,6 +300,7 @@ use rustc_arena::TypedArena; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir::def_id::DefId; use rustc_hir::HirId; +use rustc_hir::Node; use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS; use rustc_span::{Span, DUMMY_SP}; @@ -867,6 +868,8 @@ fn is_useful<'p, 'tcx>( &ctor, Constructor::Missing { nonexhaustive_enum_missing_real_variants: true } ) + // We don't want to lint patterns which are function arguments or locals + && !matches!(cx.tcx.hir().find_parent(hir_id), Some(Node::Param(_)|Node::Local(_))) { let patterns = { let mut split_wildcard = SplitWildcard::new(pcx); diff --git a/tests/ui/rfc-2008-non-exhaustive/omitted-patterns.rs b/tests/ui/rfc-2008-non-exhaustive/omitted-patterns.rs index d8f07bb8f24..7ef1d635d9c 100644 --- a/tests/ui/rfc-2008-non-exhaustive/omitted-patterns.rs +++ b/tests/ui/rfc-2008-non-exhaustive/omitted-patterns.rs @@ -184,4 +184,20 @@ fn main() { // OK: both unstable and stable fields are matched with feature on #[warn(non_exhaustive_omitted_patterns)] let UnstableStruct { stable, stable2, unstable, .. } = UnstableStruct::default(); + + // Ok: local bindings are allowed + #[deny(non_exhaustive_omitted_patterns)] + let local = NonExhaustiveEnum::Unit; + + // Ok: missing patterns will be blocked by the pattern being refutable + #[deny(non_exhaustive_omitted_patterns)] + let local_refutable @ NonExhaustiveEnum::Unit = NonExhaustiveEnum::Unit; + //~^ refutable pattern in local binding + +} + +#[deny(non_exhaustive_omitted_patterns)] +// Ok: Pattern in a param is always wildcard +pub fn takes_non_exhaustive(_: NonExhaustiveEnum) { + let _closure = |_: NonExhaustiveEnum| {}; } diff --git a/tests/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr b/tests/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr index 996bd4a1298..617c629a4fe 100644 --- a/tests/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr +++ b/tests/ui/rfc-2008-non-exhaustive/omitted-patterns.stderr @@ -184,5 +184,20 @@ note: the lint level is defined here LL | #[deny(non_exhaustive_omitted_patterns)] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 8 previous errors; 6 warnings emitted +error[E0005]: refutable pattern in local binding + --> $DIR/omitted-patterns.rs:194:9 + | +LL | let local_refutable @ NonExhaustiveEnum::Unit = NonExhaustiveEnum::Unit; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `_` not covered + | + = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant + = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html + = note: the matched value is of type `NonExhaustiveEnum` +help: you might want to use `let else` to handle the variant that isn't matched + | +LL | let local_refutable @ NonExhaustiveEnum::Unit = NonExhaustiveEnum::Unit else { todo!() }; + | ++++++++++++++++ +error: aborting due to 9 previous errors; 6 warnings emitted + +For more information about this error, try `rustc --explain E0005`. From 8ef3bf29fe47f770a52090212e3a50a0e2bc87f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= <matthias.krueger@famsik.de> Date: Sat, 1 Apr 2023 23:16:33 +0200 Subject: [PATCH 323/346] a couple clippy::complexity fixes map_identity filter_next option_as_ref_deref unnecessary_find_map redundant_slicing unnecessary_unwrap bool_comparison derivable_impls manual_flatten needless_borrowed_reference --- compiler/rustc_codegen_llvm/src/builder.rs | 4 ++-- compiler/rustc_errors/src/emitter.rs | 2 +- .../rustc_infer/src/infer/error_reporting/mod.rs | 14 +++++--------- compiler/rustc_monomorphize/src/collector.rs | 4 ++-- compiler/rustc_span/src/hygiene.rs | 2 +- .../src/traits/error_reporting/suggestions.rs | 5 ++--- src/librustdoc/config.rs | 9 ++------- src/librustdoc/html/highlight.rs | 4 ++-- src/librustdoc/html/render/sidebar.rs | 7 ++----- src/librustdoc/passes/collect_intra_doc_links.rs | 2 +- 10 files changed, 20 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 580451ba265..63e8a67db53 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -1190,8 +1190,8 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> { // Set KCFI operand bundle let is_indirect_call = unsafe { llvm::LLVMIsAFunction(llfn).is_none() }; let kcfi_bundle = - if self.tcx.sess.is_sanitizer_kcfi_enabled() && fn_abi.is_some() && is_indirect_call { - let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi.unwrap()); + if let Some(fn_abi) = fn_abi && self.tcx.sess.is_sanitizer_kcfi_enabled() && is_indirect_call { + let kcfi_typeid = kcfi_typeid_for_fnabi(self.tcx, fn_abi); Some(llvm::OperandBundleDef::new("kcfi", &[self.const_u32(kcfi_typeid)])) } else { None diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index d6fd057c5a4..4b1ff0e1df9 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -2235,7 +2235,7 @@ impl EmitterWriter { } } else if is_multiline { buffer.puts(*row_num, 0, &self.maybe_anonymized(line_num), Style::LineNumber); - match &highlight_parts[..] { + match &highlight_parts { [SubstitutionHighlight { start: 0, end }] if *end == line_to_add.len() => { buffer.puts(*row_num, max_line_num_len + 1, "+ ", Style::Addition); } diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 75c3d9f641d..1ae1e0402f7 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2399,10 +2399,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let suggestion = if has_lifetimes { format!(" + {}", sub) } else { format!(": {}", sub) }; let mut suggestions = vec![(sp, suggestion)]; - for add_lt_sugg in add_lt_suggs { - if let Some(add_lt_sugg) = add_lt_sugg { - suggestions.push(add_lt_sugg); - } + for add_lt_sugg in add_lt_suggs.into_iter().flatten() { + suggestions.push(add_lt_sugg); } err.multipart_suggestion_verbose( format!("{msg}..."), @@ -2426,11 +2424,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { }; let mut sugg = vec![(sp, suggestion), (span.shrink_to_hi(), format!(" + {}", new_lt))]; - for add_lt_sugg in add_lt_suggs.clone() { - if let Some(lt) = add_lt_sugg { - sugg.push(lt); - sugg.rotate_right(1); - } + for lt in add_lt_suggs.clone().into_iter().flatten() { + sugg.push(lt); + sugg.rotate_right(1); } // `MaybeIncorrect` due to issue #41966. err.multipart_suggestion(msg, sugg, Applicability::MaybeIncorrect); diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index d34fa39352f..f41edff8513 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -651,8 +651,8 @@ fn check_type_length_limit<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) { let (shrunk, written_to_path) = shrunk_instance_name(tcx, &instance); let span = tcx.def_span(instance.def_id()); let mut path = PathBuf::new(); - let was_written = if written_to_path.is_some() { - path = written_to_path.unwrap(); + let was_written = if let Some(path2) = written_to_path { + path = path2; Some(()) } else { None diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index d727aba6de5..0bb42a3a71f 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -109,7 +109,7 @@ fn assert_default_hashing_controls<CTX: HashStableContext>(ctx: &CTX, msg: &str) // This is the case for instance when building a hash for name mangling. // Such configuration must not be used for metadata. HashingControls { hash_spans } - if hash_spans == !ctx.unstable_opts_incremental_ignore_spans() => {} + if hash_spans != ctx.unstable_opts_incremental_ignore_spans() => {} other => panic!("Attempted hashing of {msg} with non-default HashingControls: {other:?}"), } } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index be0817472ea..fb75ec76729 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -3888,8 +3888,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { if let Some(slice_ty) = candidate_impls .iter() .map(|trait_ref| trait_ref.trait_ref.self_ty()) - .filter(|t| is_slice(*t)) - .next() + .find(|t| is_slice(*t)) { let msg = &format!("convert the array to a `{}` slice instead", slice_ty); @@ -3936,7 +3935,7 @@ fn hint_missing_borrow<'tcx>( // This could be a variant constructor, for example. let Some(fn_decl) = found_node.fn_decl() else { return; }; - let args = fn_decl.inputs.iter().map(|ty| ty); + let args = fn_decl.inputs.iter(); fn get_deref_type_and_refs(mut ty: Ty<'_>) -> (Ty<'_>, Vec<hir::Mutability>) { let mut refs = vec![]; diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 2c514a0c826..ea8c7e9a67c 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -31,18 +31,13 @@ use crate::passes::{self, Condition}; use crate::scrape_examples::{AllCallLocations, ScrapeExamplesOptions}; use crate::theme; -#[derive(Clone, Copy, PartialEq, Eq, Debug)] +#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)] pub(crate) enum OutputFormat { Json, + #[default] Html, } -impl Default for OutputFormat { - fn default() -> OutputFormat { - OutputFormat::Html - } -} - impl OutputFormat { pub(crate) fn is_json(&self) -> bool { matches!(self, OutputFormat::Json) diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index c099d0e4f3f..b61dd571458 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -177,8 +177,8 @@ impl<'a, 'tcx, F: Write> TokenHandler<'a, 'tcx, F> { } else { // We only want to "open" the tag ourselves if we have more than one pending and if the // current parent tag is not the same as our pending content. - let close_tag = if self.pending_elems.len() > 1 && current_class.is_some() { - Some(enter_span(self.out, current_class.unwrap(), &self.href_context)) + let close_tag = if self.pending_elems.len() > 1 && let Some(current_class) = current_class { + Some(enter_span(self.out, current_class, &self.href_context)) } else { None }; diff --git a/src/librustdoc/html/render/sidebar.rs b/src/librustdoc/html/render/sidebar.rs index 94ad4753d7c..455b4e9aefe 100644 --- a/src/librustdoc/html/render/sidebar.rs +++ b/src/librustdoc/html/render/sidebar.rs @@ -113,11 +113,8 @@ pub(super) fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buf } else { ("", "") }; - let version = if it.is_crate() { - cx.cache().crate_version.as_ref().map(String::as_str).unwrap_or_default() - } else { - "" - }; + let version = + if it.is_crate() { cx.cache().crate_version.as_deref().unwrap_or_default() } else { "" }; let path: String = if !it.is_mod() { cx.current.iter().map(|s| s.as_str()).intersperse("::").collect() } else { diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 4188aa1037f..1c6ab44a4c7 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -810,7 +810,7 @@ fn trait_impls_for<'a>( /// /// These are common and we should just resolve to the trait in that case. fn is_derive_trait_collision<T>(ns: &PerNS<Result<Vec<(Res, T)>, ResolutionFailure<'_>>>) -> bool { - if let (&Ok(ref type_ns), &Ok(ref macro_ns)) = (&ns.type_ns, &ns.macro_ns) { + if let (Ok(type_ns), Ok(macro_ns)) = (&ns.type_ns, &ns.macro_ns) { type_ns.iter().any(|(res, _)| matches!(res, Res::Def(DefKind::Trait, _))) && macro_ns .iter() From ac229c281981129003cfcf6ef894bb7655b0d466 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= <matthias.krueger@famsik.de> Date: Sat, 1 Apr 2023 23:44:16 +0200 Subject: [PATCH 324/346] fix clippy::iter_kv_map --- compiler/rustc_hir_analysis/src/astconv/errors.rs | 4 ++-- compiler/rustc_infer/src/infer/error_reporting/mod.rs | 2 +- compiler/rustc_middle/src/middle/mod.rs | 2 +- compiler/rustc_monomorphize/src/partitioning/default.rs | 5 +---- compiler/rustc_resolve/src/diagnostics.rs | 6 +++--- compiler/rustc_resolve/src/late.rs | 3 +-- compiler/rustc_traits/src/chalk/lowering.rs | 3 +-- 7 files changed, 10 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/astconv/errors.rs b/compiler/rustc_hir_analysis/src/astconv/errors.rs index 672e7176fde..113c3f08ab9 100644 --- a/compiler/rustc_hir_analysis/src/astconv/errors.rs +++ b/compiler/rustc_hir_analysis/src/astconv/errors.rs @@ -483,8 +483,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { [segment] if segment.args.is_none() => { trait_bound_spans = vec![segment.ident.span]; associated_types = associated_types - .into_iter() - .map(|(_, items)| (segment.ident.span, items)) + .into_values() + .map(|items| (segment.ident.span, items)) .collect(); } _ => {} diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 75c3d9f641d..1f9c993adff 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -978,7 +978,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let (_, sig, reg) = ty::print::FmtPrinter::new(self.tcx, Namespace::TypeNS) .name_all_regions(sig) .unwrap(); - let lts: Vec<String> = reg.into_iter().map(|(_, kind)| kind.to_string()).collect(); + let lts: Vec<String> = reg.into_values().map(|kind| kind.to_string()).collect(); (if lts.is_empty() { String::new() } else { format!("for<{}> ", lts.join(", ")) }, sig) }; diff --git a/compiler/rustc_middle/src/middle/mod.rs b/compiler/rustc_middle/src/middle/mod.rs index 0b6774f1b1f..9c25f3009ba 100644 --- a/compiler/rustc_middle/src/middle/mod.rs +++ b/compiler/rustc_middle/src/middle/mod.rs @@ -19,7 +19,7 @@ pub mod lib_features { .stable .iter() .map(|(f, (s, _))| (*f, Some(*s))) - .chain(self.unstable.iter().map(|(f, _)| (*f, None))) + .chain(self.unstable.keys().map(|f| (*f, None))) .collect(); all_features.sort_unstable_by(|a, b| a.0.as_str().partial_cmp(b.0.as_str()).unwrap()); all_features diff --git a/compiler/rustc_monomorphize/src/partitioning/default.rs b/compiler/rustc_monomorphize/src/partitioning/default.rs index 50bcc3336d6..482b78d42e3 100644 --- a/compiler/rustc_monomorphize/src/partitioning/default.rs +++ b/compiler/rustc_monomorphize/src/partitioning/default.rs @@ -89,10 +89,7 @@ impl<'tcx> Partitioner<'tcx> for DefaultPartitioning { } PreInliningPartitioning { - codegen_units: codegen_units - .into_iter() - .map(|(_, codegen_unit)| codegen_unit) - .collect(), + codegen_units: codegen_units.into_values().map(|codegen_unit| codegen_unit).collect(), roots, internalization_candidates, } diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 44a3d4e628e..e69a9d0aeca 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1669,8 +1669,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ) -> Option<Symbol> { let mut candidates = self .extern_prelude - .iter() - .map(|(ident, _)| ident.name) + .keys() + .map(|ident| ident.name) .chain( self.module_map .iter() @@ -2007,7 +2007,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // 1) some consistent ordering for emitted diagnostics, and // 2) `std` suggestions before `core` suggestions. let mut extern_crate_names = - self.extern_prelude.iter().map(|(ident, _)| ident.name).collect::<Vec<_>>(); + self.extern_prelude.keys().map(|ident| ident.name).collect::<Vec<_>>(); extern_crate_names.sort_by(|a, b| b.as_str().partial_cmp(a.as_str()).unwrap()); for name in extern_crate_names.into_iter() { diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index f66bad1d429..b82b07bcf0c 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2421,8 +2421,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { .iter() .rfind(|r| matches!(r.kind, ItemRibKind(_))) .expect("associated item outside of an item"); - seen_bindings - .extend(parent_rib.bindings.iter().map(|(ident, _)| (*ident, ident.span))); + seen_bindings.extend(parent_rib.bindings.keys().map(|ident| (*ident, ident.span))); }; add_bindings_for_ns(ValueNS); add_bindings_for_ns(TypeNS); diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 0e9bccba8d4..527f6013a15 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -909,8 +909,7 @@ pub(crate) fn collect_bound_vars<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>( .or_else(|| bug!("Skipped bound var index: parameters={:?}", parameters)); }); - let binders = - chalk_ir::VariableKinds::from_iter(interner, parameters.into_iter().map(|(_, v)| v)); + let binders = chalk_ir::VariableKinds::from_iter(interner, parameters.into_values()); (new_ty, binders, named_parameters) } From 5a07e33d2cc57d929bbd50a22cad703d4c666fc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= <matthias.krueger@famsik.de> Date: Sat, 1 Apr 2023 23:50:45 +0200 Subject: [PATCH 325/346] use and_then/flat_map for map().flatten() --- compiler/rustc_codegen_llvm/src/common.rs | 3 +-- compiler/rustc_middle/src/ty/consts/valtree.rs | 2 +- compiler/rustc_mir_build/src/build/expr/as_constant.rs | 6 +++--- compiler/rustc_session/src/options.rs | 2 +- .../rustc_trait_selection/src/traits/outlives_bounds.rs | 4 +--- 5 files changed, 7 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index efa0c13226e..4f8b5abd901 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -378,8 +378,7 @@ pub(crate) fn get_dllimport<'tcx>( name: &str, ) -> Option<&'tcx DllImport> { tcx.native_library(id) - .map(|lib| lib.dll_imports.iter().find(|di| di.name.as_str() == name)) - .flatten() + .and_then(|lib| lib.dll_imports.iter().find(|di| di.name.as_str() == name)) } pub(crate) fn is_mingw_gnu_toolchain(target: &Target) -> bool { diff --git a/compiler/rustc_middle/src/ty/consts/valtree.rs b/compiler/rustc_middle/src/ty/consts/valtree.rs index 5ed4af2e922..8b96864ddd7 100644 --- a/compiler/rustc_middle/src/ty/consts/valtree.rs +++ b/compiler/rustc_middle/src/ty/consts/valtree.rs @@ -79,7 +79,7 @@ impl<'tcx> ValTree<'tcx> { } pub fn try_to_target_usize(self, tcx: TyCtxt<'tcx>) -> Option<u64> { - self.try_to_scalar_int().map(|s| s.try_to_target_usize(tcx).ok()).flatten() + self.try_to_scalar_int().and_then(|s| s.try_to_target_usize(tcx).ok()) } /// Get the values inside the ValTree as a slice of bytes. This only works for diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index cfacb5ea327..99291740ac8 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -62,21 +62,21 @@ pub fn as_constant_inner<'tcx>( Constant { span, user_ty: None, literal } } ExprKind::NonHirLiteral { lit, ref user_ty } => { - let user_ty = user_ty.as_ref().map(push_cuta).flatten(); + let user_ty = user_ty.as_ref().and_then(push_cuta); let literal = ConstantKind::Val(ConstValue::Scalar(Scalar::Int(lit)), ty); Constant { span, user_ty, literal } } ExprKind::ZstLiteral { ref user_ty } => { - let user_ty = user_ty.as_ref().map(push_cuta).flatten(); + let user_ty = user_ty.as_ref().and_then(push_cuta); let literal = ConstantKind::Val(ConstValue::ZeroSized, ty); Constant { span, user_ty, literal } } ExprKind::NamedConst { def_id, substs, ref user_ty } => { - let user_ty = user_ty.as_ref().map(push_cuta).flatten(); + let user_ty = user_ty.as_ref().and_then(push_cuta); let uneval = mir::UnevaluatedConst::new(ty::WithOptConstParam::unknown(def_id), substs); let literal = ConstantKind::Unevaluated(uneval, ty); diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index c75af48e80a..be5d4fca7a0 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -911,7 +911,7 @@ mod parse { let mut seen_instruction_threshold = false; let mut seen_skip_entry = false; let mut seen_skip_exit = false; - for option in v.into_iter().map(|v| v.split(',')).flatten() { + for option in v.into_iter().flat_map(|v| v.split(',')) { match option { "always" if !seen_always && !seen_never => { options.always = true; diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs index 6d2dc94845d..cff3d277a78 100644 --- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs @@ -110,8 +110,6 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> { body_id: LocalDefId, tys: FxIndexSet<Ty<'tcx>>, ) -> Bounds<'a, 'tcx> { - tys.into_iter() - .map(move |ty| self.implied_outlives_bounds(param_env, body_id, ty)) - .flatten() + tys.into_iter().flat_map(move |ty| self.implied_outlives_bounds(param_env, body_id, ty)) } } From 73bd953dea25e0aa225eaf8844f2d06807691e3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Kr=C3=BCger?= <matthias.krueger@famsik.de> Date: Sat, 1 Apr 2023 23:55:22 +0200 Subject: [PATCH 326/346] slighty simplify a few boolean expressions (clippy::nonminimal_bool) --- compiler/rustc_const_eval/src/transform/validate.rs | 3 +-- compiler/rustc_hir_typeck/src/expr_use_visitor.rs | 2 +- compiler/rustc_passes/src/entry.rs | 2 +- compiler/rustc_resolve/src/ident.rs | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs index cd5c92f7342..558253f727b 100644 --- a/compiler/rustc_const_eval/src/transform/validate.rs +++ b/compiler/rustc_const_eval/src/transform/validate.rs @@ -677,8 +677,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { ); } if let Rvalue::CopyForDeref(place) = rvalue { - if !place.ty(&self.body.local_decls, self.tcx).ty.builtin_deref(true).is_some() - { + if place.ty(&self.body.local_decls, self.tcx).ty.builtin_deref(true).is_none() { self.fail( location, "`CopyForDeref` should only be used for dereferenceable types", diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 58902cd292c..ee1c6fbfd65 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -559,7 +559,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { // struct; however, when EUV is run during typeck, it // may not. This will generate an error earlier in typeck, // so we can just ignore it. - if !self.tcx().sess.has_errors().is_some() { + if self.tcx().sess.has_errors().is_none() { span_bug!(with_expr.span, "with expression doesn't evaluate to a struct"); } } diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs index f3e683f4b3a..8c3dff23b27 100644 --- a/compiler/rustc_passes/src/entry.rs +++ b/compiler/rustc_passes/src/entry.rs @@ -206,7 +206,7 @@ fn no_main_err(tcx: TyCtxt<'_>, visitor: &EntryContext<'_>) { // The file may be empty, which leads to the diagnostic machinery not emitting this // note. This is a relatively simple way to detect that case and emit a span-less // note instead. - let file_empty = !tcx.sess.source_map().lookup_line(sp.hi()).is_ok(); + let file_empty = tcx.sess.source_map().lookup_line(sp.hi()).is_err(); tcx.sess.emit_err(NoMainErr { sp, diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index 52f0b65fad6..06206efb9ab 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -389,7 +389,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } - assert!(force || !finalize.is_some()); // `finalize` implies `force` + assert!(force || finalize.is_none()); // `finalize` implies `force` // Make sure `self`, `super` etc produce an error when passed to here. if orig_ident.is_path_segment_keyword() { From b5b6def021d37c5f1cb7e06c1cf6915bcbcd53b1 Mon Sep 17 00:00:00 2001 From: Scott McMurray <scottmcm@users.noreply.github.com> Date: Sat, 1 Apr 2023 20:11:38 -0700 Subject: [PATCH 327/346] Use `FieldIdx` in various things related to aggregates Shrank `AggregateKind` by 8 bytes on x64, since the active field of a union is tracked as an `Option<FieldIdx>` instead of `Option<usize>`. --- .../rustc_borrowck/src/diagnostics/mod.rs | 5 +++-- compiler/rustc_borrowck/src/lib.rs | 2 +- compiler/rustc_borrowck/src/type_check/mod.rs | 19 +++++++++---------- compiler/rustc_codegen_cranelift/src/base.rs | 7 ++++--- compiler/rustc_codegen_ssa/src/base.rs | 6 +++--- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 6 +++--- .../rustc_const_eval/src/interpret/place.rs | 9 +++++---- compiler/rustc_index/src/vec.rs | 6 ++++++ compiler/rustc_middle/src/mir/syntax.rs | 7 ++++--- .../src/build/custom/parse/instruction.rs | 2 +- .../src/build/expr/as_rvalue.rs | 13 ++++++------- .../rustc_mir_build/src/build/expr/into.rs | 11 ++++------- compiler/rustc_mir_transform/src/generator.rs | 4 ++-- 13 files changed, 51 insertions(+), 46 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index da0456856ac..7bd4331c5ed 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -6,6 +6,7 @@ use rustc_errors::{Applicability, Diagnostic}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, Namespace}; use rustc_hir::GeneratorKind; +use rustc_index::vec::IndexSlice; use rustc_infer::infer::{LateBoundRegionConversionTime, TyCtxtInferExt}; use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::{ @@ -825,7 +826,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { debug!("move_spans: def_id={:?} place={:?}", closure_def_id, place); let places = &[Operand::Move(place)]; if let Some((args_span, generator_kind, capture_kind_span, path_span)) = - self.closure_span(closure_def_id, moved_place, places) + self.closure_span(closure_def_id, moved_place, IndexSlice::from_raw(places)) { return ClosureUse { generator_kind, @@ -975,7 +976,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &self, def_id: LocalDefId, target_place: PlaceRef<'tcx>, - places: &[Operand<'tcx>], + places: &IndexSlice<FieldIdx, Operand<'tcx>>, ) -> Option<(Span, Option<GeneratorKind>, Span, Span)> { debug!( "closure_span: def_id={:?} target_place={:?} places={:?}", diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 8b463a018a8..ba322425089 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -1343,7 +1343,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { self.infcx.tcx.mir_borrowck(def_id); debug!("{:?} used_mut_upvars={:?}", def_id, used_mut_upvars); for field in used_mut_upvars { - self.propagate_closure_used_mut_upvar(&operands[field.index()]); + self.propagate_closure_used_mut_upvar(&operands[*field]); } } AggregateKind::Adt(..) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 10bbce37760..f3fe5a6cada 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -14,7 +14,7 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::LocalDefId; use rustc_hir::lang_items::LangItem; -use rustc_index::vec::IndexVec; +use rustc_index::vec::{IndexSlice, IndexVec}; use rustc_infer::infer::canonical::QueryRegionConstraints; use rustc_infer::infer::outlives::env::RegionBoundPairs; use rustc_infer::infer::region_constraints::RegionConstraintData; @@ -1716,7 +1716,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { fn aggregate_field_ty( &mut self, ak: &AggregateKind<'tcx>, - field_index: usize, + field_index: FieldIdx, location: Location, ) -> Result<Ty<'tcx>, FieldAccessError> { let tcx = self.tcx(); @@ -1725,8 +1725,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { AggregateKind::Adt(adt_did, variant_index, substs, _, active_field_index) => { let def = tcx.adt_def(adt_did); let variant = &def.variant(variant_index); - let adj_field_index = - FieldIdx::from_usize(active_field_index.unwrap_or(field_index)); + let adj_field_index = active_field_index.unwrap_or(field_index); if let Some(field) = variant.fields.get(adj_field_index) { Ok(self.normalize(field.ty(tcx, substs), location)) } else { @@ -1734,7 +1733,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } AggregateKind::Closure(_, substs) => { - match substs.as_closure().upvar_tys().nth(field_index) { + match substs.as_closure().upvar_tys().nth(field_index.as_usize()) { Some(ty) => Ok(ty), None => Err(FieldAccessError::OutOfRange { field_count: substs.as_closure().upvar_tys().count(), @@ -1745,7 +1744,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // It doesn't make sense to look at a field beyond the prefix; // these require a variant index, and are not initialized in // aggregate rvalues. - match substs.as_generator().prefix_tys().nth(field_index) { + match substs.as_generator().prefix_tys().nth(field_index.as_usize()) { Some(ty) => Ok(ty), None => Err(FieldAccessError::OutOfRange { field_count: substs.as_generator().prefix_tys().count(), @@ -2350,7 +2349,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { body: &Body<'tcx>, rvalue: &Rvalue<'tcx>, aggregate_kind: &AggregateKind<'tcx>, - operands: &[Operand<'tcx>], + operands: &IndexSlice<FieldIdx, Operand<'tcx>>, location: Location, ) { let tcx = self.tcx(); @@ -2362,7 +2361,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { return; } - for (i, operand) in operands.iter().enumerate() { + for (i, operand) in operands.iter_enumerated() { let field_ty = match self.aggregate_field_ty(aggregate_kind, i, location) { Ok(field_ty) => field_ty, Err(FieldAccessError::OutOfRange { field_count }) => { @@ -2370,8 +2369,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self, rvalue, "accessed field #{} but variant only has {}", - i, - field_count + i.as_u32(), + field_count, ); continue; } diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs index 98112fe0830..2630f02e6eb 100644 --- a/compiler/rustc_codegen_cranelift/src/base.rs +++ b/compiler/rustc_codegen_cranelift/src/base.rs @@ -802,14 +802,15 @@ fn codegen_stmt<'tcx>( if active_field_index.is_some() { assert_eq!(operands.len(), 1); } - for (i, operand) in operands.iter().enumerate() { + for (i, operand) in operands.iter_enumerated() { let operand = codegen_operand(fx, operand); let field_index = active_field_index.unwrap_or(i); let to = if let mir::AggregateKind::Array(_) = **kind { - let index = fx.bcx.ins().iconst(fx.pointer_type, field_index as i64); + let array_index = i64::from(field_index.as_u32()); + let index = fx.bcx.ins().iconst(fx.pointer_type, array_index); variant_dest.place_index(fx, index) } else { - variant_dest.place_field(fx, FieldIdx::new(field_index)) + variant_dest.place_field(fx, field_index) }; to.write_cvalue(fx, operand); } diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 6c4ca8f7fb1..c5ca7936a2b 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -306,9 +306,9 @@ pub fn coerce_unsized_into<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => { assert_eq!(def_a, def_b); - for i in 0..def_a.variant(FIRST_VARIANT).fields.len() { - let src_f = src.project_field(bx, i); - let dst_f = dst.project_field(bx, i); + for i in def_a.variant(FIRST_VARIANT).fields.indices() { + let src_f = src.project_field(bx, i.as_usize()); + let dst_f = dst.project_field(bx, i.as_usize()); if dst_f.layout.is_zst() { continue; diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 0a59fabdc17..d49d23afe51 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -123,16 +123,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if active_field_index.is_some() { assert_eq!(operands.len(), 1); } - for (i, operand) in operands.iter().enumerate() { + for (i, operand) in operands.iter_enumerated() { let op = self.codegen_operand(bx, operand); // Do not generate stores and GEPis for zero-sized fields. if !op.layout.is_zst() { let field_index = active_field_index.unwrap_or(i); let field = if let mir::AggregateKind::Array(_) = **kind { - let llindex = bx.cx().const_usize(field_index as u64); + let llindex = bx.cx().const_usize(field_index.as_u32().into()); variant_dest.project_index(bx, llindex) } else { - variant_dest.project_field(bx, field_index) + variant_dest.project_field(bx, field_index.as_usize()) }; op.val.store(bx, field); } diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index a95bcaa3f99..03b09cf830b 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -5,10 +5,11 @@ use either::{Either, Left, Right}; use rustc_ast::Mutability; +use rustc_index::vec::IndexSlice; use rustc_middle::mir; use rustc_middle::ty; use rustc_middle::ty::layout::{LayoutOf, TyAndLayout}; -use rustc_target::abi::{self, Abi, Align, HasDataLayout, Size, FIRST_VARIANT}; +use rustc_target::abi::{self, Abi, Align, FieldIdx, HasDataLayout, Size, FIRST_VARIANT}; use super::{ alloc_range, mir_assign_valid_types, AllocId, AllocRef, AllocRefMut, CheckInAllocMsg, @@ -787,7 +788,7 @@ where pub fn write_aggregate( &mut self, kind: &mir::AggregateKind<'tcx>, - operands: &[mir::Operand<'tcx>], + operands: &IndexSlice<FieldIdx, mir::Operand<'tcx>>, dest: &PlaceTy<'tcx, M::Provenance>, ) -> InterpResult<'tcx> { self.write_uninit(&dest)?; @@ -801,9 +802,9 @@ where if active_field_index.is_some() { assert_eq!(operands.len(), 1); } - for (field_index, operand) in operands.iter().enumerate() { + for (field_index, operand) in operands.iter_enumerated() { let field_index = active_field_index.unwrap_or(field_index); - let field_dest = self.place_field(&variant_dest, field_index)?; + let field_dest = self.place_field(&variant_dest, field_index.as_usize())?; let op = self.eval_operand(operand, Some(field_dest.layout))?; self.copy_op(&op, &field_dest, /*allow_transmute*/ false)?; } diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs index 596849bd456..6caae059f4a 100644 --- a/compiler/rustc_index/src/vec.rs +++ b/compiler/rustc_index/src/vec.rs @@ -93,6 +93,12 @@ impl<I: Idx, T: fmt::Debug> fmt::Debug for IndexVec<I, T> { } } +impl<I: Idx, T: fmt::Debug> fmt::Debug for IndexSlice<I, T> { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::Debug::fmt(&self.raw, fmt) + } +} + impl<I: Idx, T> IndexVec<I, T> { #[inline] pub fn new() -> Self { diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 413a7629b9a..cc35e6106e2 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -16,6 +16,7 @@ use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece}; use rustc_hir::def_id::DefId; use rustc_hir::{self as hir}; use rustc_hir::{self, GeneratorKind}; +use rustc_index::vec::IndexVec; use rustc_target::abi::{FieldIdx, VariantIdx}; use rustc_ast::Mutability; @@ -1125,7 +1126,7 @@ pub enum Rvalue<'tcx> { /// /// Disallowed after deaggregation for all aggregate kinds except `Array` and `Generator`. After /// generator lowering, `Generator` aggregate kinds are disallowed too. - Aggregate(Box<AggregateKind<'tcx>>, Vec<Operand<'tcx>>), + Aggregate(Box<AggregateKind<'tcx>>, IndexVec<FieldIdx, Operand<'tcx>>), /// Transmutes a `*mut u8` into shallow-initialized `Box<T>`. /// @@ -1186,7 +1187,7 @@ pub enum AggregateKind<'tcx> { /// active field number and is present only for union expressions /// -- e.g., for a union expression `SomeUnion { c: .. }`, the /// active field index would identity the field `c` - Adt(DefId, VariantIdx, SubstsRef<'tcx>, Option<UserTypeAnnotationIndex>, Option<usize>), + Adt(DefId, VariantIdx, SubstsRef<'tcx>, Option<UserTypeAnnotationIndex>, Option<FieldIdx>), Closure(DefId, SubstsRef<'tcx>), Generator(DefId, SubstsRef<'tcx>, hir::Movability), @@ -1263,7 +1264,7 @@ pub enum BinOp { mod size_asserts { use super::*; // tidy-alphabetical-start - static_assert_size!(AggregateKind<'_>, 40); + static_assert_size!(AggregateKind<'_>, 32); static_assert_size!(Operand<'_>, 24); static_assert_size!(Place<'_>, 16); static_assert_size!(PlaceElem<'_>, 24); diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs index 77a5017b363..33b73928704 100644 --- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs @@ -185,7 +185,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { }, ExprKind::Adt(box AdtExpr{ adt_def, variant_index, substs, fields, .. }) => { let is_union = adt_def.is_union(); - let active_field_index = is_union.then(|| fields[0].name.index()); + let active_field_index = is_union.then(|| fields[0].name); Ok(Rvalue::Aggregate( Box::new(AggregateKind::Adt(adt_def.did(), *variant_index, substs, None, active_field_index)), diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index d1878bf77ef..baa12ec11c3 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -1,8 +1,8 @@ //! See docs in `build/expr/mod.rs`. -use rustc_index::vec::Idx; +use rustc_index::vec::{Idx, IndexVec}; use rustc_middle::ty::util::IntTypeExt; -use rustc_target::abi::{Abi, Primitive}; +use rustc_target::abi::{Abi, FieldIdx, Primitive}; use crate::build::expr::as_place::PlaceBase; use crate::build::expr::category::{Category, RvalueFunc}; @@ -17,7 +17,6 @@ use rustc_middle::thir::*; use rustc_middle::ty::cast::{mir_cast_kind, CastTy}; use rustc_middle::ty::{self, Ty, UpvarSubsts}; use rustc_span::Span; -use rustc_target::abi::FieldIdx; impl<'a, 'tcx> Builder<'a, 'tcx> { /// Returns an rvalue suitable for use until the end of the current @@ -327,7 +326,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // first process the set of fields let el_ty = expr.ty.sequence_element_type(this.tcx); - let fields: Vec<_> = fields + let fields: IndexVec<FieldIdx, _> = fields .into_iter() .copied() .map(|f| { @@ -348,7 +347,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ExprKind::Tuple { ref fields } => { // see (*) above // first process the set of fields - let fields: Vec<_> = fields + let fields: IndexVec<FieldIdx, _> = fields .into_iter() .copied() .map(|f| { @@ -402,7 +401,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } // see (*) above - let operands: Vec<_> = upvars + let operands: IndexVec<FieldIdx, _> = upvars .into_iter() .copied() .map(|upvar| { @@ -710,7 +709,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } this.record_operands_moved(&[value_operand]); } - block.and(Rvalue::Aggregate(Box::new(AggregateKind::Array(elem_ty)), Vec::new())) + block.and(Rvalue::Aggregate(Box::new(AggregateKind::Array(elem_ty)), IndexVec::new())) } fn limit_capture_mutability( diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index b8260c719c8..8efaba1f602 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -6,11 +6,9 @@ use rustc_ast::InlineAsmOptions; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir as hir; -use rustc_index::vec::Idx; use rustc_middle::mir::*; use rustc_middle::thir::*; use rustc_middle::ty::CanonicalUserTypeAnnotation; -use rustc_target::abi::FieldIdx; use std::iter; impl<'a, 'tcx> Builder<'a, 'tcx> { @@ -320,7 +318,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // See the notes for `ExprKind::Array` in `as_rvalue` and for // `ExprKind::Borrow` above. let is_union = adt_def.is_union(); - let active_field_index = is_union.then(|| fields[0].name.index()); + let active_field_index = is_union.then(|| fields[0].name); let scope = this.local_scope(); @@ -344,10 +342,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }) .collect(); - let field_names: Vec<_> = - (0..adt_def.variant(variant_index).fields.len()).map(FieldIdx::new).collect(); + let field_names = adt_def.variant(variant_index).fields.indices(); - let fields: Vec<_> = if let Some(FruInfo { base, field_types }) = base { + let fields = if let Some(FruInfo { base, field_types }) = base { let place_builder = unpack!(block = this.as_place_builder(block, &this.thir[*base])); @@ -364,7 +361,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }) .collect() } else { - field_names.iter().filter_map(|n| fields_map.get(n).cloned()).collect() + field_names.filter_map(|n| fields_map.get(&n).cloned()).collect() }; let inferred_ty = expr.ty; diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs index 50538248d91..af6422c7246 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/generator.rs @@ -274,7 +274,7 @@ impl<'tcx> TransformVisitor<'tcx> { statements.push(Statement { kind: StatementKind::Assign(Box::new(( Place::return_place(), - Rvalue::Aggregate(Box::new(kind), vec![]), + Rvalue::Aggregate(Box::new(kind), IndexVec::new()), ))), source_info, }); @@ -287,7 +287,7 @@ impl<'tcx> TransformVisitor<'tcx> { statements.push(Statement { kind: StatementKind::Assign(Box::new(( Place::return_place(), - Rvalue::Aggregate(Box::new(kind), vec![val]), + Rvalue::Aggregate(Box::new(kind), IndexVec::from_iter([val])), ))), source_info, }); From 28b7e6abff37d280f7077ed1f362ed7954753c75 Mon Sep 17 00:00:00 2001 From: Jynn Nelson <jyn.nelson@redjack.com> Date: Fri, 31 Mar 2023 07:15:42 -0400 Subject: [PATCH 328/346] Replace any existing `build/host` symlink This has two advantages: 1. If `build.build` changes between runs, the symlink is no longer silently wrong. 2. If the entire build directory is moved, the symlink is no longer broken because it points to the wrong absolute path. --- src/bootstrap/lib.rs | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 2ffad594fc7..e3f3ab5243e 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -21,7 +21,6 @@ use std::collections::{HashMap, HashSet}; use std::env; use std::fs::{self, File}; use std::io; -use std::io::ErrorKind; use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; use std::str; @@ -505,16 +504,18 @@ impl Build { let build_triple = build.out.join(&build.build.triple); t!(fs::create_dir_all(&build_triple)); let host = build.out.join("host"); - if let Err(e) = symlink_dir(&build.config, &build_triple, &host) { - if e.kind() != ErrorKind::AlreadyExists { - panic!( - "symlink_dir({} => {}) failed with {}", - host.display(), - build_triple.display(), - e - ); - } + if host.is_symlink() { + // Left over from a previous build; overwrite it. + // This matters if `build.build` has changed between invocations. + #[cfg(windows)] + t!(fs::remove_dir(&host)); + #[cfg(not(windows))] + t!(fs::remove_file(&host)); } + t!( + symlink_dir(&build.config, &build_triple, &host), + format!("symlink_dir({} => {}) failed", host.display(), build_triple.display()) + ); build } From 5d1ee66abedd083dcbc3ee691379e43430bc3197 Mon Sep 17 00:00:00 2001 From: ozkanonur <work@onurozkan.dev> Date: Sun, 2 Apr 2023 19:00:00 +0300 Subject: [PATCH 329/346] fix `build --stage 2 compiler/rustc` panic Signed-off-by: ozkanonur <work@onurozkan.dev> --- src/bootstrap/compile.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 07c0d2233ca..cf31d99d1b8 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -1295,6 +1295,13 @@ impl Step for Assemble { // when not performing a full bootstrap). builder.ensure(Rustc::new(build_compiler, target_compiler.host)); + // FIXME: For now patch over problems noted in #90244 by early returning here, even though + // we've not properly assembled the target sysroot. A full fix is pending further investigation, + // for now full bootstrap usage is rare enough that this is OK. + if target_compiler.stage >= 3 && !builder.config.full_bootstrap { + return target_compiler; + } + for &backend in builder.config.rust_codegen_backends.iter() { if backend == "llvm" { continue; // Already built as part of rustc From c45037b95641f22ec53a39bd13e2535d4d1605bd Mon Sep 17 00:00:00 2001 From: jyn <jyn.nelson@redjack.com> Date: Sun, 2 Apr 2023 17:25:20 -0400 Subject: [PATCH 330/346] try to fix test-various --- .../hotplug_codegen_backend/Makefile | 2 +- .../hotplug_codegen_backend/some_crate.rs | 0 .../hotplug_codegen_backend/the_backend.rs | 0 tests/run-make/compiler-lookup-paths/Makefile | 3 +++ 4 files changed, 4 insertions(+), 1 deletion(-) rename tests/{run-make => run-make-fulldeps}/hotplug_codegen_backend/Makefile (97%) rename tests/{run-make => run-make-fulldeps}/hotplug_codegen_backend/some_crate.rs (100%) rename tests/{run-make => run-make-fulldeps}/hotplug_codegen_backend/the_backend.rs (100%) diff --git a/tests/run-make/hotplug_codegen_backend/Makefile b/tests/run-make-fulldeps/hotplug_codegen_backend/Makefile similarity index 97% rename from tests/run-make/hotplug_codegen_backend/Makefile rename to tests/run-make-fulldeps/hotplug_codegen_backend/Makefile index 4cda243ffb5..6752091e699 100644 --- a/tests/run-make/hotplug_codegen_backend/Makefile +++ b/tests/run-make-fulldeps/hotplug_codegen_backend/Makefile @@ -1,4 +1,4 @@ -include ../tools.mk +include ../../run-make/tools.mk # ignore-stage1 diff --git a/tests/run-make/hotplug_codegen_backend/some_crate.rs b/tests/run-make-fulldeps/hotplug_codegen_backend/some_crate.rs similarity index 100% rename from tests/run-make/hotplug_codegen_backend/some_crate.rs rename to tests/run-make-fulldeps/hotplug_codegen_backend/some_crate.rs diff --git a/tests/run-make/hotplug_codegen_backend/the_backend.rs b/tests/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs similarity index 100% rename from tests/run-make/hotplug_codegen_backend/the_backend.rs rename to tests/run-make-fulldeps/hotplug_codegen_backend/the_backend.rs diff --git a/tests/run-make/compiler-lookup-paths/Makefile b/tests/run-make/compiler-lookup-paths/Makefile index c16bf7af6c4..310d6772c34 100644 --- a/tests/run-make/compiler-lookup-paths/Makefile +++ b/tests/run-make/compiler-lookup-paths/Makefile @@ -1,5 +1,8 @@ include ../tools.mk +# ignore-wasm32 (need a C compiler) +# ignore-wasm64 (need a C compiler) + all: $(TMPDIR)/libnative.a mkdir -p $(TMPDIR)/crate mkdir -p $(TMPDIR)/native From 423e76f1ddf2ffeec4235b09946f563d3ddb6004 Mon Sep 17 00:00:00 2001 From: jyn <jyn.nelson@redjack.com> Date: Sun, 2 Apr 2023 17:48:12 -0400 Subject: [PATCH 331/346] Improve job names in Github Actions preview Before: `CI / PR (mingw-check, false, ubuntu-20.04-16core-64gb) (pull_request)` After: `CI / PR - mingw-check (pull_request)` --- .github/workflows/ci.yml | 6 +++--- src/ci/github-actions/ci.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b45246eb4ea..a917d9a7d55 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,7 +34,7 @@ jobs: pr: permissions: actions: write - name: PR + name: "PR - ${{ matrix.name }}" env: CI_JOB_NAME: "${{ matrix.name }}" CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse @@ -159,7 +159,7 @@ jobs: auto: permissions: actions: write - name: auto + name: "auto - ${{ matrix.name }}" env: CI_JOB_NAME: "${{ matrix.name }}" CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse @@ -578,7 +578,7 @@ jobs: try: permissions: actions: write - name: try + name: "try - ${{ matrix.name }}" env: CI_JOB_NAME: "${{ matrix.name }}" CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index c594288dcf8..403953b5047 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -284,7 +284,7 @@ jobs: permissions: actions: write # for rust-lang/simpleinfra/github-actions/cancel-outdated-builds <<: *base-ci-job - name: PR + name: PR - ${{ matrix.name }} env: <<: [*shared-ci-variables, *public-variables] if: github.event_name == 'pull_request' @@ -312,7 +312,7 @@ jobs: permissions: actions: write # for rust-lang/simpleinfra/github-actions/cancel-outdated-builds <<: *base-ci-job - name: auto + name: auto - ${{ matrix.name }} env: <<: [*shared-ci-variables, *prod-variables] if: github.event_name == 'push' && github.ref == 'refs/heads/auto' && github.repository == 'rust-lang-ci/rust' @@ -741,7 +741,7 @@ jobs: permissions: actions: write # for rust-lang/simpleinfra/github-actions/cancel-outdated-builds <<: *base-ci-job - name: try + name: try - ${{ matrix.name }} env: <<: [*shared-ci-variables, *prod-variables] if: github.event_name == 'push' && (github.ref == 'refs/heads/try' || github.ref == 'refs/heads/try-perf') && github.repository == 'rust-lang-ci/rust' From dd85271ef5ea61fc4be3cd7607c838b99f8740f5 Mon Sep 17 00:00:00 2001 From: Mark Rousskov <mark.simulacrum@gmail.com> Date: Sun, 2 Apr 2023 19:02:55 -0400 Subject: [PATCH 332/346] Include invocation start times For multi-invocation builders (e.g., dist-x86_64-linux) this timestamp is necessary to correlate the data in the metrics JSON with other data sources (e.g., logs, cpu-usage CSV, etc.). Such correlation may not be perfect but is sometimes helpful and awkward to do otherwise. --- src/bootstrap/metrics.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/metrics.rs b/src/bootstrap/metrics.rs index 5f254761aa1..82b123ec8a5 100644 --- a/src/bootstrap/metrics.rs +++ b/src/bootstrap/metrics.rs @@ -11,7 +11,7 @@ use serde_derive::{Deserialize, Serialize}; use std::cell::RefCell; use std::fs::File; use std::io::BufWriter; -use std::time::{Duration, Instant}; +use std::time::{Duration, Instant, SystemTime}; use sysinfo::{CpuExt, System, SystemExt}; pub(crate) struct BuildMetrics { @@ -27,6 +27,7 @@ impl BuildMetrics { system_info: System::new(), timer_start: None, invocation_timer_start: Instant::now(), + invocation_start: SystemTime::now(), }); BuildMetrics { state } @@ -124,6 +125,11 @@ impl BuildMetrics { } }; invocations.push(JsonInvocation { + start_time: state + .invocation_start + .duration_since(SystemTime::UNIX_EPOCH) + .unwrap() + .as_secs(), duration_including_children_sec: state.invocation_timer_start.elapsed().as_secs_f64(), children: steps.into_iter().map(|step| self.prepare_json_step(step)).collect(), }); @@ -166,6 +172,7 @@ struct MetricsState { system_info: System, timer_start: Option<Instant>, invocation_timer_start: Instant, + invocation_start: SystemTime, } struct StepMetrics { @@ -194,6 +201,10 @@ struct JsonRoot { #[derive(Serialize, Deserialize)] #[serde(rename_all = "snake_case")] struct JsonInvocation { + // Unix timestamp in seconds + // + // This is necessary to easily correlate this invocation with logs or other data. + start_time: u64, duration_including_children_sec: f64, children: Vec<JsonNode>, } From 01b75e20f2f92e3086bc004cd2f4430bf41ccdc0 Mon Sep 17 00:00:00 2001 From: jyn <jyn.nelson@redjack.com> Date: Sun, 2 Apr 2023 19:30:32 -0400 Subject: [PATCH 333/346] Move some UI tests into subdirectories to avoid going over the existing limit now that the ui-fulldeps tests have been moved to ui. --- src/tools/tidy/src/ui_tests.rs | 2 +- .../ui/{ => generics}/slightly-nice-generic-literal-messages.rs | 0 .../slightly-nice-generic-literal-messages.stderr | 0 tests/ui/{ => lexer}/unterminated-comment.rs | 0 tests/ui/{ => lexer}/unterminated-comment.stderr | 0 tests/ui/{ => lexer}/unterminated-nested-comment.rs | 0 tests/ui/{ => lexer}/unterminated-nested-comment.stderr | 0 tests/ui/{ => privacy}/auxiliary/xc-private-method-lib.rs | 0 tests/ui/{ => privacy}/xc-private-method.rs | 0 tests/ui/{ => privacy}/xc-private-method.stderr | 0 tests/ui/{ => privacy}/xc-private-method2.rs | 0 tests/ui/{ => privacy}/xc-private-method2.stderr | 0 tests/ui/{ => reachable}/reachable-unnameable-type-alias.rs | 0 tests/ui/{ => resolve}/disambiguate-identical-names.rs | 0 tests/ui/{ => resolve}/disambiguate-identical-names.stderr | 0 tests/ui/{ => thread-local}/thread-local-mutation.rs | 0 tests/ui/{ => thread-local}/thread-local-mutation.stderr | 0 tests/ui/{ => thread-local}/thread-local-static.rs | 0 tests/ui/{ => thread-local}/thread-local-static.stderr | 0 tests/ui/{ => traits}/wrong-mul-method-signature.rs | 0 tests/ui/{ => traits}/wrong-mul-method-signature.stderr | 0 tests/ui/{ => tuple}/tuple-index.rs | 0 tests/ui/{ => typeck}/output-type-mismatch.rs | 0 tests/ui/{ => typeck}/output-type-mismatch.stderr | 0 tests/ui/{ => typeck}/suppressed-error.rs | 0 tests/ui/{ => typeck}/suppressed-error.stderr | 0 tests/ui/{ => typeck}/tag-that-dare-not-speak-its-name.rs | 0 tests/ui/{ => typeck}/tag-that-dare-not-speak-its-name.stderr | 0 tests/ui/{ => typeck}/terr-in-field.rs | 0 tests/ui/{ => typeck}/terr-in-field.stderr | 0 tests/ui/{ => typeck}/terr-sorts.rs | 0 tests/ui/{ => typeck}/terr-sorts.stderr | 0 tests/ui/{ => typeck}/while-type-error.rs | 0 tests/ui/{ => typeck}/while-type-error.stderr | 0 tests/ui/{ => typeck}/wrong-ret-type.rs | 0 tests/ui/{ => typeck}/wrong-ret-type.stderr | 0 tests/ui/{ => ufcs}/ufcs-polymorphic-paths.rs | 0 tests/ui/{ => unique}/expr-block-generic-unique1.rs | 0 tests/ui/{ => unique}/expr-block-generic-unique2.rs | 0 tests/ui/{ => unique}/expr-if-unique.rs | 0 tests/ui/{ => unique}/unique-object-noncopyable.rs | 0 tests/ui/{ => unique}/unique-object-noncopyable.stderr | 0 tests/ui/{ => unique}/unique-pinned-nocopy.rs | 0 tests/ui/{ => unique}/unique-pinned-nocopy.stderr | 0 tests/ui/{ => unique}/unwind-unique.rs | 0 tests/ui/{ => unpretty}/mir-unpretty.rs | 0 tests/ui/{ => unpretty}/mir-unpretty.stderr | 0 tests/ui/{ => unpretty}/unpretty-expr-fn-arg.rs | 0 tests/ui/{ => unpretty}/unpretty-expr-fn-arg.stdout | 0 tests/ui/{ => unsafe}/foreign-unsafe-fn-called.mir.stderr | 0 tests/ui/{ => unsafe}/foreign-unsafe-fn-called.rs | 0 tests/ui/{ => unsafe}/foreign-unsafe-fn-called.thir.stderr | 0 tests/ui/{ => unsafe}/new-unsafe-pointers.rs | 0 tests/ui/{ => unsafe}/unsafe-fn-called-from-unsafe-blk.rs | 0 tests/ui/{ => unsafe}/unsafe-fn-called-from-unsafe-fn.rs | 0 tests/ui/{ => unsafe}/unsafe-pointer-assignability.rs | 0 .../{ => variance}/variance-intersection-of-ref-and-opt-ref.rs | 0 tests/ui/{ => variance}/variance-iterators-in-libcore.rs | 0 tests/ui/{ => wasm}/wasm-custom-section-relocations.rs | 0 tests/ui/{ => wasm}/wasm-custom-section-relocations.stderr | 0 60 files changed, 1 insertion(+), 1 deletion(-) rename tests/ui/{ => generics}/slightly-nice-generic-literal-messages.rs (100%) rename tests/ui/{ => generics}/slightly-nice-generic-literal-messages.stderr (100%) rename tests/ui/{ => lexer}/unterminated-comment.rs (100%) rename tests/ui/{ => lexer}/unterminated-comment.stderr (100%) rename tests/ui/{ => lexer}/unterminated-nested-comment.rs (100%) rename tests/ui/{ => lexer}/unterminated-nested-comment.stderr (100%) rename tests/ui/{ => privacy}/auxiliary/xc-private-method-lib.rs (100%) rename tests/ui/{ => privacy}/xc-private-method.rs (100%) rename tests/ui/{ => privacy}/xc-private-method.stderr (100%) rename tests/ui/{ => privacy}/xc-private-method2.rs (100%) rename tests/ui/{ => privacy}/xc-private-method2.stderr (100%) rename tests/ui/{ => reachable}/reachable-unnameable-type-alias.rs (100%) rename tests/ui/{ => resolve}/disambiguate-identical-names.rs (100%) rename tests/ui/{ => resolve}/disambiguate-identical-names.stderr (100%) rename tests/ui/{ => thread-local}/thread-local-mutation.rs (100%) rename tests/ui/{ => thread-local}/thread-local-mutation.stderr (100%) rename tests/ui/{ => thread-local}/thread-local-static.rs (100%) rename tests/ui/{ => thread-local}/thread-local-static.stderr (100%) rename tests/ui/{ => traits}/wrong-mul-method-signature.rs (100%) rename tests/ui/{ => traits}/wrong-mul-method-signature.stderr (100%) rename tests/ui/{ => tuple}/tuple-index.rs (100%) rename tests/ui/{ => typeck}/output-type-mismatch.rs (100%) rename tests/ui/{ => typeck}/output-type-mismatch.stderr (100%) rename tests/ui/{ => typeck}/suppressed-error.rs (100%) rename tests/ui/{ => typeck}/suppressed-error.stderr (100%) rename tests/ui/{ => typeck}/tag-that-dare-not-speak-its-name.rs (100%) rename tests/ui/{ => typeck}/tag-that-dare-not-speak-its-name.stderr (100%) rename tests/ui/{ => typeck}/terr-in-field.rs (100%) rename tests/ui/{ => typeck}/terr-in-field.stderr (100%) rename tests/ui/{ => typeck}/terr-sorts.rs (100%) rename tests/ui/{ => typeck}/terr-sorts.stderr (100%) rename tests/ui/{ => typeck}/while-type-error.rs (100%) rename tests/ui/{ => typeck}/while-type-error.stderr (100%) rename tests/ui/{ => typeck}/wrong-ret-type.rs (100%) rename tests/ui/{ => typeck}/wrong-ret-type.stderr (100%) rename tests/ui/{ => ufcs}/ufcs-polymorphic-paths.rs (100%) rename tests/ui/{ => unique}/expr-block-generic-unique1.rs (100%) rename tests/ui/{ => unique}/expr-block-generic-unique2.rs (100%) rename tests/ui/{ => unique}/expr-if-unique.rs (100%) rename tests/ui/{ => unique}/unique-object-noncopyable.rs (100%) rename tests/ui/{ => unique}/unique-object-noncopyable.stderr (100%) rename tests/ui/{ => unique}/unique-pinned-nocopy.rs (100%) rename tests/ui/{ => unique}/unique-pinned-nocopy.stderr (100%) rename tests/ui/{ => unique}/unwind-unique.rs (100%) rename tests/ui/{ => unpretty}/mir-unpretty.rs (100%) rename tests/ui/{ => unpretty}/mir-unpretty.stderr (100%) rename tests/ui/{ => unpretty}/unpretty-expr-fn-arg.rs (100%) rename tests/ui/{ => unpretty}/unpretty-expr-fn-arg.stdout (100%) rename tests/ui/{ => unsafe}/foreign-unsafe-fn-called.mir.stderr (100%) rename tests/ui/{ => unsafe}/foreign-unsafe-fn-called.rs (100%) rename tests/ui/{ => unsafe}/foreign-unsafe-fn-called.thir.stderr (100%) rename tests/ui/{ => unsafe}/new-unsafe-pointers.rs (100%) rename tests/ui/{ => unsafe}/unsafe-fn-called-from-unsafe-blk.rs (100%) rename tests/ui/{ => unsafe}/unsafe-fn-called-from-unsafe-fn.rs (100%) rename tests/ui/{ => unsafe}/unsafe-pointer-assignability.rs (100%) rename tests/ui/{ => variance}/variance-intersection-of-ref-and-opt-ref.rs (100%) rename tests/ui/{ => variance}/variance-iterators-in-libcore.rs (100%) rename tests/ui/{ => wasm}/wasm-custom-section-relocations.rs (100%) rename tests/ui/{ => wasm}/wasm-custom-section-relocations.stderr (100%) diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 20b8a2c3b24..f582666ab28 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -9,7 +9,7 @@ use std::path::{Path, PathBuf}; const ENTRY_LIMIT: usize = 1000; // FIXME: The following limits should be reduced eventually. -const ROOT_ENTRY_LIMIT: usize = 940; +const ROOT_ENTRY_LIMIT: usize = 881; const ISSUES_ENTRY_LIMIT: usize = 1978; fn check_entries(tests_path: &Path, bad: &mut bool) { diff --git a/tests/ui/slightly-nice-generic-literal-messages.rs b/tests/ui/generics/slightly-nice-generic-literal-messages.rs similarity index 100% rename from tests/ui/slightly-nice-generic-literal-messages.rs rename to tests/ui/generics/slightly-nice-generic-literal-messages.rs diff --git a/tests/ui/slightly-nice-generic-literal-messages.stderr b/tests/ui/generics/slightly-nice-generic-literal-messages.stderr similarity index 100% rename from tests/ui/slightly-nice-generic-literal-messages.stderr rename to tests/ui/generics/slightly-nice-generic-literal-messages.stderr diff --git a/tests/ui/unterminated-comment.rs b/tests/ui/lexer/unterminated-comment.rs similarity index 100% rename from tests/ui/unterminated-comment.rs rename to tests/ui/lexer/unterminated-comment.rs diff --git a/tests/ui/unterminated-comment.stderr b/tests/ui/lexer/unterminated-comment.stderr similarity index 100% rename from tests/ui/unterminated-comment.stderr rename to tests/ui/lexer/unterminated-comment.stderr diff --git a/tests/ui/unterminated-nested-comment.rs b/tests/ui/lexer/unterminated-nested-comment.rs similarity index 100% rename from tests/ui/unterminated-nested-comment.rs rename to tests/ui/lexer/unterminated-nested-comment.rs diff --git a/tests/ui/unterminated-nested-comment.stderr b/tests/ui/lexer/unterminated-nested-comment.stderr similarity index 100% rename from tests/ui/unterminated-nested-comment.stderr rename to tests/ui/lexer/unterminated-nested-comment.stderr diff --git a/tests/ui/auxiliary/xc-private-method-lib.rs b/tests/ui/privacy/auxiliary/xc-private-method-lib.rs similarity index 100% rename from tests/ui/auxiliary/xc-private-method-lib.rs rename to tests/ui/privacy/auxiliary/xc-private-method-lib.rs diff --git a/tests/ui/xc-private-method.rs b/tests/ui/privacy/xc-private-method.rs similarity index 100% rename from tests/ui/xc-private-method.rs rename to tests/ui/privacy/xc-private-method.rs diff --git a/tests/ui/xc-private-method.stderr b/tests/ui/privacy/xc-private-method.stderr similarity index 100% rename from tests/ui/xc-private-method.stderr rename to tests/ui/privacy/xc-private-method.stderr diff --git a/tests/ui/xc-private-method2.rs b/tests/ui/privacy/xc-private-method2.rs similarity index 100% rename from tests/ui/xc-private-method2.rs rename to tests/ui/privacy/xc-private-method2.rs diff --git a/tests/ui/xc-private-method2.stderr b/tests/ui/privacy/xc-private-method2.stderr similarity index 100% rename from tests/ui/xc-private-method2.stderr rename to tests/ui/privacy/xc-private-method2.stderr diff --git a/tests/ui/reachable-unnameable-type-alias.rs b/tests/ui/reachable/reachable-unnameable-type-alias.rs similarity index 100% rename from tests/ui/reachable-unnameable-type-alias.rs rename to tests/ui/reachable/reachable-unnameable-type-alias.rs diff --git a/tests/ui/disambiguate-identical-names.rs b/tests/ui/resolve/disambiguate-identical-names.rs similarity index 100% rename from tests/ui/disambiguate-identical-names.rs rename to tests/ui/resolve/disambiguate-identical-names.rs diff --git a/tests/ui/disambiguate-identical-names.stderr b/tests/ui/resolve/disambiguate-identical-names.stderr similarity index 100% rename from tests/ui/disambiguate-identical-names.stderr rename to tests/ui/resolve/disambiguate-identical-names.stderr diff --git a/tests/ui/thread-local-mutation.rs b/tests/ui/thread-local/thread-local-mutation.rs similarity index 100% rename from tests/ui/thread-local-mutation.rs rename to tests/ui/thread-local/thread-local-mutation.rs diff --git a/tests/ui/thread-local-mutation.stderr b/tests/ui/thread-local/thread-local-mutation.stderr similarity index 100% rename from tests/ui/thread-local-mutation.stderr rename to tests/ui/thread-local/thread-local-mutation.stderr diff --git a/tests/ui/thread-local-static.rs b/tests/ui/thread-local/thread-local-static.rs similarity index 100% rename from tests/ui/thread-local-static.rs rename to tests/ui/thread-local/thread-local-static.rs diff --git a/tests/ui/thread-local-static.stderr b/tests/ui/thread-local/thread-local-static.stderr similarity index 100% rename from tests/ui/thread-local-static.stderr rename to tests/ui/thread-local/thread-local-static.stderr diff --git a/tests/ui/wrong-mul-method-signature.rs b/tests/ui/traits/wrong-mul-method-signature.rs similarity index 100% rename from tests/ui/wrong-mul-method-signature.rs rename to tests/ui/traits/wrong-mul-method-signature.rs diff --git a/tests/ui/wrong-mul-method-signature.stderr b/tests/ui/traits/wrong-mul-method-signature.stderr similarity index 100% rename from tests/ui/wrong-mul-method-signature.stderr rename to tests/ui/traits/wrong-mul-method-signature.stderr diff --git a/tests/ui/tuple-index.rs b/tests/ui/tuple/tuple-index.rs similarity index 100% rename from tests/ui/tuple-index.rs rename to tests/ui/tuple/tuple-index.rs diff --git a/tests/ui/output-type-mismatch.rs b/tests/ui/typeck/output-type-mismatch.rs similarity index 100% rename from tests/ui/output-type-mismatch.rs rename to tests/ui/typeck/output-type-mismatch.rs diff --git a/tests/ui/output-type-mismatch.stderr b/tests/ui/typeck/output-type-mismatch.stderr similarity index 100% rename from tests/ui/output-type-mismatch.stderr rename to tests/ui/typeck/output-type-mismatch.stderr diff --git a/tests/ui/suppressed-error.rs b/tests/ui/typeck/suppressed-error.rs similarity index 100% rename from tests/ui/suppressed-error.rs rename to tests/ui/typeck/suppressed-error.rs diff --git a/tests/ui/suppressed-error.stderr b/tests/ui/typeck/suppressed-error.stderr similarity index 100% rename from tests/ui/suppressed-error.stderr rename to tests/ui/typeck/suppressed-error.stderr diff --git a/tests/ui/tag-that-dare-not-speak-its-name.rs b/tests/ui/typeck/tag-that-dare-not-speak-its-name.rs similarity index 100% rename from tests/ui/tag-that-dare-not-speak-its-name.rs rename to tests/ui/typeck/tag-that-dare-not-speak-its-name.rs diff --git a/tests/ui/tag-that-dare-not-speak-its-name.stderr b/tests/ui/typeck/tag-that-dare-not-speak-its-name.stderr similarity index 100% rename from tests/ui/tag-that-dare-not-speak-its-name.stderr rename to tests/ui/typeck/tag-that-dare-not-speak-its-name.stderr diff --git a/tests/ui/terr-in-field.rs b/tests/ui/typeck/terr-in-field.rs similarity index 100% rename from tests/ui/terr-in-field.rs rename to tests/ui/typeck/terr-in-field.rs diff --git a/tests/ui/terr-in-field.stderr b/tests/ui/typeck/terr-in-field.stderr similarity index 100% rename from tests/ui/terr-in-field.stderr rename to tests/ui/typeck/terr-in-field.stderr diff --git a/tests/ui/terr-sorts.rs b/tests/ui/typeck/terr-sorts.rs similarity index 100% rename from tests/ui/terr-sorts.rs rename to tests/ui/typeck/terr-sorts.rs diff --git a/tests/ui/terr-sorts.stderr b/tests/ui/typeck/terr-sorts.stderr similarity index 100% rename from tests/ui/terr-sorts.stderr rename to tests/ui/typeck/terr-sorts.stderr diff --git a/tests/ui/while-type-error.rs b/tests/ui/typeck/while-type-error.rs similarity index 100% rename from tests/ui/while-type-error.rs rename to tests/ui/typeck/while-type-error.rs diff --git a/tests/ui/while-type-error.stderr b/tests/ui/typeck/while-type-error.stderr similarity index 100% rename from tests/ui/while-type-error.stderr rename to tests/ui/typeck/while-type-error.stderr diff --git a/tests/ui/wrong-ret-type.rs b/tests/ui/typeck/wrong-ret-type.rs similarity index 100% rename from tests/ui/wrong-ret-type.rs rename to tests/ui/typeck/wrong-ret-type.rs diff --git a/tests/ui/wrong-ret-type.stderr b/tests/ui/typeck/wrong-ret-type.stderr similarity index 100% rename from tests/ui/wrong-ret-type.stderr rename to tests/ui/typeck/wrong-ret-type.stderr diff --git a/tests/ui/ufcs-polymorphic-paths.rs b/tests/ui/ufcs/ufcs-polymorphic-paths.rs similarity index 100% rename from tests/ui/ufcs-polymorphic-paths.rs rename to tests/ui/ufcs/ufcs-polymorphic-paths.rs diff --git a/tests/ui/expr-block-generic-unique1.rs b/tests/ui/unique/expr-block-generic-unique1.rs similarity index 100% rename from tests/ui/expr-block-generic-unique1.rs rename to tests/ui/unique/expr-block-generic-unique1.rs diff --git a/tests/ui/expr-block-generic-unique2.rs b/tests/ui/unique/expr-block-generic-unique2.rs similarity index 100% rename from tests/ui/expr-block-generic-unique2.rs rename to tests/ui/unique/expr-block-generic-unique2.rs diff --git a/tests/ui/expr-if-unique.rs b/tests/ui/unique/expr-if-unique.rs similarity index 100% rename from tests/ui/expr-if-unique.rs rename to tests/ui/unique/expr-if-unique.rs diff --git a/tests/ui/unique-object-noncopyable.rs b/tests/ui/unique/unique-object-noncopyable.rs similarity index 100% rename from tests/ui/unique-object-noncopyable.rs rename to tests/ui/unique/unique-object-noncopyable.rs diff --git a/tests/ui/unique-object-noncopyable.stderr b/tests/ui/unique/unique-object-noncopyable.stderr similarity index 100% rename from tests/ui/unique-object-noncopyable.stderr rename to tests/ui/unique/unique-object-noncopyable.stderr diff --git a/tests/ui/unique-pinned-nocopy.rs b/tests/ui/unique/unique-pinned-nocopy.rs similarity index 100% rename from tests/ui/unique-pinned-nocopy.rs rename to tests/ui/unique/unique-pinned-nocopy.rs diff --git a/tests/ui/unique-pinned-nocopy.stderr b/tests/ui/unique/unique-pinned-nocopy.stderr similarity index 100% rename from tests/ui/unique-pinned-nocopy.stderr rename to tests/ui/unique/unique-pinned-nocopy.stderr diff --git a/tests/ui/unwind-unique.rs b/tests/ui/unique/unwind-unique.rs similarity index 100% rename from tests/ui/unwind-unique.rs rename to tests/ui/unique/unwind-unique.rs diff --git a/tests/ui/mir-unpretty.rs b/tests/ui/unpretty/mir-unpretty.rs similarity index 100% rename from tests/ui/mir-unpretty.rs rename to tests/ui/unpretty/mir-unpretty.rs diff --git a/tests/ui/mir-unpretty.stderr b/tests/ui/unpretty/mir-unpretty.stderr similarity index 100% rename from tests/ui/mir-unpretty.stderr rename to tests/ui/unpretty/mir-unpretty.stderr diff --git a/tests/ui/unpretty-expr-fn-arg.rs b/tests/ui/unpretty/unpretty-expr-fn-arg.rs similarity index 100% rename from tests/ui/unpretty-expr-fn-arg.rs rename to tests/ui/unpretty/unpretty-expr-fn-arg.rs diff --git a/tests/ui/unpretty-expr-fn-arg.stdout b/tests/ui/unpretty/unpretty-expr-fn-arg.stdout similarity index 100% rename from tests/ui/unpretty-expr-fn-arg.stdout rename to tests/ui/unpretty/unpretty-expr-fn-arg.stdout diff --git a/tests/ui/foreign-unsafe-fn-called.mir.stderr b/tests/ui/unsafe/foreign-unsafe-fn-called.mir.stderr similarity index 100% rename from tests/ui/foreign-unsafe-fn-called.mir.stderr rename to tests/ui/unsafe/foreign-unsafe-fn-called.mir.stderr diff --git a/tests/ui/foreign-unsafe-fn-called.rs b/tests/ui/unsafe/foreign-unsafe-fn-called.rs similarity index 100% rename from tests/ui/foreign-unsafe-fn-called.rs rename to tests/ui/unsafe/foreign-unsafe-fn-called.rs diff --git a/tests/ui/foreign-unsafe-fn-called.thir.stderr b/tests/ui/unsafe/foreign-unsafe-fn-called.thir.stderr similarity index 100% rename from tests/ui/foreign-unsafe-fn-called.thir.stderr rename to tests/ui/unsafe/foreign-unsafe-fn-called.thir.stderr diff --git a/tests/ui/new-unsafe-pointers.rs b/tests/ui/unsafe/new-unsafe-pointers.rs similarity index 100% rename from tests/ui/new-unsafe-pointers.rs rename to tests/ui/unsafe/new-unsafe-pointers.rs diff --git a/tests/ui/unsafe-fn-called-from-unsafe-blk.rs b/tests/ui/unsafe/unsafe-fn-called-from-unsafe-blk.rs similarity index 100% rename from tests/ui/unsafe-fn-called-from-unsafe-blk.rs rename to tests/ui/unsafe/unsafe-fn-called-from-unsafe-blk.rs diff --git a/tests/ui/unsafe-fn-called-from-unsafe-fn.rs b/tests/ui/unsafe/unsafe-fn-called-from-unsafe-fn.rs similarity index 100% rename from tests/ui/unsafe-fn-called-from-unsafe-fn.rs rename to tests/ui/unsafe/unsafe-fn-called-from-unsafe-fn.rs diff --git a/tests/ui/unsafe-pointer-assignability.rs b/tests/ui/unsafe/unsafe-pointer-assignability.rs similarity index 100% rename from tests/ui/unsafe-pointer-assignability.rs rename to tests/ui/unsafe/unsafe-pointer-assignability.rs diff --git a/tests/ui/variance-intersection-of-ref-and-opt-ref.rs b/tests/ui/variance/variance-intersection-of-ref-and-opt-ref.rs similarity index 100% rename from tests/ui/variance-intersection-of-ref-and-opt-ref.rs rename to tests/ui/variance/variance-intersection-of-ref-and-opt-ref.rs diff --git a/tests/ui/variance-iterators-in-libcore.rs b/tests/ui/variance/variance-iterators-in-libcore.rs similarity index 100% rename from tests/ui/variance-iterators-in-libcore.rs rename to tests/ui/variance/variance-iterators-in-libcore.rs diff --git a/tests/ui/wasm-custom-section-relocations.rs b/tests/ui/wasm/wasm-custom-section-relocations.rs similarity index 100% rename from tests/ui/wasm-custom-section-relocations.rs rename to tests/ui/wasm/wasm-custom-section-relocations.rs diff --git a/tests/ui/wasm-custom-section-relocations.stderr b/tests/ui/wasm/wasm-custom-section-relocations.stderr similarity index 100% rename from tests/ui/wasm-custom-section-relocations.stderr rename to tests/ui/wasm/wasm-custom-section-relocations.stderr From a2ee7592d6b7c0daa62b7870ade85e0cc0acca05 Mon Sep 17 00:00:00 2001 From: Scott McMurray <scottmcm@users.noreply.github.com> Date: Fri, 31 Mar 2023 00:32:44 -0700 Subject: [PATCH 334/346] Use `&IndexSlice` instead of `&IndexVec` where possible All the same reasons as for `[T]`: more general, less pointer chasing, and `&mut IndexSlice` emphasizes that it doesn't change *length*. --- compiler/rustc_abi/src/layout.rs | 4 +- compiler/rustc_abi/src/lib.rs | 2 +- compiler/rustc_ast_lowering/src/item.rs | 4 +- compiler/rustc_ast_lowering/src/lib.rs | 4 +- .../rustc_borrowck/src/constraints/mod.rs | 6 ++- compiler/rustc_borrowck/src/consumers.rs | 4 +- .../src/diagnostics/explain_borrow.rs | 4 +- .../src/diagnostics/var_name.rs | 6 +-- compiler/rustc_borrowck/src/lib.rs | 8 ++-- .../rustc_borrowck/src/member_constraints.rs | 4 +- compiler/rustc_borrowck/src/nll.rs | 6 +-- .../rustc_borrowck/src/region_infer/mod.rs | 6 +-- compiler/rustc_borrowck/src/renumber.rs | 4 +- compiler/rustc_borrowck/src/type_check/mod.rs | 6 +-- .../src/debuginfo/metadata/enums/mod.rs | 4 +- .../rustc_codegen_ssa/src/coverageinfo/map.rs | 4 +- compiler/rustc_codegen_ssa/src/mir/analyze.rs | 9 ++-- .../src/transform/promote_consts.rs | 6 +-- .../src/graph/dominators/mod.rs | 14 +++---- .../src/graph/iterate/mod.rs | 4 +- .../src/graph/scc/mod.rs | 6 +-- compiler/rustc_index/src/vec.rs | 42 ++++++++++++++++++- .../src/infer/lexical_region_resolve/mod.rs | 6 +-- compiler/rustc_middle/src/mir/basic_blocks.rs | 6 +-- compiler/rustc_middle/src/mir/mod.rs | 19 ++++++--- compiler/rustc_middle/src/mir/tcx.rs | 10 ++--- compiler/rustc_middle/src/mir/traversal.rs | 4 +- compiler/rustc_middle/src/ty/adt.rs | 4 +- .../rustc_mir_build/src/build/custom/mod.rs | 6 +-- .../rustc_mir_build/src/build/custom/parse.rs | 4 +- compiler/rustc_mir_build/src/build/mod.rs | 4 +- compiler/rustc_mir_build/src/build/scope.rs | 4 +- .../rustc_mir_dataflow/src/move_paths/mod.rs | 8 ++-- .../rustc_mir_dataflow/src/value_analysis.rs | 10 ++--- .../src/check_alignment.rs | 2 +- .../rustc_mir_transform/src/const_prop.rs | 6 +-- .../src/const_prop_lint.rs | 8 ++-- compiler/rustc_mir_transform/src/copy_prop.rs | 4 +- .../rustc_mir_transform/src/coverage/graph.rs | 6 +-- .../src/lower_slice_len.rs | 4 +- compiler/rustc_mir_transform/src/simplify.rs | 10 ++--- compiler/rustc_mir_transform/src/ssa.rs | 4 +- 42 files changed, 168 insertions(+), 118 deletions(-) diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs index 343f27326ad..aea59ee6aea 100644 --- a/compiler/rustc_abi/src/layout.rs +++ b/compiler/rustc_abi/src/layout.rs @@ -289,7 +289,7 @@ pub trait LayoutCalculator { fn layout_of_struct_or_enum( &self, repr: &ReprOptions, - variants: &IndexVec<VariantIdx, Vec<Layout<'_>>>, + variants: &IndexSlice<VariantIdx, Vec<Layout<'_>>>, is_enum: bool, is_unsafe_cell: bool, scalar_valid_range: (Bound<u128>, Bound<u128>), @@ -883,7 +883,7 @@ pub trait LayoutCalculator { fn layout_of_union( &self, repr: &ReprOptions, - variants: &IndexVec<VariantIdx, Vec<Layout<'_>>>, + variants: &IndexSlice<VariantIdx, Vec<Layout<'_>>>, ) -> Option<LayoutS> { let dl = self.current_data_layout(); let dl = dl.borrow(); diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index 428191bc8b9..7b5732b488b 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -11,7 +11,7 @@ use bitflags::bitflags; use rustc_data_structures::intern::Interned; #[cfg(feature = "nightly")] use rustc_data_structures::stable_hasher::StableOrd; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexSlice, IndexVec}; #[cfg(feature = "nightly")] use rustc_macros::HashStable_Generic; #[cfg(feature = "nightly")] diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index cc879982abc..2efffbb6dc5 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -12,7 +12,7 @@ use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; use rustc_hir::PredicateOrigin; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexSlice, IndexVec}; use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::source_map::DesugaringKind; @@ -25,7 +25,7 @@ use thin_vec::ThinVec; pub(super) struct ItemLowerer<'a, 'hir> { pub(super) tcx: TyCtxt<'hir>, pub(super) resolver: &'a mut ResolverAstLowering, - pub(super) ast_index: &'a IndexVec<LocalDefId, AstOwner<'a>>, + pub(super) ast_index: &'a IndexSlice<LocalDefId, AstOwner<'a>>, pub(super) owners: &'a mut IndexVec<LocalDefId, hir::MaybeOwner<&'hir hir::OwnerInfo<'hir>>>, } diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index c5d39634c44..ca659db4dbe 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -60,7 +60,7 @@ use rustc_hir::def::{DefKind, LifetimeRes, Namespace, PartialRes, PerNS, Res}; use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID}; use rustc_hir::definitions::DefPathData; use rustc_hir::{ConstArg, GenericArg, ItemLocalId, ParamName, TraitCandidate}; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexSlice, IndexVec}; use rustc_macros::fluent_messages; use rustc_middle::{ span_bug, @@ -414,7 +414,7 @@ fn index_crate<'a>( /// This hash will then be part of the crate_hash which is stored in the metadata. fn compute_hir_hash( tcx: TyCtxt<'_>, - owners: &IndexVec<LocalDefId, hir::MaybeOwner<&hir::OwnerInfo<'_>>>, + owners: &IndexSlice<LocalDefId, hir::MaybeOwner<&hir::OwnerInfo<'_>>>, ) -> Fingerprint { let mut hir_body_nodes: Vec<_> = owners .iter_enumerated() diff --git a/compiler/rustc_borrowck/src/constraints/mod.rs b/compiler/rustc_borrowck/src/constraints/mod.rs index f370c02161b..d2d9779dbea 100644 --- a/compiler/rustc_borrowck/src/constraints/mod.rs +++ b/compiler/rustc_borrowck/src/constraints/mod.rs @@ -2,7 +2,7 @@ #![deny(rustc::diagnostic_outside_of_impl)] use rustc_data_structures::graph::scc::Sccs; -use rustc_index::vec::IndexVec; +use rustc_index::vec::{IndexSlice, IndexVec}; use rustc_middle::mir::ConstraintCategory; use rustc_middle::ty::{RegionVid, VarianceDiagInfo}; use rustc_span::Span; @@ -60,7 +60,9 @@ impl<'tcx> OutlivesConstraintSet<'tcx> { Sccs::new(region_graph) } - pub(crate) fn outlives(&self) -> &IndexVec<OutlivesConstraintIndex, OutlivesConstraint<'tcx>> { + pub(crate) fn outlives( + &self, + ) -> &IndexSlice<OutlivesConstraintIndex, OutlivesConstraint<'tcx>> { &self.outlives } } diff --git a/compiler/rustc_borrowck/src/consumers.rs b/compiler/rustc_borrowck/src/consumers.rs index 055b281bc2e..cb1a6522223 100644 --- a/compiler/rustc_borrowck/src/consumers.rs +++ b/compiler/rustc_borrowck/src/consumers.rs @@ -3,7 +3,7 @@ //! This file provides API for compiler consumers. use rustc_hir::def_id::LocalDefId; -use rustc_index::vec::IndexVec; +use rustc_index::vec::IndexSlice; use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt}; use rustc_middle::mir::Body; use rustc_middle::ty::{self, TyCtxt}; @@ -35,6 +35,6 @@ pub fn get_body_with_borrowck_facts( let (input_body, promoted) = tcx.mir_promoted(def); let infcx = tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(def.did)).build(); let input_body: &Body<'_> = &input_body.borrow(); - let promoted: &IndexVec<_, _> = &promoted.borrow(); + let promoted: &IndexSlice<_, _> = &promoted.borrow(); *super::do_mir_borrowck(&infcx, input_body, promoted, true).1.unwrap() } diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs index 62b3f3ecfc3..8860395e71c 100644 --- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs +++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs @@ -3,7 +3,7 @@ use rustc_errors::{Applicability, Diagnostic}; use rustc_hir as hir; use rustc_hir::intravisit::Visitor; -use rustc_index::vec::IndexVec; +use rustc_index::vec::IndexSlice; use rustc_infer::infer::NllRegionVariableOrigin; use rustc_middle::mir::{ Body, CastKind, ConstraintCategory, FakeReadCause, Local, LocalInfo, Location, Operand, Place, @@ -60,7 +60,7 @@ impl<'tcx> BorrowExplanation<'tcx> { &self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>, - local_names: &IndexVec<Local, Option<Symbol>>, + local_names: &IndexSlice<Local, Option<Symbol>>, err: &mut Diagnostic, borrow_desc: &str, borrow_span: Option<Span>, diff --git a/compiler/rustc_borrowck/src/diagnostics/var_name.rs b/compiler/rustc_borrowck/src/diagnostics/var_name.rs index ada3310d807..80b2787ce0c 100644 --- a/compiler/rustc_borrowck/src/diagnostics/var_name.rs +++ b/compiler/rustc_borrowck/src/diagnostics/var_name.rs @@ -3,7 +3,7 @@ use crate::Upvar; use crate::{nll::ToRegionVid, region_infer::RegionInferenceContext}; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexSlice}; use rustc_middle::mir::{Body, Local}; use rustc_middle::ty::{RegionVid, TyCtxt}; use rustc_span::source_map::Span; @@ -14,7 +14,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { &self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>, - local_names: &IndexVec<Local, Option<Symbol>>, + local_names: &IndexSlice<Local, Option<Symbol>>, upvars: &[Upvar<'tcx>], fr: RegionVid, ) -> Option<(Option<Symbol>, Span)> { @@ -113,7 +113,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { pub(crate) fn get_argument_name_and_span_for_region( &self, body: &Body<'tcx>, - local_names: &IndexVec<Local, Option<Symbol>>, + local_names: &IndexSlice<Local, Option<Symbol>>, argument_index: usize, ) -> (Option<Symbol>, Span) { let implicit_inputs = self.universal_regions().defining_ty.implicit_inputs(); diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index ba322425089..1d4d1406239 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -23,7 +23,7 @@ use rustc_errors::{Diagnostic, DiagnosticBuilder, DiagnosticMessage, Subdiagnost use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; use rustc_index::bit_set::ChunkedBitSet; -use rustc_index::vec::IndexVec; +use rustc_index::vec::{IndexSlice, IndexVec}; use rustc_infer::infer::{ DefiningAnchor, InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin, TyCtxtInferExt, }; @@ -154,7 +154,7 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> &Bor let infcx = tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id)).build(); let input_body: &Body<'_> = &input_body.borrow(); - let promoted: &IndexVec<_, _> = &promoted.borrow(); + let promoted: &IndexSlice<_, _> = &promoted.borrow(); let opt_closure_req = do_mir_borrowck(&infcx, input_body, promoted, false).0; debug!("mir_borrowck done"); @@ -170,7 +170,7 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: ty::WithOptConstParam<LocalDefId>) -> &Bor fn do_mir_borrowck<'tcx>( infcx: &InferCtxt<'tcx>, input_body: &Body<'tcx>, - input_promoted: &IndexVec<Promoted, Body<'tcx>>, + input_promoted: &IndexSlice<Promoted, Body<'tcx>>, return_body_with_facts: bool, ) -> (BorrowCheckResult<'tcx>, Option<Box<BodyWithBorrowckFacts<'tcx>>>) { let def = input_body.source.with_opt_param().as_local().unwrap(); @@ -223,7 +223,7 @@ fn do_mir_borrowck<'tcx>( // be modified (in place) to contain non-lexical lifetimes. It // will have a lifetime tied to the inference context. let mut body_owned = input_body.clone(); - let mut promoted = input_promoted.clone(); + let mut promoted = input_promoted.to_owned(); let free_regions = nll::replace_regions_in_mir(&infcx, param_env, &mut body_owned, &mut promoted); let body = &body_owned; // no further changes diff --git a/compiler/rustc_borrowck/src/member_constraints.rs b/compiler/rustc_borrowck/src/member_constraints.rs index b6c5d4245d7..f637e6a95ac 100644 --- a/compiler/rustc_borrowck/src/member_constraints.rs +++ b/compiler/rustc_borrowck/src/member_constraints.rs @@ -2,7 +2,7 @@ #![deny(rustc::diagnostic_outside_of_impl)] use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxIndexMap; -use rustc_index::vec::IndexVec; +use rustc_index::vec::{IndexSlice, IndexVec}; use rustc_middle::infer::MemberConstraint; use rustc_middle::ty::{self, Ty}; use rustc_span::Span; @@ -215,7 +215,7 @@ where /// target_list: A -> B -> C -> D -> E -> F -> (None) /// ``` fn append_list( - constraints: &mut IndexVec<NllMemberConstraintIndex, NllMemberConstraint<'_>>, + constraints: &mut IndexSlice<NllMemberConstraintIndex, NllMemberConstraint<'_>>, target_list: NllMemberConstraintIndex, source_list: NllMemberConstraintIndex, ) { diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index f0068fc9226..06ecbdb1707 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -4,7 +4,7 @@ use rustc_data_structures::fx::FxIndexMap; use rustc_hir::def_id::LocalDefId; -use rustc_index::vec::IndexVec; +use rustc_index::vec::IndexSlice; use rustc_middle::mir::{create_dump_file, dump_enabled, dump_mir, PassWhere}; use rustc_middle::mir::{ BasicBlock, Body, ClosureOutlivesSubject, ClosureRegionRequirements, LocalKind, Location, @@ -59,7 +59,7 @@ pub(crate) fn replace_regions_in_mir<'tcx>( infcx: &BorrowckInferCtxt<'_, 'tcx>, param_env: ty::ParamEnv<'tcx>, body: &mut Body<'tcx>, - promoted: &mut IndexVec<Promoted, Body<'tcx>>, + promoted: &mut IndexSlice<Promoted, Body<'tcx>>, ) -> UniversalRegions<'tcx> { let def = body.source.with_opt_param().as_local().unwrap(); @@ -158,7 +158,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>( infcx: &BorrowckInferCtxt<'_, 'tcx>, universal_regions: UniversalRegions<'tcx>, body: &Body<'tcx>, - promoted: &IndexVec<Promoted, Body<'tcx>>, + promoted: &IndexSlice<Promoted, Body<'tcx>>, location_table: &LocationTable, param_env: ty::ParamEnv<'tcx>, flow_inits: &mut ResultsCursor<'cx, 'tcx, MaybeInitializedPlaces<'cx, 'tcx>>, diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 03f175daca9..f67af4584a4 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -7,7 +7,7 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::graph::scc::Sccs; use rustc_errors::Diagnostic; use rustc_hir::def_id::CRATE_DEF_ID; -use rustc_index::vec::IndexVec; +use rustc_index::vec::{IndexSlice, IndexVec}; use rustc_infer::infer::outlives::test_type_match; use rustc_infer::infer::region_constraints::{GenericKind, VarInfos, VerifyBound, VerifyIfEq}; use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin}; @@ -399,7 +399,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// the minimum, or narrowest, universe. fn compute_scc_universes( constraint_sccs: &Sccs<RegionVid, ConstraintSccIndex>, - definitions: &IndexVec<RegionVid, RegionDefinition<'tcx>>, + definitions: &IndexSlice<RegionVid, RegionDefinition<'tcx>>, ) -> IndexVec<ConstraintSccIndex, ty::UniverseIndex> { let num_sccs = constraint_sccs.num_sccs(); let mut scc_universes = IndexVec::from_elem_n(ty::UniverseIndex::MAX, num_sccs); @@ -486,7 +486,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// more details. fn compute_scc_representatives( constraints_scc: &Sccs<RegionVid, ConstraintSccIndex>, - definitions: &IndexVec<RegionVid, RegionDefinition<'tcx>>, + definitions: &IndexSlice<RegionVid, RegionDefinition<'tcx>>, ) -> IndexVec<ConstraintSccIndex, ty::RegionVid> { let num_sccs = constraints_scc.num_sccs(); let next_region_vid = definitions.next_index(); diff --git a/compiler/rustc_borrowck/src/renumber.rs b/compiler/rustc_borrowck/src/renumber.rs index 016f6f78dfa..0fbf01dbe44 100644 --- a/compiler/rustc_borrowck/src/renumber.rs +++ b/compiler/rustc_borrowck/src/renumber.rs @@ -1,7 +1,7 @@ #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] use crate::BorrowckInferCtxt; -use rustc_index::vec::IndexVec; +use rustc_index::vec::IndexSlice; use rustc_infer::infer::NllRegionVariableOrigin; use rustc_middle::mir::visit::{MutVisitor, TyContext}; use rustc_middle::mir::Constant; @@ -16,7 +16,7 @@ use rustc_span::{Span, Symbol}; pub fn renumber_mir<'tcx>( infcx: &BorrowckInferCtxt<'_, 'tcx>, body: &mut Body<'tcx>, - promoted: &mut IndexVec<Promoted, Body<'tcx>>, + promoted: &mut IndexSlice<Promoted, Body<'tcx>>, ) { debug!(?body.arg_count); diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index f3fe5a6cada..2fc4e32ecb2 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -125,7 +125,7 @@ pub(crate) fn type_check<'mir, 'tcx>( infcx: &BorrowckInferCtxt<'_, 'tcx>, param_env: ty::ParamEnv<'tcx>, body: &Body<'tcx>, - promoted: &IndexVec<Promoted, Body<'tcx>>, + promoted: &IndexSlice<Promoted, Body<'tcx>>, universal_regions: &Rc<UniversalRegions<'tcx>>, location_table: &LocationTable, borrow_set: &BorrowSet<'tcx>, @@ -292,7 +292,7 @@ enum FieldAccessError { /// is a problem. struct TypeVerifier<'a, 'b, 'tcx> { cx: &'a mut TypeChecker<'b, 'tcx>, - promoted: &'b IndexVec<Promoted, Body<'tcx>>, + promoted: &'b IndexSlice<Promoted, Body<'tcx>>, last_span: Span, errors_reported: bool, } @@ -493,7 +493,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> { impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { fn new( cx: &'a mut TypeChecker<'b, 'tcx>, - promoted: &'b IndexVec<Promoted, Body<'tcx>>, + promoted: &'b IndexSlice<Promoted, Body<'tcx>>, ) -> Self { TypeVerifier { promoted, last_span: cx.body.span, cx, errors_reported: false } } diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs index c3439591b92..55a217f59f9 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs @@ -3,7 +3,7 @@ use rustc_codegen_ssa::debuginfo::{ wants_c_like_enum_debuginfo, }; use rustc_hir::def::CtorKind; -use rustc_index::vec::IndexVec; +use rustc_index::vec::IndexSlice; use rustc_middle::{ bug, mir::{GeneratorLayout, GeneratorSavedLocal}, @@ -323,7 +323,7 @@ pub fn build_generator_variant_struct_type_di_node<'ll, 'tcx>( generator_type_and_layout: TyAndLayout<'tcx>, generator_type_di_node: &'ll DIType, generator_layout: &GeneratorLayout<'tcx>, - state_specific_upvar_names: &IndexVec<GeneratorSavedLocal, Option<Symbol>>, + state_specific_upvar_names: &IndexSlice<GeneratorSavedLocal, Option<Symbol>>, common_upvar_names: &[String], ) -> &'ll DIType { let variant_name = GeneratorSubsts::variant_name(variant_index); diff --git a/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs b/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs index 1a6495cb15c..1ea13040072 100644 --- a/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs +++ b/compiler/rustc_codegen_ssa/src/coverageinfo/map.rs @@ -1,6 +1,6 @@ pub use super::ffi::*; -use rustc_index::vec::IndexVec; +use rustc_index::vec::{IndexSlice, IndexVec}; use rustc_middle::mir::coverage::{ CodeRegion, CounterValueReference, ExpressionOperandId, InjectedExpressionId, InjectedExpressionIndex, MappedExpressionIndex, Op, @@ -205,7 +205,7 @@ impl<'tcx> FunctionCoverage<'tcx> { // `expression_index`s lower than the referencing `Expression`. Therefore, it is // reasonable to look up the new index of an expression operand while the `new_indexes` // vector is only complete up to the current `ExpressionIndex`. - let id_to_counter = |new_indexes: &IndexVec< + let id_to_counter = |new_indexes: &IndexSlice< InjectedExpressionIndex, Option<MappedExpressionIndex>, >, diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs index 0ce395e912d..dcf533dc39c 100644 --- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs +++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs @@ -5,7 +5,7 @@ use super::FunctionCx; use crate::traits::*; use rustc_data_structures::graph::dominators::Dominators; use rustc_index::bit_set::BitSet; -use rustc_index::vec::IndexVec; +use rustc_index::vec::{IndexSlice, IndexVec}; use rustc_middle::mir::traversal; use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::{self, Location, TerminatorKind}; @@ -277,7 +277,7 @@ impl CleanupKind { /// Recover that structure in an analyze pass. pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec<mir::BasicBlock, CleanupKind> { fn discover_masters<'tcx>( - result: &mut IndexVec<mir::BasicBlock, CleanupKind>, + result: &mut IndexSlice<mir::BasicBlock, CleanupKind>, mir: &mir::Body<'tcx>, ) { for (bb, data) in mir.basic_blocks.iter_enumerated() { @@ -308,7 +308,10 @@ pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec<mir::BasicBlock, CleanupKi } } - fn propagate<'tcx>(result: &mut IndexVec<mir::BasicBlock, CleanupKind>, mir: &mir::Body<'tcx>) { + fn propagate<'tcx>( + result: &mut IndexSlice<mir::BasicBlock, CleanupKind>, + mir: &mir::Body<'tcx>, + ) { let mut funclet_succs = IndexVec::from_elem(None, &mir.basic_blocks); let mut set_successor = |funclet: mir::BasicBlock, succ| match funclet_succs[funclet] { diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs index 40c848de2be..6774e5a5837 100644 --- a/compiler/rustc_const_eval/src/transform/promote_consts.rs +++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs @@ -21,7 +21,7 @@ use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::{self, List, TyCtxt, TypeVisitableExt}; use rustc_span::Span; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexSlice, IndexVec}; use std::cell::Cell; use std::{cmp, iter, mem}; @@ -184,7 +184,7 @@ pub fn collect_temps_and_candidates<'tcx>( /// This wraps an `Item`, and has access to all fields of that `Item` via `Deref` coercion. struct Validator<'a, 'tcx> { ccx: &'a ConstCx<'a, 'tcx>, - temps: &'a mut IndexVec<Local, TempState>, + temps: &'a mut IndexSlice<Local, TempState>, } impl<'a, 'tcx> std::ops::Deref for Validator<'a, 'tcx> { @@ -669,7 +669,7 @@ impl<'tcx> Validator<'_, 'tcx> { // FIXME(eddyb) remove the differences for promotability in `static`, `const`, `const fn`. pub fn validate_candidates( ccx: &ConstCx<'_, '_>, - temps: &mut IndexVec<Local, TempState>, + temps: &mut IndexSlice<Local, TempState>, candidates: &[Candidate], ) -> Vec<Candidate> { let mut validator = Validator { ccx, temps }; diff --git a/compiler/rustc_data_structures/src/graph/dominators/mod.rs b/compiler/rustc_data_structures/src/graph/dominators/mod.rs index 0a21a4249c8..0df9dc112ee 100644 --- a/compiler/rustc_data_structures/src/graph/dominators/mod.rs +++ b/compiler/rustc_data_structures/src/graph/dominators/mod.rs @@ -10,7 +10,7 @@ //! <https://www.cs.princeton.edu/courses/archive/spr03/cs423/download/dominators.pdf> use super::ControlFlowGraph; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexSlice, IndexVec}; use std::cmp::Ordering; #[cfg(test)] @@ -256,10 +256,10 @@ pub fn dominators<G: ControlFlowGraph>(graph: G) -> Dominators<G::Node> { /// where `+>` is a proper ancestor and `*>` is just an ancestor. #[inline] fn eval( - ancestor: &mut IndexVec<PreorderIndex, PreorderIndex>, + ancestor: &mut IndexSlice<PreorderIndex, PreorderIndex>, lastlinked: Option<PreorderIndex>, - semi: &IndexVec<PreorderIndex, PreorderIndex>, - label: &mut IndexVec<PreorderIndex, PreorderIndex>, + semi: &IndexSlice<PreorderIndex, PreorderIndex>, + label: &mut IndexSlice<PreorderIndex, PreorderIndex>, node: PreorderIndex, ) -> PreorderIndex { if is_processed(node, lastlinked) { @@ -277,10 +277,10 @@ fn is_processed(v: PreorderIndex, lastlinked: Option<PreorderIndex>) -> bool { #[inline] fn compress( - ancestor: &mut IndexVec<PreorderIndex, PreorderIndex>, + ancestor: &mut IndexSlice<PreorderIndex, PreorderIndex>, lastlinked: Option<PreorderIndex>, - semi: &IndexVec<PreorderIndex, PreorderIndex>, - label: &mut IndexVec<PreorderIndex, PreorderIndex>, + semi: &IndexSlice<PreorderIndex, PreorderIndex>, + label: &mut IndexSlice<PreorderIndex, PreorderIndex>, v: PreorderIndex, ) { assert!(is_processed(v, lastlinked)); diff --git a/compiler/rustc_data_structures/src/graph/iterate/mod.rs b/compiler/rustc_data_structures/src/graph/iterate/mod.rs index 8a9af300c06..01a83b40a75 100644 --- a/compiler/rustc_data_structures/src/graph/iterate/mod.rs +++ b/compiler/rustc_data_structures/src/graph/iterate/mod.rs @@ -1,6 +1,6 @@ use super::{DirectedGraph, WithNumNodes, WithStartNode, WithSuccessors}; use rustc_index::bit_set::BitSet; -use rustc_index::vec::IndexVec; +use rustc_index::vec::{IndexSlice, IndexVec}; use std::ops::ControlFlow; #[cfg(test)] @@ -31,7 +31,7 @@ fn post_order_walk<G: DirectedGraph + WithSuccessors + WithNumNodes>( graph: &G, node: G::Node, result: &mut Vec<G::Node>, - visited: &mut IndexVec<G::Node, bool>, + visited: &mut IndexSlice<G::Node, bool>, ) { struct PostOrderFrame<Node, Iter> { node: Node, diff --git a/compiler/rustc_data_structures/src/graph/scc/mod.rs b/compiler/rustc_data_structures/src/graph/scc/mod.rs index c4b11951ab7..28c357e54dd 100644 --- a/compiler/rustc_data_structures/src/graph/scc/mod.rs +++ b/compiler/rustc_data_structures/src/graph/scc/mod.rs @@ -8,7 +8,7 @@ use crate::fx::FxHashSet; use crate::graph::vec_graph::VecGraph; use crate::graph::{DirectedGraph, GraphSuccessors, WithNumEdges, WithNumNodes, WithSuccessors}; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexSlice, IndexVec}; use std::ops::Range; #[cfg(test)] @@ -43,7 +43,7 @@ impl<N: Idx, S: Idx + Ord> Sccs<N, S> { SccsConstruction::construct(graph) } - pub fn scc_indices(&self) -> &IndexVec<N, S> { + pub fn scc_indices(&self) -> &IndexSlice<N, S> { &self.scc_indices } @@ -123,7 +123,7 @@ impl<S: Idx> SccData<S> { self.ranges.len() } - pub fn ranges(&self) -> &IndexVec<S, Range<usize>> { + pub fn ranges(&self) -> &IndexSlice<S, Range<usize>> { &self.ranges } diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs index 6caae059f4a..5945de2302a 100644 --- a/compiler/rustc_index/src/vec.rs +++ b/compiler/rustc_index/src/vec.rs @@ -1,6 +1,7 @@ #[cfg(feature = "rustc_serialize")] use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; +use std::borrow::{Borrow, BorrowMut}; use std::fmt; use std::fmt::Debug; use std::hash::Hash; @@ -51,6 +52,12 @@ impl Idx for u32 { } } +/// An owned contiguous collection of `T`s, indexed by `I` rather than by `usize`. +/// +/// While it's possible to use `u32` or `usize` directly for `I`, +/// you almost certainly want to use a [`newtype_index!`]-generated type instead. +/// +/// [`newtype_index!`]: ../macro.newtype_index.html #[derive(Clone, PartialEq, Eq, Hash)] #[repr(transparent)] pub struct IndexVec<I: Idx, T> { @@ -58,6 +65,13 @@ pub struct IndexVec<I: Idx, T> { _marker: PhantomData<fn(&I)>, } +/// A view into contiguous `T`s, indexed by `I` rather than by `usize`. +/// +/// One common pattern you'll see is code that uses [`IndexVec::from_elem`] +/// to create the storage needed for a particular "universe" (aka the set of all +/// the possible keys that need an associated value) then passes that working +/// area as `&mut IndexSlice<I, T>` to clarify that nothing will be added nor +/// removed during processing (and, as a bonus, to chase fewer pointers). #[derive(PartialEq, Eq, Hash)] #[repr(transparent)] pub struct IndexSlice<I: Idx, T> { @@ -116,7 +130,7 @@ impl<I: Idx, T> IndexVec<I, T> { } #[inline] - pub fn from_elem<S>(elem: T, universe: &IndexVec<I, S>) -> Self + pub fn from_elem<S>(elem: T, universe: &IndexSlice<I, S>) -> Self where T: Clone, { @@ -244,6 +258,30 @@ impl<I: Idx, T> DerefMut for IndexVec<I, T> { } } +impl<I: Idx, T> Borrow<IndexSlice<I, T>> for IndexVec<I, T> { + fn borrow(&self) -> &IndexSlice<I, T> { + self + } +} + +impl<I: Idx, T> BorrowMut<IndexSlice<I, T>> for IndexVec<I, T> { + fn borrow_mut(&mut self) -> &mut IndexSlice<I, T> { + self + } +} + +impl<I: Idx, T: Clone> ToOwned for IndexSlice<I, T> { + type Owned = IndexVec<I, T>; + + fn to_owned(&self) -> IndexVec<I, T> { + IndexVec::from_raw(self.raw.to_owned()) + } + + fn clone_into(&self, target: &mut IndexVec<I, T>) { + self.raw.clone_into(&mut target.raw) + } +} + impl<I: Idx, T> IndexSlice<I, T> { #[inline] pub fn from_raw(raw: &[T]) -> &Self { @@ -388,7 +426,7 @@ impl<I: Idx, T: Clone> IndexVec<I, T> { } } -impl<I: Idx, T: Ord> IndexVec<I, T> { +impl<I: Idx, T: Ord> IndexSlice<I, T> { #[inline] pub fn binary_search(&self, value: &T) -> Result<I, I> { match self.raw.binary_search(value) { diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index cf657756ff5..9e2bdb7f510 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -13,7 +13,7 @@ use rustc_data_structures::graph::implementation::{ Direction, Graph, NodeIndex, INCOMING, OUTGOING, }; use rustc_data_structures::intern::Interned; -use rustc_index::vec::IndexVec; +use rustc_index::vec::{IndexSlice, IndexVec}; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::PlaceholderRegion; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -723,7 +723,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { fn collect_error_for_expanding_node( &self, graph: &RegionGraph<'tcx>, - dup_vec: &mut IndexVec<RegionVid, Option<RegionVid>>, + dup_vec: &mut IndexSlice<RegionVid, Option<RegionVid>>, node_idx: RegionVid, errors: &mut Vec<RegionResolutionError<'tcx>>, ) { @@ -846,7 +846,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> { graph: &RegionGraph<'tcx>, orig_node_idx: RegionVid, dir: Direction, - mut dup_vec: Option<&mut IndexVec<RegionVid, Option<RegionVid>>>, + mut dup_vec: Option<&mut IndexSlice<RegionVid, Option<RegionVid>>>, ) -> (Vec<RegionAndOrigin<'tcx>>, FxHashSet<RegionVid>, bool) { struct WalkState<'tcx> { set: FxHashSet<RegionVid>, diff --git a/compiler/rustc_middle/src/mir/basic_blocks.rs b/compiler/rustc_middle/src/mir/basic_blocks.rs index b93871769b7..3fb46837935 100644 --- a/compiler/rustc_middle/src/mir/basic_blocks.rs +++ b/compiler/rustc_middle/src/mir/basic_blocks.rs @@ -6,7 +6,7 @@ use rustc_data_structures::graph; use rustc_data_structures::graph::dominators::{dominators, Dominators}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::sync::OnceCell; -use rustc_index::vec::IndexVec; +use rustc_index::vec::{IndexSlice, IndexVec}; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use smallvec::SmallVec; @@ -124,10 +124,10 @@ impl<'tcx> BasicBlocks<'tcx> { } impl<'tcx> std::ops::Deref for BasicBlocks<'tcx> { - type Target = IndexVec<BasicBlock, BasicBlockData<'tcx>>; + type Target = IndexSlice<BasicBlock, BasicBlockData<'tcx>>; #[inline] - fn deref(&self) -> &IndexVec<BasicBlock, BasicBlockData<'tcx>> { + fn deref(&self) -> &IndexSlice<BasicBlock, BasicBlockData<'tcx>> { &self.basic_blocks } } diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index de7e8bc861d..44fd8478be9 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -27,7 +27,7 @@ use polonius_engine::Atom; pub use rustc_ast::Mutability; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::graph::dominators::Dominators; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexSlice, IndexVec}; use rustc_serialize::{Decodable, Encodable}; use rustc_span::symbol::Symbol; use rustc_span::{Span, DUMMY_SP}; @@ -70,12 +70,19 @@ pub use self::pretty::{ }; /// Types for locals -pub type LocalDecls<'tcx> = IndexVec<Local, LocalDecl<'tcx>>; +pub type LocalDecls<'tcx> = IndexSlice<Local, LocalDecl<'tcx>>; pub trait HasLocalDecls<'tcx> { fn local_decls(&self) -> &LocalDecls<'tcx>; } +impl<'tcx> HasLocalDecls<'tcx> for IndexVec<Local, LocalDecl<'tcx>> { + #[inline] + fn local_decls(&self) -> &LocalDecls<'tcx> { + self + } +} + impl<'tcx> HasLocalDecls<'tcx> for LocalDecls<'tcx> { #[inline] fn local_decls(&self) -> &LocalDecls<'tcx> { @@ -250,7 +257,7 @@ pub struct Body<'tcx> { /// The first local is the return value pointer, followed by `arg_count` /// locals for the function arguments, followed by any user-declared /// variables and temporaries. - pub local_decls: LocalDecls<'tcx>, + pub local_decls: IndexVec<Local, LocalDecl<'tcx>>, /// User type annotations. pub user_type_annotations: ty::CanonicalUserTypeAnnotations<'tcx>, @@ -311,7 +318,7 @@ impl<'tcx> Body<'tcx> { source: MirSource<'tcx>, basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>, source_scopes: IndexVec<SourceScope, SourceScopeData<'tcx>>, - local_decls: LocalDecls<'tcx>, + local_decls: IndexVec<Local, LocalDecl<'tcx>>, user_type_annotations: ty::CanonicalUserTypeAnnotations<'tcx>, arg_count: usize, var_debug_info: Vec<VarDebugInfo<'tcx>>, @@ -1779,7 +1786,7 @@ impl SourceScope { /// from the function that was inlined instead of the function call site. pub fn lint_root( self, - source_scopes: &IndexVec<SourceScope, SourceScopeData<'_>>, + source_scopes: &IndexSlice<SourceScope, SourceScopeData<'_>>, ) -> Option<HirId> { let mut data = &source_scopes[self]; // FIXME(oli-obk): we should be able to just walk the `inlined_parent_scope`, but it @@ -1799,7 +1806,7 @@ impl SourceScope { #[inline] pub fn inlined_instance<'tcx>( self, - source_scopes: &IndexVec<SourceScope, SourceScopeData<'tcx>>, + source_scopes: &IndexSlice<SourceScope, SourceScopeData<'tcx>>, ) -> Option<ty::Instance<'tcx>> { let scope_data = &source_scopes[self]; if let Some((inlined_instance, _)) = scope_data.inlined { diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index ac28ef5276c..0092401470f 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -116,7 +116,7 @@ impl<'tcx> PlaceTy<'tcx> { } impl<'tcx> Place<'tcx> { - pub fn ty_from<D>( + pub fn ty_from<D: ?Sized>( local: Local, projection: &[PlaceElem<'tcx>], local_decls: &D, @@ -132,7 +132,7 @@ impl<'tcx> Place<'tcx> { }) } - pub fn ty<D>(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> PlaceTy<'tcx> + pub fn ty<D: ?Sized>(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> PlaceTy<'tcx> where D: HasLocalDecls<'tcx>, { @@ -141,7 +141,7 @@ impl<'tcx> Place<'tcx> { } impl<'tcx> PlaceRef<'tcx> { - pub fn ty<D>(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> PlaceTy<'tcx> + pub fn ty<D: ?Sized>(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> PlaceTy<'tcx> where D: HasLocalDecls<'tcx>, { @@ -155,7 +155,7 @@ pub enum RvalueInitializationState { } impl<'tcx> Rvalue<'tcx> { - pub fn ty<D>(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> Ty<'tcx> + pub fn ty<D: ?Sized>(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> Ty<'tcx> where D: HasLocalDecls<'tcx>, { @@ -217,7 +217,7 @@ impl<'tcx> Rvalue<'tcx> { } impl<'tcx> Operand<'tcx> { - pub fn ty<D>(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> Ty<'tcx> + pub fn ty<D: ?Sized>(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> Ty<'tcx> where D: HasLocalDecls<'tcx>, { diff --git a/compiler/rustc_middle/src/mir/traversal.rs b/compiler/rustc_middle/src/mir/traversal.rs index f37222cb297..62cdf794b1e 100644 --- a/compiler/rustc_middle/src/mir/traversal.rs +++ b/compiler/rustc_middle/src/mir/traversal.rs @@ -101,7 +101,7 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> { /// /// A Postorder traversal of this graph is `D B C A` or `D C B A` pub struct Postorder<'a, 'tcx> { - basic_blocks: &'a IndexVec<BasicBlock, BasicBlockData<'tcx>>, + basic_blocks: &'a IndexSlice<BasicBlock, BasicBlockData<'tcx>>, visited: BitSet<BasicBlock>, visit_stack: Vec<(BasicBlock, Successors<'a>)>, root_is_start_block: bool, @@ -109,7 +109,7 @@ pub struct Postorder<'a, 'tcx> { impl<'a, 'tcx> Postorder<'a, 'tcx> { pub fn new( - basic_blocks: &'a IndexVec<BasicBlock, BasicBlockData<'tcx>>, + basic_blocks: &'a IndexSlice<BasicBlock, BasicBlockData<'tcx>>, root: BasicBlock, ) -> Postorder<'a, 'tcx> { let mut po = Postorder { diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 50d7fb1813a..3a03c0901d7 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -10,7 +10,7 @@ use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def_id::DefId; -use rustc_index::vec::IndexVec; +use rustc_index::vec::{IndexSlice, IndexVec}; use rustc_query_system::ich::StableHashingContext; use rustc_session::DataTypeKind; use rustc_span::symbol::sym; @@ -168,7 +168,7 @@ impl<'tcx> AdtDef<'tcx> { } #[inline] - pub fn variants(self) -> &'tcx IndexVec<VariantIdx, VariantDef> { + pub fn variants(self) -> &'tcx IndexSlice<VariantIdx, VariantDef> { &self.0.0.variants } diff --git a/compiler/rustc_mir_build/src/build/custom/mod.rs b/compiler/rustc_mir_build/src/build/custom/mod.rs index 33fdc1901cd..d385153ba94 100644 --- a/compiler/rustc_mir_build/src/build/custom/mod.rs +++ b/compiler/rustc_mir_build/src/build/custom/mod.rs @@ -21,7 +21,7 @@ use rustc_ast::Attribute; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def_id::DefId; use rustc_hir::HirId; -use rustc_index::vec::IndexVec; +use rustc_index::vec::{IndexSlice, IndexVec}; use rustc_middle::{ mir::*, thir::*, @@ -37,7 +37,7 @@ pub(super) fn build_custom_mir<'tcx>( hir_id: HirId, thir: &Thir<'tcx>, expr: ExprId, - params: &IndexVec<ParamId, Param<'tcx>>, + params: &IndexSlice<ParamId, Param<'tcx>>, return_ty: Ty<'tcx>, return_ty_span: Span, span: Span, @@ -49,7 +49,7 @@ pub(super) fn build_custom_mir<'tcx>( phase: MirPhase::Built, source_scopes: IndexVec::new(), generator: None, - local_decls: LocalDecls::new(), + local_decls: IndexVec::new(), user_type_annotations: IndexVec::new(), arg_count: params.len(), spread_arg: None, diff --git a/compiler/rustc_mir_build/src/build/custom/parse.rs b/compiler/rustc_mir_build/src/build/custom/parse.rs index d72770e70c7..12b2f5d8077 100644 --- a/compiler/rustc_mir_build/src/build/custom/parse.rs +++ b/compiler/rustc_mir_build/src/build/custom/parse.rs @@ -1,4 +1,4 @@ -use rustc_index::vec::IndexVec; +use rustc_index::vec::IndexSlice; use rustc_middle::{mir::*, thir::*, ty::Ty}; use rustc_span::Span; @@ -81,7 +81,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { } } - pub fn parse_args(&mut self, params: &IndexVec<ParamId, Param<'tcx>>) -> PResult<()> { + pub fn parse_args(&mut self, params: &IndexSlice<ParamId, Param<'tcx>>) -> PResult<()> { for param in params.iter() { let (var, span) = { let pat = param.pat.as_ref().unwrap(); diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index e87e38fd04c..ac645cce5c6 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -11,7 +11,7 @@ use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::{GeneratorKind, Node}; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexSlice, IndexVec}; use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_middle::hir::place::PlaceBase as HirPlaceBase; use rustc_middle::middle::region; @@ -821,7 +821,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { fn args_and_body( &mut self, mut block: BasicBlock, - arguments: &IndexVec<ParamId, Param<'tcx>>, + arguments: &IndexSlice<ParamId, Param<'tcx>>, argument_scope: region::Scope, expr: &Expr<'tcx>, ) -> BlockAnd<()> { diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs index 4bc2c0ca791..25af221bf36 100644 --- a/compiler/rustc_mir_build/src/build/scope.rs +++ b/compiler/rustc_mir_build/src/build/scope.rs @@ -86,7 +86,7 @@ use std::mem; use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder, CFG}; use rustc_data_structures::fx::FxHashMap; use rustc_hir::HirId; -use rustc_index::vec::IndexVec; +use rustc_index::vec::{IndexSlice, IndexVec}; use rustc_middle::middle::region; use rustc_middle::mir::*; use rustc_middle::thir::{Expr, LintLevel}; @@ -360,7 +360,7 @@ impl DropTree { fn link_blocks<'tcx>( &self, cfg: &mut CFG<'tcx>, - blocks: &IndexVec<DropIdx, Option<BasicBlock>>, + blocks: &IndexSlice<DropIdx, Option<BasicBlock>>, ) { for (drop_idx, drop_data) in self.drops.iter_enumerated().rev() { let Some(block) = blocks[drop_idx] else { continue }; diff --git a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs index 5f22a418de8..257a42cddc8 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs @@ -1,6 +1,6 @@ use crate::move_paths::builder::MoveDat; use rustc_data_structures::fx::FxHashMap; -use rustc_index::vec::IndexVec; +use rustc_index::vec::{IndexSlice, IndexVec}; use rustc_middle::mir::*; use rustc_middle::ty::{ParamEnv, Ty, TyCtxt}; use rustc_span::Span; @@ -64,7 +64,7 @@ impl<'tcx> MovePath<'tcx> { /// Returns an iterator over the parents of `self`. pub fn parents<'a>( &self, - move_paths: &'a IndexVec<MovePathIndex, MovePath<'tcx>>, + move_paths: &'a IndexSlice<MovePathIndex, MovePath<'tcx>>, ) -> impl 'a + Iterator<Item = (MovePathIndex, &'a MovePath<'tcx>)> { let first = self.parent.map(|mpi| (mpi, &move_paths[mpi])); MovePathLinearIter { @@ -78,7 +78,7 @@ impl<'tcx> MovePath<'tcx> { /// Returns an iterator over the immediate children of `self`. pub fn children<'a>( &self, - move_paths: &'a IndexVec<MovePathIndex, MovePath<'tcx>>, + move_paths: &'a IndexSlice<MovePathIndex, MovePath<'tcx>>, ) -> impl 'a + Iterator<Item = (MovePathIndex, &'a MovePath<'tcx>)> { let first = self.first_child.map(|mpi| (mpi, &move_paths[mpi])); MovePathLinearIter { @@ -95,7 +95,7 @@ impl<'tcx> MovePath<'tcx> { /// `f` will **not** be called on `self`. pub fn find_descendant( &self, - move_paths: &IndexVec<MovePathIndex, MovePath<'_>>, + move_paths: &IndexSlice<MovePathIndex, MovePath<'_>>, f: impl Fn(MovePathIndex) -> bool, ) -> Option<MovePathIndex> { let mut todo = if let Some(child) = self.first_child { diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index 63e553bec53..33a15a8d224 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -36,7 +36,7 @@ use std::fmt::{Debug, Formatter}; use rustc_data_structures::fx::FxHashMap; use rustc_index::bit_set::BitSet; -use rustc_index::vec::IndexVec; +use rustc_index::vec::{IndexSlice, IndexVec}; use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -1028,8 +1028,8 @@ where fn debug_with_context_rec<V: Debug + Eq>( place: PlaceIndex, place_str: &str, - new: &IndexVec<ValueIndex, V>, - old: Option<&IndexVec<ValueIndex, V>>, + new: &IndexSlice<ValueIndex, V>, + old: Option<&IndexSlice<ValueIndex, V>>, map: &Map, f: &mut Formatter<'_>, ) -> std::fmt::Result { @@ -1069,8 +1069,8 @@ fn debug_with_context_rec<V: Debug + Eq>( } fn debug_with_context<V: Debug + Eq>( - new: &IndexVec<ValueIndex, V>, - old: Option<&IndexVec<ValueIndex, V>>, + new: &IndexSlice<ValueIndex, V>, + old: Option<&IndexSlice<ValueIndex, V>>, map: &Map, f: &mut Formatter<'_>, ) -> std::fmt::Result { diff --git a/compiler/rustc_mir_transform/src/check_alignment.rs b/compiler/rustc_mir_transform/src/check_alignment.rs index 996416ef22e..5815887e5bb 100644 --- a/compiler/rustc_mir_transform/src/check_alignment.rs +++ b/compiler/rustc_mir_transform/src/check_alignment.rs @@ -128,7 +128,7 @@ fn split_block( fn insert_alignment_check<'tcx>( tcx: TyCtxt<'tcx>, - local_decls: &mut LocalDecls<'tcx>, + local_decls: &mut IndexVec<Local, LocalDecl<'tcx>>, block_data: &mut BasicBlockData<'tcx>, pointer: Place<'tcx>, pointee_ty: Ty<'tcx>, diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index e7075d5e791..ac55948e61b 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -7,7 +7,7 @@ use rustc_const_eval::const_eval::CheckAlignment; use rustc_data_structures::fx::FxHashSet; use rustc_hir::def::DefKind; use rustc_index::bit_set::BitSet; -use rustc_index::vec::IndexVec; +use rustc_index::vec::{IndexSlice, IndexVec}; use rustc_middle::mir::visit::{ MutVisitor, MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor, }; @@ -127,7 +127,7 @@ impl<'tcx> MirPass<'tcx> for ConstProp { let dummy_body = &Body::new( body.source, - (*body.basic_blocks).clone(), + (*body.basic_blocks).to_owned(), body.source_scopes.clone(), body.local_decls.clone(), Default::default(), @@ -319,7 +319,7 @@ struct ConstPropagator<'mir, 'tcx> { ecx: InterpCx<'mir, 'tcx, ConstPropMachine<'mir, 'tcx>>, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, - local_decls: &'mir IndexVec<Local, LocalDecl<'tcx>>, + local_decls: &'mir IndexSlice<Local, LocalDecl<'tcx>>, } impl<'tcx> LayoutOfHelpers<'tcx> for ConstPropagator<'_, 'tcx> { diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index 60401b05492..d7696a57000 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -9,7 +9,7 @@ use rustc_const_eval::interpret::{ }; use rustc_hir::def::DefKind; use rustc_hir::HirId; -use rustc_index::vec::IndexVec; +use rustc_index::vec::IndexSlice; use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::*; use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout}; @@ -103,7 +103,7 @@ impl<'tcx> MirLint<'tcx> for ConstProp { let dummy_body = &Body::new( body.source, - (*body.basic_blocks).clone(), + (*body.basic_blocks).to_owned(), body.source_scopes.clone(), body.local_decls.clone(), Default::default(), @@ -130,8 +130,8 @@ struct ConstPropagator<'mir, 'tcx> { ecx: InterpCx<'mir, 'tcx, ConstPropMachine<'mir, 'tcx>>, tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, - source_scopes: &'mir IndexVec<SourceScope, SourceScopeData<'tcx>>, - local_decls: &'mir IndexVec<Local, LocalDecl<'tcx>>, + source_scopes: &'mir IndexSlice<SourceScope, SourceScopeData<'tcx>>, + local_decls: &'mir IndexSlice<Local, LocalDecl<'tcx>>, // Because we have `MutVisitor` we can't obtain the `SourceInfo` from a `Location`. So we store // the last known `SourceInfo` here and just keep revisiting it. source_info: Option<SourceInfo>, diff --git a/compiler/rustc_mir_transform/src/copy_prop.rs b/compiler/rustc_mir_transform/src/copy_prop.rs index f27beb64a14..c155048c98b 100644 --- a/compiler/rustc_mir_transform/src/copy_prop.rs +++ b/compiler/rustc_mir_transform/src/copy_prop.rs @@ -1,5 +1,5 @@ use rustc_index::bit_set::BitSet; -use rustc_index::vec::IndexVec; +use rustc_index::vec::IndexSlice; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; use rustc_middle::ty::TyCtxt; @@ -102,7 +102,7 @@ struct Replacer<'a, 'tcx> { fully_moved: BitSet<Local>, storage_to_remove: BitSet<Local>, borrowed_locals: BitSet<Local>, - copy_classes: &'a IndexVec<Local, Local>, + copy_classes: &'a IndexSlice<Local, Local>, } impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> { diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs index 49028ca4e5e..689d6c71361 100644 --- a/compiler/rustc_mir_transform/src/coverage/graph.rs +++ b/compiler/rustc_mir_transform/src/coverage/graph.rs @@ -5,7 +5,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::graph::dominators::{self, Dominators}; use rustc_data_structures::graph::{self, GraphSuccessors, WithNumNodes, WithStartNode}; use rustc_index::bit_set::BitSet; -use rustc_index::vec::IndexVec; +use rustc_index::vec::{IndexSlice, IndexVec}; use rustc_middle::mir::coverage::*; use rustc_middle::mir::{self, BasicBlock, BasicBlockData, Terminator, TerminatorKind}; @@ -176,10 +176,10 @@ impl CoverageGraph { fn add_basic_coverage_block( bcbs: &mut IndexVec<BasicCoverageBlock, BasicCoverageBlockData>, - bb_to_bcb: &mut IndexVec<BasicBlock, Option<BasicCoverageBlock>>, + bb_to_bcb: &mut IndexSlice<BasicBlock, Option<BasicCoverageBlock>>, basic_blocks: Vec<BasicBlock>, ) { - let bcb = BasicCoverageBlock::from_usize(bcbs.len()); + let bcb = bcbs.next_index(); for &bb in basic_blocks.iter() { bb_to_bcb[bb] = Some(bcb); } diff --git a/compiler/rustc_mir_transform/src/lower_slice_len.rs b/compiler/rustc_mir_transform/src/lower_slice_len.rs index c6e7468aab4..101fae2f08c 100644 --- a/compiler/rustc_mir_transform/src/lower_slice_len.rs +++ b/compiler/rustc_mir_transform/src/lower_slice_len.rs @@ -3,7 +3,7 @@ use crate::MirPass; use rustc_hir::def_id::DefId; -use rustc_index::vec::IndexVec; +use rustc_index::vec::IndexSlice; use rustc_middle::mir::*; use rustc_middle::ty::{self, TyCtxt}; @@ -42,7 +42,7 @@ struct SliceLenPatchInformation<'tcx> { fn lower_slice_len_call<'tcx>( tcx: TyCtxt<'tcx>, block: &mut BasicBlockData<'tcx>, - local_decls: &IndexVec<Local, LocalDecl<'tcx>>, + local_decls: &IndexSlice<Local, LocalDecl<'tcx>>, slice_len_fn_item_def_id: DefId, ) { let mut patch_found: Option<SliceLenPatchInformation<'_>> = None; diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs index 5bdb8ab6bfc..c79e1cf0805 100644 --- a/compiler/rustc_mir_transform/src/simplify.rs +++ b/compiler/rustc_mir_transform/src/simplify.rs @@ -29,7 +29,7 @@ use crate::MirPass; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; -use rustc_index::vec::{Idx, IndexVec}; +use rustc_index::vec::{Idx, IndexSlice, IndexVec}; use rustc_middle::mir::coverage::*; use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; @@ -67,7 +67,7 @@ impl<'tcx> MirPass<'tcx> for SimplifyCfg { } pub struct CfgSimplifier<'a, 'tcx> { - basic_blocks: &'a mut IndexVec<BasicBlock, BasicBlockData<'tcx>>, + basic_blocks: &'a mut IndexSlice<BasicBlock, BasicBlockData<'tcx>>, pred_count: IndexVec<BasicBlock, u32>, } @@ -369,8 +369,8 @@ pub fn remove_dead_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { /// instances in a single body, so the strategy described above is applied to /// coverage counters from each instance individually. fn save_unreachable_coverage( - basic_blocks: &mut IndexVec<BasicBlock, BasicBlockData<'_>>, - source_scopes: &IndexVec<SourceScope, SourceScopeData<'_>>, + basic_blocks: &mut IndexSlice<BasicBlock, BasicBlockData<'_>>, + source_scopes: &IndexSlice<SourceScope, SourceScopeData<'_>>, first_dead_block: usize, ) { // Identify instances that still have some live coverage counters left. @@ -489,7 +489,7 @@ fn make_local_map<V>( local_decls: &mut IndexVec<Local, V>, used_locals: &UsedLocals, ) -> IndexVec<Local, Option<Local>> { - let mut map: IndexVec<Local, Option<Local>> = IndexVec::from_elem(None, &*local_decls); + let mut map: IndexVec<Local, Option<Local>> = IndexVec::from_elem(None, local_decls); let mut used = Local::new(0); for alive_index in local_decls.indices() { diff --git a/compiler/rustc_mir_transform/src/ssa.rs b/compiler/rustc_mir_transform/src/ssa.rs index 73168652f8f..be026402dd5 100644 --- a/compiler/rustc_mir_transform/src/ssa.rs +++ b/compiler/rustc_mir_transform/src/ssa.rs @@ -1,7 +1,7 @@ use either::Either; use rustc_data_structures::graph::dominators::Dominators; use rustc_index::bit_set::BitSet; -use rustc_index::vec::IndexVec; +use rustc_index::vec::{IndexSlice, IndexVec}; use rustc_middle::middle::resolve_bound_vars::Set1; use rustc_middle::mir::visit::*; use rustc_middle::mir::*; @@ -135,7 +135,7 @@ impl SsaLocals { /// _d => _a // transitively through _c /// /// Exception: we do not see through the return place, as it cannot be substituted. - pub fn copy_classes(&self) -> &IndexVec<Local, Local> { + pub fn copy_classes(&self) -> &IndexSlice<Local, Local> { &self.copy_classes } From d8a4e7cf51fbdca489084e117050fe2e2c22cb21 Mon Sep 17 00:00:00 2001 From: bohan <bohan-zhang@foxmail.com> Date: Sun, 2 Apr 2023 18:50:01 +0800 Subject: [PATCH 335/346] fix(middle): emit error rather than delay bug when reaching limit --- compiler/rustc_middle/messages.ftl | 4 ++ compiler/rustc_middle/src/error.rs | 8 +++ compiler/rustc_middle/src/ty/util.rs | 14 +++-- tests/ui/autoref-autoderef/issue-38940.rs | 52 ------------------- tests/ui/autoref-autoderef/issue-38940.stderr | 23 -------- .../did_you_mean/recursion_limit_deref.stderr | 6 ++- 6 files changed, 26 insertions(+), 81 deletions(-) delete mode 100644 tests/ui/autoref-autoderef/issue-38940.rs delete mode 100644 tests/ui/autoref-autoderef/issue-38940.stderr diff --git a/compiler/rustc_middle/messages.ftl b/compiler/rustc_middle/messages.ftl index 4f4e5c6a2c9..bd9d89deee1 100644 --- a/compiler/rustc_middle/messages.ftl +++ b/compiler/rustc_middle/messages.ftl @@ -16,6 +16,10 @@ middle_limit_invalid = `limit` must be a non-negative integer .label = {$error_str} +middle_recursion_limit_reached = + reached the recursion limit finding the struct tail for `{$ty}` + .help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` + middle_const_eval_non_int = constant evaluation of enum discriminant resulted in non-integer diff --git a/compiler/rustc_middle/src/error.rs b/compiler/rustc_middle/src/error.rs index 5e94da8cb4d..dc4aa18640f 100644 --- a/compiler/rustc_middle/src/error.rs +++ b/compiler/rustc_middle/src/error.rs @@ -49,6 +49,14 @@ pub struct LimitInvalid<'a> { pub error_str: &'a str, } +#[derive(Diagnostic)] +#[diag(middle_recursion_limit_reached)] +#[help] +pub struct RecursionLimitReached<'tcx> { + pub ty: Ty<'tcx>, + pub suggested_limit: rustc_session::Limit, +} + #[derive(Diagnostic)] #[diag(middle_const_eval_non_int)] pub struct ConstEvalNonIntError { diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index d3565b28ae5..4411bcd927d 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -19,7 +19,8 @@ use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_index::bit_set::GrowableBitSet; use rustc_index::vec::{Idx, IndexVec}; use rustc_macros::HashStable; -use rustc_span::{sym, DUMMY_SP}; +use rustc_session::Limit; +use rustc_span::sym; use rustc_target::abi::{Integer, IntegerType, Size, TargetDataLayout}; use rustc_target::spec::abi::Abi; use smallvec::SmallVec; @@ -225,10 +226,13 @@ impl<'tcx> TyCtxt<'tcx> { let recursion_limit = self.recursion_limit(); for iteration in 0.. { if !recursion_limit.value_within_limit(iteration) { - return self.ty_error_with_message( - DUMMY_SP, - &format!("reached the recursion limit finding the struct tail for {}", ty), - ); + let suggested_limit = match recursion_limit { + Limit(0) => Limit(2), + limit => limit * 2, + }; + let reported = + self.sess.emit_err(crate::error::RecursionLimitReached { ty, suggested_limit }); + return self.ty_error(reported); } match *ty.kind() { ty::Adt(def, substs) => { diff --git a/tests/ui/autoref-autoderef/issue-38940.rs b/tests/ui/autoref-autoderef/issue-38940.rs deleted file mode 100644 index d2f1c6e3271..00000000000 --- a/tests/ui/autoref-autoderef/issue-38940.rs +++ /dev/null @@ -1,52 +0,0 @@ -// issue-38940: error printed twice for deref recursion limit exceeded -// Test that the recursion limit can be changed. In this case, we have -// deeply nested types that will fail the `Send` check by overflow -// when the recursion limit is set very low. -// compile-flags: -Zdeduplicate-diagnostics=yes - -#![allow(dead_code)] -#![recursion_limit = "10"] -macro_rules! link { - ($outer:ident, $inner:ident) => { - struct $outer($inner); - impl $outer { - fn new() -> $outer { - $outer($inner::new()) - } - } - impl std::ops::Deref for $outer { - type Target = $inner; - fn deref(&self) -> &$inner { - &self.0 - } - } - }; -} - -struct Bottom; - -impl Bottom { - fn new() -> Bottom { - Bottom - } -} - -link!(Top, A); -link!(A, B); -link!(B, C); -link!(C, D); -link!(D, E); -link!(E, F); -link!(F, G); -link!(G, H); -link!(H, I); -link!(I, J); -link!(J, K); -link!(K, Bottom); - -fn main() { - let t = Top::new(); - let x: &Bottom = &t; - //~^ ERROR mismatched types - //~| ERROR reached the recursion limit while auto-dereferencing `J` -} diff --git a/tests/ui/autoref-autoderef/issue-38940.stderr b/tests/ui/autoref-autoderef/issue-38940.stderr deleted file mode 100644 index 8e98bfcd90f..00000000000 --- a/tests/ui/autoref-autoderef/issue-38940.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error[E0055]: reached the recursion limit while auto-dereferencing `J` - --> $DIR/issue-38940.rs:49:22 - | -LL | let x: &Bottom = &t; - | ^^ deref recursion limit reached - | - = help: consider increasing the recursion limit by adding a `#![recursion_limit = "20"]` attribute to your crate (`issue_38940`) - -error[E0308]: mismatched types - --> $DIR/issue-38940.rs:49:22 - | -LL | let x: &Bottom = &t; - | ------- ^^ expected `&Bottom`, found `&Top` - | | - | expected due to this - | - = note: expected reference `&Bottom` - found reference `&Top` - -error: aborting due to 2 previous errors - -Some errors have detailed explanations: E0055, E0308. -For more information about an error, try `rustc --explain E0055`. diff --git a/tests/ui/did_you_mean/recursion_limit_deref.stderr b/tests/ui/did_you_mean/recursion_limit_deref.stderr index 32fb628c470..b0c493faf1e 100644 --- a/tests/ui/did_you_mean/recursion_limit_deref.stderr +++ b/tests/ui/did_you_mean/recursion_limit_deref.stderr @@ -1,3 +1,7 @@ +error: reached the recursion limit finding the struct tail for `Bottom` + | + = help: consider increasing the recursion limit by adding a `#![recursion_limit = "20"]` + error[E0055]: reached the recursion limit while auto-dereferencing `J` --> $DIR/recursion_limit_deref.rs:51:22 | @@ -17,7 +21,7 @@ LL | let x: &Bottom = &t; = note: expected reference `&Bottom` found reference `&Top` -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0055, E0308. For more information about an error, try `rustc --explain E0055`. From abc61d23de7007773e3e75d50967e3813ca9ac92 Mon Sep 17 00:00:00 2001 From: Sergey Kaunov <65976143+skaunov@users.noreply.github.com> Date: Mon, 3 Apr 2023 09:18:14 +0300 Subject: [PATCH 336/346] Add links to <cell.rs> `UnsafeCell` page could benefit too from having links to these most popular structs in the module. --- library/core/src/cell.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs index 63bce5d0ccd..d728dc03817 100644 --- a/library/core/src/cell.rs +++ b/library/core/src/cell.rs @@ -1816,7 +1816,7 @@ impl<T: ?Sized + fmt::Display> fmt::Display for RefMut<'_, T> { /// `UnsafeCell<T>` opts-out of the immutability guarantee for `&T`: a shared reference /// `&UnsafeCell<T>` may point to data that is being mutated. This is called "interior mutability". /// -/// All other types that allow internal mutability, such as `Cell<T>` and `RefCell<T>`, internally +/// All other types that allow internal mutability, such as [`Cell<T>`] and [`RefCell<T>`], internally /// use `UnsafeCell` to wrap their data. /// /// Note that only the immutability guarantee for shared references is affected by `UnsafeCell`. The From 5d842a6f3219f577eefe41853c47db6a21dd9f6f Mon Sep 17 00:00:00 2001 From: Pietro Albini <pietro.albini@ferrous-systems.com> Date: Mon, 3 Apr 2023 11:09:10 +0200 Subject: [PATCH 337/346] update book --- src/doc/book | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/book b/src/doc/book index 21a2ed14f44..0510ca84c2c 160000 --- a/src/doc/book +++ b/src/doc/book @@ -1 +1 @@ -Subproject commit 21a2ed14f4480dab62438dcc1130291bebc65379 +Subproject commit 0510ca84c2ce6bf93c4ccf9248756e9e4fd00b12 From 09541b5e1b3d35b932fed363eac9b83a11ca4136 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand <ulrich.weigand@de.ibm.com> Date: Thu, 30 Mar 2023 15:37:47 +0200 Subject: [PATCH 338/346] Increase libffi version to 3.2 to support s390x --- Cargo.lock | 8 ++++---- src/tools/miri/Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 561f29abec4..949aefbc744 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2888,9 +2888,9 @@ dependencies = [ [[package]] name = "libffi" -version = "3.0.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e454b3efb16fba3b17810ae5e41df02b649e564ab3c5a34b3b93ed07ad287e6" +checksum = "ce826c243048e3d5cec441799724de52e2d42f820468431fc3fceee2341871e2" dependencies = [ "libc", "libffi-sys", @@ -2898,9 +2898,9 @@ dependencies = [ [[package]] name = "libffi-sys" -version = "2.0.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab4106b7f09d7b87d021334d5618fac1dfcfb824d4c5fe111ff0074dfd242e15" +checksum = "dc65067b78c0fc069771e8b9a9e02df71e08858bec92c1f101377c67b9dca7c7" dependencies = [ "cc", ] diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml index 717020f43c4..6705bf7b007 100644 --- a/src/tools/miri/Cargo.toml +++ b/src/tools/miri/Cargo.toml @@ -34,7 +34,7 @@ measureme = "10.0.0" libc = "0.2" [target.'cfg(target_os = "linux")'.dependencies] -libffi = "3.0.0" +libffi = "3.2.0" libloading = "0.7" [dev-dependencies] From 0da526b5f36daccb2d52adb6e21785474d3525e3 Mon Sep 17 00:00:00 2001 From: Mark Rousskov <mark.simulacrum@gmail.com> Date: Mon, 3 Apr 2023 07:44:58 -0400 Subject: [PATCH 339/346] Remove optimal xz settings from CI This is a companion PR to rust-lang/promote-release#58, which moves the relevant optimal code to rust-lang/promote-release. As mentioned in the comments of that PR, this is expected to cut CI costs (and time, though predominantly felt on fast builders) and reduce wasted resources due to in-practice single-threaded compression not using the full 8+ vCPU builders we have available. --- src/ci/run.sh | 7 ++- src/tools/rust-installer/src/compression.rs | 52 +++------------------ 2 files changed, 13 insertions(+), 46 deletions(-) diff --git a/src/ci/run.sh b/src/ci/run.sh index 5f4e4a8e1b4..3056d9fc054 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -58,7 +58,12 @@ RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --disable-manage-submodules" RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-locked-deps" RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --enable-cargo-native-static" RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set rust.codegen-units-std=1" -RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set dist.compression-profile=best" +# rust-lang/promote-release will recompress CI artifacts, and while we care +# about the per-commit artifact sizes, it's not as important that they're +# highly compressed as it is that the process is fast. Best compression +# generally implies single-threaded compression which results in wasting most +# of our CPU resources. +RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --set dist.compression-profile=balanced" # When building for mingw, limit the number of parallel linker jobs during # the LLVM build, as not to run out of memory. diff --git a/src/tools/rust-installer/src/compression.rs b/src/tools/rust-installer/src/compression.rs index 510c914163c..7c9c946e0b5 100644 --- a/src/tools/rust-installer/src/compression.rs +++ b/src/tools/rust-installer/src/compression.rs @@ -89,43 +89,11 @@ impl CompressionFormat { xz2::stream::MtStreamBuilder::new().threads(6).preset(6).encoder().unwrap() } CompressionProfile::Best => { - let mut filters = xz2::stream::Filters::new(); - // the preset is overridden by the other options so it doesn't matter - let mut lzma_ops = xz2::stream::LzmaOptions::new_preset(9).unwrap(); - // This sets the overall dictionary size, which is also how much memory (baseline) - // is needed for decompression. - lzma_ops.dict_size(64 * 1024 * 1024); - // Use the best match finder for compression ratio. - lzma_ops.match_finder(xz2::stream::MatchFinder::BinaryTree4); - lzma_ops.mode(xz2::stream::Mode::Normal); - // Set nice len to the maximum for best compression ratio - lzma_ops.nice_len(273); - // Set depth to a reasonable value, 0 means auto, 1000 is somwhat high but gives - // good results. - lzma_ops.depth(1000); - // 2 is the default and does well for most files - lzma_ops.position_bits(2); - // 0 is the default and does well for most files - lzma_ops.literal_position_bits(0); - // 3 is the default and does well for most files - lzma_ops.literal_context_bits(3); - - filters.lzma2(&lzma_ops); - - let mut builder = xz2::stream::MtStreamBuilder::new(); - builder.filters(filters); - - // On 32-bit platforms limit ourselves to 3 threads, otherwise we exceed memory - // usage this process can take. In the future we'll likely only do super-fast - // compression in CI and move this heavyweight processing to promote-release (which - // is always 64-bit and can run on big-memory machines) but for now this lets us - // move forward. - if std::mem::size_of::<usize>() == 4 { - builder.threads(3); - } else { - builder.threads(6); - } - builder.encoder().unwrap() + // Note that this isn't actually the best compression settings for the + // produced artifacts, the production artifacts on static.rust-lang.org are + // produced by rust-lang/promote-release which hosts recompression logic + // and is tuned for optimal compression. + xz2::stream::MtStreamBuilder::new().threads(6).preset(9).encoder().unwrap() } }; @@ -245,20 +213,14 @@ impl Write for CombinedEncoder { } fn flush(&mut self) -> std::io::Result<()> { - self.encoders - .par_iter_mut() - .map(|w| w.flush()) - .collect::<std::io::Result<Vec<()>>>()?; + self.encoders.par_iter_mut().map(|w| w.flush()).collect::<std::io::Result<Vec<()>>>()?; Ok(()) } } impl Encoder for CombinedEncoder { fn finish(self: Box<Self>) -> Result<(), Error> { - self.encoders - .into_par_iter() - .map(|e| e.finish()) - .collect::<Result<Vec<()>, Error>>()?; + self.encoders.into_par_iter().map(|e| e.finish()).collect::<Result<Vec<()>, Error>>()?; Ok(()) } } From 49795b40cf375a3c9ffe1843792856b40eace949 Mon Sep 17 00:00:00 2001 From: Pietro Albini <pietro.albini@ferrous-systems.com> Date: Mon, 3 Apr 2023 14:12:13 +0200 Subject: [PATCH 340/346] update rustc dev guide --- src/doc/rustc-dev-guide | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide index d08baa166b4..fca8af6c154 160000 --- a/src/doc/rustc-dev-guide +++ b/src/doc/rustc-dev-guide @@ -1 +1 @@ -Subproject commit d08baa166b463537229eeb737c4ccadabd83cf78 +Subproject commit fca8af6c154c6cde2512f1331cf2704f214a818e From a6431e96b13b3420cd528692a648de47a1c05a96 Mon Sep 17 00:00:00 2001 From: Pietro Albini <pietro.albini@ferrous-systems.com> Date: Mon, 3 Apr 2023 14:12:48 +0200 Subject: [PATCH 341/346] update rust-by-example --- src/doc/rust-by-example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example index cfbfd648ce3..ba84bf35d0f 160000 --- a/src/doc/rust-by-example +++ b/src/doc/rust-by-example @@ -1 +1 @@ -Subproject commit cfbfd648ce33926c3490f24de9a5b56cce404b88 +Subproject commit ba84bf35d0f17d404003349309201654d25f61af From ca79b82c6cff632c98ed355e7d0f554ef8b5cc5d Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Mon, 3 Apr 2023 15:23:08 +0000 Subject: [PATCH 342/346] Never consider int and float vars for `FnPtr` candidates This solves a regression where `0.0.cmp()` was ambiguous when a custom trait with a `cmp` method was in scope. FOr integers it shouldn't be a problem in practice so I wasn't able to add a test. --- .../src/traits/select/candidate_assembly.rs | 10 ++++++++-- .../rustc_trait_selection/src/traits/select/mod.rs | 12 ++++++------ tests/ui/fn/fn-ptr-trait-int-float-infer-var.rs | 10 ++++++++++ 3 files changed, 24 insertions(+), 8 deletions(-) create mode 100644 tests/ui/fn/fn-ptr-trait-int-float-infer-var.rs diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 47a351590b1..090312338e0 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -998,8 +998,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::Alias(..) | ty::Param(..) | ty::Bound(..) - | ty::Error(_) => {} - ty::Infer(_) => { + | ty::Error(_) + | ty::Infer( + ty::InferTy::IntVar(_) + | ty::InferTy::FloatVar(_) + | ty::InferTy::FreshIntTy(_) + | ty::InferTy::FreshFloatTy(_), + ) => {} + ty::Infer(ty::InferTy::TyVar(_) | ty::InferTy::FreshTy(_)) => { candidates.ambiguous = true; } } diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 3ed3dd2d20d..b58e62536d6 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -177,14 +177,14 @@ struct TraitObligationStack<'prev, 'tcx> { } struct SelectionCandidateSet<'tcx> { - // A list of candidates that definitely apply to the current - // obligation (meaning: types unify). + /// A list of candidates that definitely apply to the current + /// obligation (meaning: types unify). vec: Vec<SelectionCandidate<'tcx>>, - // If `true`, then there were candidates that might or might - // not have applied, but we couldn't tell. This occurs when some - // of the input types are type variables, in which case there are - // various "builtin" rules that might or might not trigger. + /// If `true`, then there were candidates that might or might + /// not have applied, but we couldn't tell. This occurs when some + /// of the input types are type variables, in which case there are + /// various "builtin" rules that might or might not trigger. ambiguous: bool, } diff --git a/tests/ui/fn/fn-ptr-trait-int-float-infer-var.rs b/tests/ui/fn/fn-ptr-trait-int-float-infer-var.rs new file mode 100644 index 00000000000..eec7da044c0 --- /dev/null +++ b/tests/ui/fn/fn-ptr-trait-int-float-infer-var.rs @@ -0,0 +1,10 @@ +// check-pass +trait MyCmp { + fn cmp(&self) {} +} +impl MyCmp for f32 {} + +fn main() { + // Ensure that `impl<F: FnPtr> Ord for F` is never considered for int and float infer vars. + 0.0.cmp(); +} From 9e579cc10c32945cdde6fa1fb474005d31b8c2cf Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Mon, 3 Apr 2023 20:29:41 +0200 Subject: [PATCH 343/346] Add test --- .../missed-capture-issue-107414.rs | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 tests/ui/async-await/missed-capture-issue-107414.rs diff --git a/tests/ui/async-await/missed-capture-issue-107414.rs b/tests/ui/async-await/missed-capture-issue-107414.rs new file mode 100644 index 00000000000..0ab4f5ade98 --- /dev/null +++ b/tests/ui/async-await/missed-capture-issue-107414.rs @@ -0,0 +1,24 @@ +// check-pass +// edition:2018 + +fn main() {} + +struct StructA {} +struct StructB {} + +impl StructA { + fn fn_taking_struct_b(&self, struct_b: &StructB) -> bool { + true + } +} + +async fn get_struct_a_async() -> StructA { + StructA {} +} + +async fn ice() { + match Some(StructB {}) { + Some(struct_b) if get_struct_a_async().await.fn_taking_struct_b(&struct_b) => {} + _ => {} + } +} From 07e3bd1ffbc3bacbbdc99fc923c2a301ad92372a Mon Sep 17 00:00:00 2001 From: Chris Denton <chris@chrisdenton.dev> Date: Mon, 3 Apr 2023 20:07:35 +0100 Subject: [PATCH 344/346] Add Chris Denton to `.mailmap` --- .mailmap | 1 + 1 file changed, 1 insertion(+) diff --git a/.mailmap b/.mailmap index b8a9fc27eb7..92be3174750 100644 --- a/.mailmap +++ b/.mailmap @@ -102,6 +102,7 @@ Carol Willing <carolcode@willingconsulting.com> Chandler Deng <chandde@microsoft.com> Charles Lew <crlf0710@gmail.com> CrLF0710 <crlf0710@gmail.com> Chris C Cerami <chrisccerami@users.noreply.github.com> Chris C Cerami <chrisccerami@gmail.com> +Chris Denton <chris@chrisdenton.dev> Chris Denton <ChrisDenton@users.noreply.github.com> Chris Gregory <czipperz@gmail.com> Chris Pardy <chrispardy36@gmail.com> Chris Pressey <cpressey@gmail.com> From aef713b8ffb32825e9a954c6618f5de2738540bc Mon Sep 17 00:00:00 2001 From: Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de> Date: Tue, 4 Apr 2023 08:01:05 +0000 Subject: [PATCH 345/346] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 8842e939d67..1bf1217c83b 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -c763eceae349c1d827d9cfbf5df21ca40b21c861 +bd991d9953625e9d51fc4fcb5e19aa9c3ea598a8 From 663664bec65de66e80dccaf0805a35c77c43d5fc Mon Sep 17 00:00:00 2001 From: Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de> Date: Tue, 4 Apr 2023 08:05:39 +0000 Subject: [PATCH 346/346] Update Cargo.lock --- src/tools/miri/Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock index d17bb9533b4..46deebf2cdd 100644 --- a/src/tools/miri/Cargo.lock +++ b/src/tools/miri/Cargo.lock @@ -282,9 +282,9 @@ checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" [[package]] name = "libffi" -version = "3.0.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e454b3efb16fba3b17810ae5e41df02b649e564ab3c5a34b3b93ed07ad287e6" +checksum = "ce826c243048e3d5cec441799724de52e2d42f820468431fc3fceee2341871e2" dependencies = [ "libc", "libffi-sys", @@ -292,9 +292,9 @@ dependencies = [ [[package]] name = "libffi-sys" -version = "2.0.1" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84e78d02e5a8eae9c24c38ce6e6026f80e16dff76adcdae4bc5c6c52c2de4a60" +checksum = "dc65067b78c0fc069771e8b9a9e02df71e08858bec92c1f101377c67b9dca7c7" dependencies = [ "cc", ]