From 5907a8ca107100b387293f86d486fabdaa61ab31 Mon Sep 17 00:00:00 2001 From: Jacob Pratt Date: Sun, 14 Nov 2021 00:53:09 -0500 Subject: [PATCH 01/13] Fix incorrect feature flags --- library/core/src/num/saturating.rs | 2 +- library/core/src/num/uint_macros.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/num/saturating.rs b/library/core/src/num/saturating.rs index ba81f3f9fd6..d9b14c82e96 100644 --- a/library/core/src/num/saturating.rs +++ b/library/core/src/num/saturating.rs @@ -628,7 +628,7 @@ macro_rules! saturating_int_impl { /// ``` #[inline] #[unstable(feature = "saturating_int_impl", issue = "87920")] - #[rustc_const_stable(feature = "const_reverse_bits", since = "1.37.0")] + #[rustc_const_unstable(feature = "saturating_int_impl", issue = "87920")] #[must_use = "this returns the result of the operation, \ without modifying the original"] pub const fn reverse_bits(self) -> Self { diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs index a15eabf7966..054b814b7e0 100644 --- a/library/core/src/num/uint_macros.rs +++ b/library/core/src/num/uint_macros.rs @@ -2223,7 +2223,7 @@ macro_rules! uint_impl { /// ``` #[unstable(feature = "wrapping_next_power_of_two", issue = "32463", reason = "needs decision on wrapping behaviour")] - #[rustc_const_stable(feature = "const_int_pow", since = "1.50.0")] + #[rustc_const_unstable(feature = "wrapping_next_power_of_two", issue = "32463")] #[must_use = "this returns the result of the operation, \ without modifying the original"] pub const fn wrapping_next_power_of_two(self) -> Self { From 64cca297cb9028c5cfc6b9cb9ab82ed5129b0841 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Sun, 21 Nov 2021 11:57:38 +0100 Subject: [PATCH 02/13] Fix method name reference in stream documentation --- library/core/src/stream/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/core/src/stream/mod.rs b/library/core/src/stream/mod.rs index 58dc8e1e5e6..b59a46d5f3a 100644 --- a/library/core/src/stream/mod.rs +++ b/library/core/src/stream/mod.rs @@ -114,9 +114,9 @@ //! # Laziness //! //! Streams are *lazy*. This means that just creating a stream doesn't _do_ a -//! whole lot. Nothing really happens until you call `next`. This is sometimes a -//! source of confusion when creating a stream solely for its side effects. The -//! compiler will warn us about this kind of behavior: +//! whole lot. Nothing really happens until you call `poll_next`. This is +//! sometimes a source of confusion when creating a stream solely for its side +//! effects. The compiler will warn us about this kind of behavior: //! //! ```text //! warning: unused result that must be used: streams do nothing unless polled From 15a4ed693722b4bb6d2fa43272a58ab94acfec1a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 28 Nov 2021 13:48:53 -0500 Subject: [PATCH 03/13] adjust const_eval_select documentation --- library/core/src/intrinsics.rs | 41 +++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 23b28766d70..3814c4237f1 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -2271,19 +2271,40 @@ pub unsafe fn write_bytes(dst: *mut T, val: u8, count: usize) { /// /// # Safety /// -/// This intrinsic allows breaking [referential transparency] in `const fn` -/// and is therefore `unsafe`. +/// The two functions must behave observably equivalent. Safe code in other +/// crates may assume that calling a `const fn` at compile-time and at run-time +/// produces the same result. A function that produces a different result when +/// evaluated at run-time, or has any other observable side-effects, is +/// *unsound*. /// -/// Code that uses this intrinsic must be extremely careful to ensure that -/// `const fn`s remain referentially-transparent independently of when they -/// are evaluated. +/// Here is an example of how this could cause a problem: +/// ```no_run +/// #![feature(const_eval_select)] +/// use std::hint::unreachable_unchecked; +/// use std::intrinsics::const_eval_select; /// -/// The Rust compiler assumes that it is sound to replace a call to a `const -/// fn` with the result produced by evaluating it at compile-time. If -/// evaluating the function at run-time were to produce a different result, -/// or have any other observable side-effects, the behavior is undefined. +/// // Crate A +/// pub const fn inconsistent() -> i32 { +/// fn runtime() -> i32 { 1 } +/// const fn compiletime() -> i32 { 2 } /// -/// [referential transparency]: https://en.wikipedia.org/wiki/Referential_transparency +/// unsafe { +// // โš  This code violates the required equivalence of `compiletime` +/// // and `runtime`. +/// const_eval_select((), compiletime, runtime) +/// } +/// } +/// +/// // Crate B +/// const X: i32 = inconsistent(); +/// let x = inconsistent(); +/// if x != X { unsafe { unreachable_unchecked(); }} +/// ``` +/// +/// This code causes Undefined Behavior when being run, since the +/// `unreachable_unchecked` is actually being reached. The bug is in *crate A*, +/// which violates the principle that a `const fn` must behave the same at +/// compile-time and at run-time. The unsafe code in crate B is fine. #[unstable( feature = "const_eval_select", issue = "none", From 85558ad5b39d435d3c57e3e0df5f4c160ee0c6e3 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 28 Nov 2021 14:00:58 -0500 Subject: [PATCH 04/13] adjust some const_eval_select safety comments --- library/core/src/intrinsics.rs | 8 ++++---- library/core/src/slice/raw.rs | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 3814c4237f1..975dc593b51 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -2068,8 +2068,8 @@ pub const unsafe fn copy_nonoverlapping(src: *const T, dst: *mut T, count: us #[cfg(debug_assertions)] const fn compiletime_check(_src: *const T, _dst: *mut T, _count: usize) {} #[cfg(debug_assertions)] - // SAFETY: runtime debug-assertions are a best-effort basis; it's fine to - // not do them during compile time + // SAFETY: As per our safety precondition, we may assume that the `abort` above is never reached. + // Therefore, compiletime_check and runtime_check are observably equivalent. unsafe { const_eval_select((src, dst, count), compiletime_check, runtime_check); } @@ -2159,8 +2159,8 @@ pub const unsafe fn copy(src: *const T, dst: *mut T, count: usize) { #[cfg(debug_assertions)] const fn compiletime_check(_src: *const T, _dst: *mut T) {} #[cfg(debug_assertions)] - // SAFETY: runtime debug-assertions are a best-effort basis; it's fine to - // not do them during compile time + // SAFETY: As per our safety precondition, we may assume that the `abort` above is never reached. + // Therefore, compiletime_check and runtime_check are observably equivalent. unsafe { const_eval_select((src, dst), compiletime_check, runtime_check); } diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs index 81bb16d5401..a8667c3a8ca 100644 --- a/library/core/src/slice/raw.rs +++ b/library/core/src/slice/raw.rs @@ -149,8 +149,8 @@ const fn debug_check_data_len(data: *const T, len: usize) { // it is not required for safety (the safety must be guatanteed by // the `from_raw_parts[_mut]` caller). // - // Since the checks are not required, we ignore them in CTFE as they can't - // be done there (alignment does not make much sense there). + // As per our safety precondition, we may assume that assertion above never fails. + // Therefore, noop and rt_check are observably equivalent. unsafe { crate::intrinsics::const_eval_select((data,), noop, rt_check); } From 80a308df322d426a5f98b0fe4d888cc701a854c6 Mon Sep 17 00:00:00 2001 From: Joseph T Lyons Date: Thu, 2 Dec 2021 12:26:47 -0500 Subject: [PATCH 05/13] Use `HashMap::from()` instead of using `HashMap::new()` with `HashMap::insert()` --- library/std/src/collections/hash/map.rs | 123 ++++++++++++++---------- 1 file changed, 70 insertions(+), 53 deletions(-) diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index 12246b5173d..c585827b9eb 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -334,10 +334,11 @@ impl HashMap { /// ``` /// use std::collections::HashMap; /// - /// let mut map = HashMap::new(); - /// map.insert("a", 1); - /// map.insert("b", 2); - /// map.insert("c", 3); + /// let map = HashMap::from([ + /// ("a", 1), + /// ("b", 2), + /// ("c", 3), + /// ]); /// /// for key in map.keys() { /// println!("{}", key); @@ -356,10 +357,11 @@ impl HashMap { /// ``` /// use std::collections::HashMap; /// - /// let mut map = HashMap::new(); - /// map.insert("a", 1); - /// map.insert("b", 2); - /// map.insert("c", 3); + /// let map = HashMap::from([ + /// ("a", 1), + /// ("b", 2), + /// ("c", 3), + /// ]); /// /// for val in map.values() { /// println!("{}", val); @@ -378,11 +380,11 @@ impl HashMap { /// ``` /// use std::collections::HashMap; /// - /// let mut map = HashMap::new(); - /// - /// map.insert("a", 1); - /// map.insert("b", 2); - /// map.insert("c", 3); + /// let map = HashMap::from([ + /// ("a", 1), + /// ("b", 2), + /// ("c", 3), + /// ]); /// /// for val in map.values_mut() { /// *val = *val + 10; @@ -405,10 +407,11 @@ impl HashMap { /// ``` /// use std::collections::HashMap; /// - /// let mut map = HashMap::new(); - /// map.insert("a", 1); - /// map.insert("b", 2); - /// map.insert("c", 3); + /// let map = HashMap::from([ + /// ("a", 1), + /// ("b", 2), + /// ("c", 3), + /// ]); /// /// for (key, val) in map.iter() { /// println!("key: {} val: {}", key, val); @@ -428,10 +431,11 @@ impl HashMap { /// ``` /// use std::collections::HashMap; /// - /// let mut map = HashMap::new(); - /// map.insert("a", 1); - /// map.insert("b", 2); - /// map.insert("c", 3); + /// let map = HashMap::from([ + /// ("a", 1), + /// ("b", 2), + /// ("c", 3), + /// ]); /// /// // Update all values /// for (_, val) in map.iter_mut() { @@ -966,10 +970,11 @@ where /// ``` /// use std::collections::HashMap; /// - /// let mut map = HashMap::new(); - /// map.insert("a", 1); - /// map.insert("b", 2); - /// map.insert("c", 3); + /// let map = HashMap::from([ + /// ("a", 1), + /// ("b", 2), + /// ("c", 3), + /// ]); /// /// let mut vec: Vec<&str> = map.into_keys().collect(); /// // The `IntoKeys` iterator produces keys in arbitrary order, so the @@ -992,10 +997,11 @@ where /// ``` /// use std::collections::HashMap; /// - /// let mut map = HashMap::new(); - /// map.insert("a", 1); - /// map.insert("b", 2); - /// map.insert("c", 3); + /// let map = HashMap::from([ + /// ("a", 1), + /// ("b", 2), + /// ("c", 3), + /// ]); /// /// let mut vec: Vec = map.into_values().collect(); /// // The `IntoValues` iterator produces values in arbitrary order, so @@ -1202,8 +1208,9 @@ where /// ``` /// use std::collections::HashMap; /// -/// let mut map = HashMap::new(); -/// map.insert("a", 1); +/// let map = HashMap::from([ +/// ("a", 1), +/// ]); /// let iter = map.iter(); /// ``` #[stable(feature = "rust1", since = "1.0.0")] @@ -1239,8 +1246,9 @@ impl fmt::Debug for Iter<'_, K, V> { /// ``` /// use std::collections::HashMap; /// -/// let mut map = HashMap::new(); -/// map.insert("a", 1); +/// let map = HashMap::from([ +/// ("a", 1), +/// ]); /// let iter = map.iter_mut(); /// ``` #[stable(feature = "rust1", since = "1.0.0")] @@ -1269,8 +1277,9 @@ impl<'a, K, V> IterMut<'a, K, V> { /// ``` /// use std::collections::HashMap; /// -/// let mut map = HashMap::new(); -/// map.insert("a", 1); +/// let map = HashMap::from([ +/// ("a", 1), +/// ]); /// let iter = map.into_iter(); /// ``` #[stable(feature = "rust1", since = "1.0.0")] @@ -1298,8 +1307,9 @@ impl IntoIter { /// ``` /// use std::collections::HashMap; /// -/// let mut map = HashMap::new(); -/// map.insert("a", 1); +/// let map = HashMap::from([ +/// ("a", 1), +/// ]); /// let iter_keys = map.keys(); /// ``` #[stable(feature = "rust1", since = "1.0.0")] @@ -1335,8 +1345,9 @@ impl fmt::Debug for Keys<'_, K, V> { /// ``` /// use std::collections::HashMap; /// -/// let mut map = HashMap::new(); -/// map.insert("a", 1); +/// let map = HashMap::from([ +/// ("a", 1), +/// ]); /// let iter_values = map.values(); /// ``` #[stable(feature = "rust1", since = "1.0.0")] @@ -1372,8 +1383,9 @@ impl fmt::Debug for Values<'_, K, V> { /// ``` /// use std::collections::HashMap; /// -/// let mut map = HashMap::new(); -/// map.insert("a", 1); +/// let map = HashMap::from([ +/// ("a", 1), +/// ]); /// let iter = map.drain(); /// ``` #[stable(feature = "drain", since = "1.6.0")] @@ -1402,8 +1414,9 @@ impl<'a, K, V> Drain<'a, K, V> { /// /// use std::collections::HashMap; /// -/// let mut map = HashMap::new(); -/// map.insert("a", 1); +/// let map = HashMap::from([ +/// ("a", 1), +/// ]); /// let iter = map.drain_filter(|_k, v| *v % 2 == 0); /// ``` #[unstable(feature = "hash_drain_filter", issue = "59618")] @@ -1426,8 +1439,9 @@ where /// ``` /// use std::collections::HashMap; /// -/// let mut map = HashMap::new(); -/// map.insert("a", 1); +/// let map = HashMap::from([ +/// ("a", 1), +/// ]); /// let iter_values = map.values_mut(); /// ``` #[stable(feature = "map_values_mut", since = "1.10.0")] @@ -1447,8 +1461,9 @@ pub struct ValuesMut<'a, K: 'a, V: 'a> { /// ``` /// use std::collections::HashMap; /// -/// let mut map = HashMap::new(); -/// map.insert("a", 1); +/// let map = HashMap::from([ +/// ("a", 1), +/// ]); /// let iter_keys = map.into_keys(); /// ``` #[stable(feature = "map_into_keys_values", since = "1.54.0")] @@ -1468,8 +1483,9 @@ pub struct IntoKeys { /// ``` /// use std::collections::HashMap; /// -/// let mut map = HashMap::new(); -/// map.insert("a", 1); +/// let map = HashMap::from([ +/// ("a", 1), +/// ]); /// let iter_keys = map.into_values(); /// ``` #[stable(feature = "map_into_keys_values", since = "1.54.0")] @@ -2004,10 +2020,11 @@ impl IntoIterator for HashMap { /// ``` /// use std::collections::HashMap; /// - /// let mut map = HashMap::new(); - /// map.insert("a", 1); - /// map.insert("b", 2); - /// map.insert("c", 3); + /// let map = HashMap::from([ + /// ("a", 1), + /// ("b", 2), + /// ("c", 3), + /// ]); /// /// // Not possible with .iter() /// let vec: Vec<(&str, i32)> = map.into_iter().collect(); From 440cffd551ef6040253e79e350d585cbd1471140 Mon Sep 17 00:00:00 2001 From: Joseph T Lyons Date: Thu, 2 Dec 2021 12:27:23 -0500 Subject: [PATCH 06/13] Use `BTreeMap::from()` instead of using `BTreeMap::new()` with `BTreeMap::insert()` --- library/alloc/src/collections/btree/map.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 2ff7b0fbb75..f771c186e9a 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -2107,10 +2107,11 @@ impl BTreeMap { /// ``` /// use std::collections::BTreeMap; /// - /// let mut map = BTreeMap::new(); - /// map.insert("a", 1); - /// map.insert("b", 2); - /// map.insert("c", 3); + /// let mut map = BTreeMap::from([ + /// ("a", 1), + /// ("b", 2), + /// ("c", 3), + /// ]); /// /// // add 10 to the value if the key isn't "a" /// for (key, value) in map.iter_mut() { From 72a6974e455793f9dcc370cc8bdf9c055b843d39 Mon Sep 17 00:00:00 2001 From: Joseph T Lyons Date: Fri, 3 Dec 2021 00:14:55 -0500 Subject: [PATCH 07/13] Make `HashMap`s mutable again --- library/std/src/collections/hash/map.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index c585827b9eb..fa597cfba6c 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -380,7 +380,7 @@ impl HashMap { /// ``` /// use std::collections::HashMap; /// - /// let map = HashMap::from([ + /// let mut map = HashMap::from([ /// ("a", 1), /// ("b", 2), /// ("c", 3), @@ -431,7 +431,7 @@ impl HashMap { /// ``` /// use std::collections::HashMap; /// - /// let map = HashMap::from([ + /// let mut map = HashMap::from([ /// ("a", 1), /// ("b", 2), /// ("c", 3), @@ -1246,7 +1246,7 @@ impl fmt::Debug for Iter<'_, K, V> { /// ``` /// use std::collections::HashMap; /// -/// let map = HashMap::from([ +/// let mut map = HashMap::from([ /// ("a", 1), /// ]); /// let iter = map.iter_mut(); @@ -1383,7 +1383,7 @@ impl fmt::Debug for Values<'_, K, V> { /// ``` /// use std::collections::HashMap; /// -/// let map = HashMap::from([ +/// let mut map = HashMap::from([ /// ("a", 1), /// ]); /// let iter = map.drain(); @@ -1414,7 +1414,7 @@ impl<'a, K, V> Drain<'a, K, V> { /// /// use std::collections::HashMap; /// -/// let map = HashMap::from([ +/// let mut map = HashMap::from([ /// ("a", 1), /// ]); /// let iter = map.drain_filter(|_k, v| *v % 2 == 0); @@ -1439,7 +1439,7 @@ where /// ``` /// use std::collections::HashMap; /// -/// let map = HashMap::from([ +/// let mut map = HashMap::from([ /// ("a", 1), /// ]); /// let iter_values = map.values_mut(); From d5f6b9c8c228689026aedc7e6e2cc13294f1020f Mon Sep 17 00:00:00 2001 From: Wesley Wiser Date: Thu, 2 Dec 2021 16:16:34 -0500 Subject: [PATCH 08/13] code-cov: generate dead functions with private/default linkage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As discovered in #85461, the MSVC linker treats weak symbols slightly differently than unix-y linkers do. This causes link.exe to fail with LNK1227 "conflicting weak extern definition" where as other targets are able to link successfully. This changes the dead functions from being generated as weak/hidden to private/default which, as the LLVM reference says: > Global values with โ€œprivateโ€ linkage are only directly accessible by objects in the current module. In particular, linking code into a module with a private global value may cause the private to be renamed as necessary to avoid collisions. Because the symbol is private to the module, all references can be updated. This doesnโ€™t show up in any symbol table in the object file. This fixes the conflicting weak symbols but doesn't address the reason *why* we have conflicting symbols for these dead functions. The test cases added in this commit contain a minimal repro of the fundamental issue which is that the logic used to decide what dead code functions should be codegen'd in the current CGU doesn't take into account that functions can be duplicated across multiple CGUs (for instance, in the case of `#[inline(always)]` functions). Fixing that is likely to be a more complex change (see https://github.com/rust-lang/rust/issues/85461#issuecomment-985005805). Fixes #85461 --- .../src/coverageinfo/mod.rs | 4 +-- .../expected_show_coverage.issue-85461.txt | 36 +++++++++++++++++++ .../run-make-fulldeps/coverage/issue-85461.rs | 10 ++++++ .../lib/inline_always_with_dead_code.rs | 22 ++++++++++++ src/test/ui/issues/issue-85461.rs | 27 ++++++++++++++ 5 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.issue-85461.txt create mode 100644 src/test/run-make-fulldeps/coverage/issue-85461.rs create mode 100644 src/test/run-make-fulldeps/coverage/lib/inline_always_with_dead_code.rs create mode 100644 src/test/ui/issues/issue-85461.rs diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs index ef11e2972ea..96b278dbe32 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs @@ -212,8 +212,8 @@ fn declare_unused_fn(cx: &CodegenCx<'ll, 'tcx>, def_id: &DefId) -> Instance<'tcx ), ); - llvm::set_linkage(llfn, llvm::Linkage::WeakAnyLinkage); - llvm::set_visibility(llfn, llvm::Visibility::Hidden); + llvm::set_linkage(llfn, llvm::Linkage::PrivateLinkage); + llvm::set_visibility(llfn, llvm::Visibility::Default); assert!(cx.instances.borrow_mut().insert(instance, llfn).is_none()); diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.issue-85461.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.issue-85461.txt new file mode 100644 index 00000000000..2831e9b532a --- /dev/null +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.issue-85461.txt @@ -0,0 +1,36 @@ +../coverage/issue-85461.rs: + 1| |// Regression test for #85461: MSVC sometimes fail to link with dead code and #[inline(always)] + 2| | + 3| |extern crate inline_always_with_dead_code; + 4| | + 5| |use inline_always_with_dead_code::{bar, baz}; + 6| | + 7| 1|fn main() { + 8| 1| bar::call_me(); + 9| 1| baz::call_me(); + 10| 1|} + +../coverage/lib/inline_always_with_dead_code.rs: + 1| |// compile-flags: -Zinstrument-coverage -Ccodegen-units=4 -Copt-level=0 + 2| | + 3| |#![allow(dead_code)] + 4| | + 5| |mod foo { + 6| | #[inline(always)] + 7| 2| pub fn called() { } + 8| | + 9| 0| fn uncalled() { } + 10| |} + 11| | + 12| |pub mod bar { + 13| 1| pub fn call_me() { + 14| 1| super::foo::called(); + 15| 1| } + 16| |} + 17| | + 18| |pub mod baz { + 19| 1| pub fn call_me() { + 20| 1| super::foo::called(); + 21| 1| } + 22| |} + diff --git a/src/test/run-make-fulldeps/coverage/issue-85461.rs b/src/test/run-make-fulldeps/coverage/issue-85461.rs new file mode 100644 index 00000000000..a1b9ebb1ed3 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage/issue-85461.rs @@ -0,0 +1,10 @@ +// Regression test for #85461: MSVC sometimes fail to link with dead code and #[inline(always)] + +extern crate inline_always_with_dead_code; + +use inline_always_with_dead_code::{bar, baz}; + +fn main() { + bar::call_me(); + baz::call_me(); +} diff --git a/src/test/run-make-fulldeps/coverage/lib/inline_always_with_dead_code.rs b/src/test/run-make-fulldeps/coverage/lib/inline_always_with_dead_code.rs new file mode 100644 index 00000000000..b567916aea0 --- /dev/null +++ b/src/test/run-make-fulldeps/coverage/lib/inline_always_with_dead_code.rs @@ -0,0 +1,22 @@ +// compile-flags: -Zinstrument-coverage -Ccodegen-units=4 -Copt-level=0 + +#![allow(dead_code)] + +mod foo { + #[inline(always)] + pub fn called() { } + + fn uncalled() { } +} + +pub mod bar { + pub fn call_me() { + super::foo::called(); + } +} + +pub mod baz { + pub fn call_me() { + super::foo::called(); + } +} diff --git a/src/test/ui/issues/issue-85461.rs b/src/test/ui/issues/issue-85461.rs new file mode 100644 index 00000000000..4c6c83f2612 --- /dev/null +++ b/src/test/ui/issues/issue-85461.rs @@ -0,0 +1,27 @@ +// compile-flags: -Zinstrument-coverage -Ccodegen-units=4 --crate-type dylib -Copt-level=0 +// build-pass +// needs-profiler-support + +// Regression test for #85461 where MSVC sometimes fails to link instrument-coverage binaries +// with dead code and #[inline(always)]. + +#![allow(dead_code)] + +mod foo { + #[inline(always)] + pub fn called() { } + + fn uncalled() { } +} + +pub mod bar { + pub fn call_me() { + super::foo::called(); + } +} + +pub mod baz { + pub fn call_me() { + super::foo::called(); + } +} From 8bfc76dd6241aa7da0bc6660f0651e17092f8c93 Mon Sep 17 00:00:00 2001 From: Lucas Kent Date: Sun, 5 Dec 2021 01:22:49 +1100 Subject: [PATCH 09/13] Fix Vec::extend_from_slice docs --- library/alloc/src/vec/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 88bde6e8ce4..af26a5b5998 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2199,7 +2199,7 @@ impl Vec { /// Clones and appends all elements in a slice to the `Vec`. /// /// Iterates over the slice `other`, clones each element, and then appends - /// it to this `Vec`. The `other` vector is traversed in-order. + /// it to this `Vec`. The `other` slice is traversed in-order. /// /// Note that this function is same as [`extend`] except that it is /// specialized to work with slices instead. If and when Rust gets From 41f76924d06ad4b267c0c1e5c83acf666c07f34e Mon Sep 17 00:00:00 2001 From: pierwill Date: Fri, 29 Oct 2021 12:14:17 -0500 Subject: [PATCH 10/13] Document all public items in `rustc_incremental` Also: - Review and edit current docs - Enforce documentation for crate Co-authored-by: r00ster Co-authored-by: Camille Gillot --- .../rustc_incremental/src/assert_dep_graph.rs | 2 ++ .../src/assert_module_sources.rs | 1 + compiler/rustc_incremental/src/lib.rs | 1 + compiler/rustc_incremental/src/persist/fs.rs | 34 ++++++++++++++----- .../rustc_incremental/src/persist/load.rs | 17 ++++++++-- .../rustc_incremental/src/persist/save.rs | 15 ++++++-- .../src/persist/work_product.rs | 6 +++- 7 files changed, 63 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_incremental/src/assert_dep_graph.rs b/compiler/rustc_incremental/src/assert_dep_graph.rs index 571337a8dcb..7b5b015d5a5 100644 --- a/compiler/rustc_incremental/src/assert_dep_graph.rs +++ b/compiler/rustc_incremental/src/assert_dep_graph.rs @@ -52,6 +52,7 @@ use std::env; use std::fs::{self, File}; use std::io::{BufWriter, Write}; +#[allow(missing_docs)] pub fn assert_dep_graph(tcx: TyCtxt<'_>) { tcx.dep_graph.with_ignore(|| { if tcx.sess.opts.debugging_opts.dump_dep_graph { @@ -262,6 +263,7 @@ fn dump_graph(query: &DepGraphQuery) { } } +#[allow(missing_docs)] pub struct GraphvizDepGraph<'q>(FxHashSet<&'q DepNode>, Vec<(&'q DepNode, &'q DepNode)>); impl<'a, 'q> dot::GraphWalk<'a> for GraphvizDepGraph<'q> { diff --git a/compiler/rustc_incremental/src/assert_module_sources.rs b/compiler/rustc_incremental/src/assert_module_sources.rs index a5f3e4553ce..2cf8f9b08e1 100644 --- a/compiler/rustc_incremental/src/assert_module_sources.rs +++ b/compiler/rustc_incremental/src/assert_module_sources.rs @@ -29,6 +29,7 @@ use rustc_session::cgu_reuse_tracker::*; use rustc_span::symbol::{sym, Symbol}; use std::collections::BTreeSet; +#[allow(missing_docs)] pub fn assert_module_sources(tcx: TyCtxt<'_>) { tcx.dep_graph.with_ignore(|| { if tcx.sess.opts.incremental.is_none() { diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs index dd3f8c937f8..07e9f8b00ca 100644 --- a/compiler/rustc_incremental/src/lib.rs +++ b/compiler/rustc_incremental/src/lib.rs @@ -1,5 +1,6 @@ //! Support for serializing the dep-graph and reloading it. +#![deny(missing_docs)] #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(in_band_lifetimes)] #![feature(let_else)] diff --git a/compiler/rustc_incremental/src/persist/fs.rs b/compiler/rustc_incremental/src/persist/fs.rs index c0137fc7a5a..a49a1554d5b 100644 --- a/compiler/rustc_incremental/src/persist/fs.rs +++ b/compiler/rustc_incremental/src/persist/fs.rs @@ -133,21 +133,26 @@ const QUERY_CACHE_FILENAME: &str = "query-cache.bin"; // case-sensitive (as opposed to base64, for example). const INT_ENCODE_BASE: usize = base_n::CASE_INSENSITIVE; +/// Returns the path to a session's dependency graph. pub fn dep_graph_path(sess: &Session) -> PathBuf { in_incr_comp_dir_sess(sess, DEP_GRAPH_FILENAME) } +/// Returns the path to a session's staging dependency graph. +/// +/// On the difference between dep-graph and staging dep-graph, +/// see `build_dep_graph`. pub fn staging_dep_graph_path(sess: &Session) -> PathBuf { in_incr_comp_dir_sess(sess, STAGING_DEP_GRAPH_FILENAME) } - pub fn work_products_path(sess: &Session) -> PathBuf { in_incr_comp_dir_sess(sess, WORK_PRODUCTS_FILENAME) } - +/// Returns the path to a session's query cache. pub fn query_cache_path(sess: &Session) -> PathBuf { in_incr_comp_dir_sess(sess, QUERY_CACHE_FILENAME) } +/// Locks a given session directory. pub fn lock_file_path(session_dir: &Path) -> PathBuf { let crate_dir = session_dir.parent().unwrap(); @@ -166,23 +171,35 @@ pub fn lock_file_path(session_dir: &Path) -> PathBuf { crate_dir.join(&directory_name[0..dash_indices[2]]).with_extension(&LOCK_FILE_EXT[1..]) } +/// Returns the path for a given filename within the incremental compilation directory +/// in the current session. pub fn in_incr_comp_dir_sess(sess: &Session, file_name: &str) -> PathBuf { in_incr_comp_dir(&sess.incr_comp_session_dir(), file_name) } +/// Returns the path for a given filename within the incremental compilation directory, +/// not necessarily from the current session. +/// +/// To ensure the file is part of the current session, use [`in_incr_comp_dir_sess`]. pub fn in_incr_comp_dir(incr_comp_session_dir: &Path, file_name: &str) -> PathBuf { incr_comp_session_dir.join(file_name) } -/// Allocates the private session directory. The boolean in the Ok() result -/// indicates whether we should try loading a dep graph from the successfully -/// initialized directory, or not. -/// The post-condition of this fn is that we have a valid incremental -/// compilation session directory, if the result is `Ok`. A valid session +/// Allocates the private session directory. +/// +/// If the result of this function is `Ok`, we have a valid incremental +/// compilation session directory. A valid session /// directory is one that contains a locked lock file. It may or may not contain /// a dep-graph and work products from a previous session. -/// If the call fails, the fn may leave behind an invalid session directory. +/// +/// This always attempts to load a dep-graph from the directory. +/// If loading fails for some reason, we fallback to a disabled `DepGraph`. +/// See [`rustc_interface::queries::dep_graph`]. +/// +/// If this function returns an error, it may leave behind an invalid session directory. /// The garbage collection will take care of it. +/// +/// [`rustc_interface::queries::dep_graph`]: ../../rustc_interface/struct.Queries.html#structfield.dep_graph pub fn prepare_session_directory( sess: &Session, crate_name: &str, @@ -661,6 +678,7 @@ fn is_old_enough_to_be_collected(timestamp: SystemTime) -> bool { timestamp < SystemTime::now() - Duration::from_secs(10) } +/// Runs garbage collection for the current session. pub fn garbage_collect_session_directories(sess: &Session) -> io::Result<()> { debug!("garbage_collect_session_directories() - begin"); diff --git a/compiler/rustc_incremental/src/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs index 9c6e2aeb50a..9cae4e91818 100644 --- a/compiler/rustc_incremental/src/persist/load.rs +++ b/compiler/rustc_incremental/src/persist/load.rs @@ -18,13 +18,24 @@ use super::work_product; type WorkProductMap = FxHashMap; #[derive(Debug)] +/// Represents the result of an attempt to load incremental compilation data. pub enum LoadResult { - Ok { data: T }, + /// Loading was successful. + Ok { + #[allow(missing_docs)] + data: T, + }, + /// The file either didn't exist or was produced by an incompatible compiler version. DataOutOfDate, - Error { message: String }, + /// An error occured. + Error { + #[allow(missing_docs)] + message: String, + }, } impl LoadResult { + /// Accesses the data returned in [`LoadResult::Ok`]. pub fn open(self, sess: &Session) -> T { // Check for errors when using `-Zassert-incremental-state` match (sess.opts.assert_incr_state, &self) { @@ -99,6 +110,7 @@ pub enum MaybeAsync { } impl MaybeAsync> { + /// Accesses the data returned in [`LoadResult::Ok`] in an asynchronous way if possible. pub fn open(self) -> LoadResult { match self { MaybeAsync::Sync(result) => result, @@ -109,6 +121,7 @@ impl MaybeAsync> { } } +/// An asynchronous type for computing the dependency graph. pub type DepGraphFuture = MaybeAsync>; /// Launch a thread and load the dependency graph in the background. diff --git a/compiler/rustc_incremental/src/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs index 6c683058b12..9601a49267f 100644 --- a/compiler/rustc_incremental/src/persist/save.rs +++ b/compiler/rustc_incremental/src/persist/save.rs @@ -13,9 +13,13 @@ use super::file_format; use super::fs::*; use super::work_product; -/// Save and dump the DepGraph. +/// Saves and writes the [`DepGraph`] to the file system. /// -/// No query must be invoked after this function. +/// This function saves both the dep-graph and the query result cache, +/// and drops the result cache. +/// +/// This function should only run after all queries have completed. +/// Trying to execute a query afterwards would attempt to read the result cache we just dropped. pub fn save_dep_graph(tcx: TyCtxt<'_>) { debug!("save_dep_graph()"); tcx.dep_graph.with_ignore(|| { @@ -75,6 +79,7 @@ pub fn save_dep_graph(tcx: TyCtxt<'_>) { }) } +/// Saves the work product index. pub fn save_work_product_index( sess: &Session, dep_graph: &DepGraph, @@ -139,6 +144,12 @@ fn encode_query_cache(tcx: TyCtxt<'_>, encoder: &mut FileEncoder) -> FileEncodeR tcx.sess.time("incr_comp_serialize_result_cache", || tcx.serialize_query_result_cache(encoder)) } +/// Builds the dependency graph. +/// +/// This function breates the *staging dep-graph*. When the dep-graph is modified by a query +/// execution, the new dependency information is not kept in memory but directly +/// output to this file. `save_dep_graph` then finalizes the staging dep-graph +/// and moves it to the permanent dep-graph path pub fn build_dep_graph( sess: &Session, prev_graph: SerializedDepGraph, diff --git a/compiler/rustc_incremental/src/persist/work_product.rs b/compiler/rustc_incremental/src/persist/work_product.rs index 19d64bda56d..85b44ed7531 100644 --- a/compiler/rustc_incremental/src/persist/work_product.rs +++ b/compiler/rustc_incremental/src/persist/work_product.rs @@ -1,4 +1,6 @@ -//! This module contains files for saving intermediate work-products. +//! Functions for saving and removing intermediate [work products]. +//! +//! [work products]: WorkProduct use crate::persist::fs::*; use rustc_fs_util::link_or_copy; @@ -7,6 +9,7 @@ use rustc_session::Session; use std::fs as std_fs; use std::path::PathBuf; +/// Copies a CGU work product to the incremental compilation directory, so next compilation can find and reuse it. pub fn copy_cgu_workproduct_to_incr_comp_cache_dir( sess: &Session, cgu_name: &str, @@ -40,6 +43,7 @@ pub fn copy_cgu_workproduct_to_incr_comp_cache_dir( Some((work_product_id, work_product)) } +/// Removes files for a given work product. pub fn delete_workproduct_files(sess: &Session, work_product: &WorkProduct) { if let Some(ref file_name) = work_product.saved_file { let path = in_incr_comp_dir_sess(sess, file_name); From d9e45026b3589779c2b0879fe58e273fcf56a891 Mon Sep 17 00:00:00 2001 From: Ibraheem Ahmed Date: Tue, 7 Dec 2021 23:25:44 -0500 Subject: [PATCH 11/13] fix documentation for `core::ready::Ready` --- library/core/src/future/ready.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/future/ready.rs b/library/core/src/future/ready.rs index cc905d288f9..48f20f90a32 100644 --- a/library/core/src/future/ready.rs +++ b/library/core/src/future/ready.rs @@ -2,7 +2,7 @@ use crate::future::Future; use crate::pin::Pin; use crate::task::{Context, Poll}; -/// Creates a future that is immediately ready with a value. +/// A future that is immediately ready with a value. /// /// This `struct` is created by [`ready()`]. See its /// documentation for more. From 15de4cbc4b49be2fbf082fe02f877d5f774569a5 Mon Sep 17 00:00:00 2001 From: est31 Date: Fri, 3 Dec 2021 03:06:36 +0100 Subject: [PATCH 12/13] Remove redundant [..]s --- compiler/rustc_ast/src/util/literal.rs | 2 +- compiler/rustc_ast_passes/src/feature_gate.rs | 6 ++-- compiler/rustc_ast_pretty/src/pprust/state.rs | 28 +++++++-------- compiler/rustc_builtin_macros/src/asm.rs | 2 +- .../src/deriving/generic/mod.rs | 20 +++++------ compiler/rustc_builtin_macros/src/format.rs | 2 +- compiler/rustc_codegen_gcc/src/back/write.rs | 4 +-- compiler/rustc_codegen_llvm/src/asm.rs | 2 +- compiler/rustc_codegen_llvm/src/back/lto.rs | 2 +- compiler/rustc_codegen_llvm/src/back/write.rs | 36 +++++++++---------- compiler/rustc_codegen_llvm/src/common.rs | 2 +- compiler/rustc_codegen_llvm/src/consts.rs | 2 +- .../src/coverageinfo/mapgen.rs | 4 +-- .../src/debuginfo/metadata.rs | 8 ++--- .../rustc_codegen_llvm/src/debuginfo/mod.rs | 2 +- compiler/rustc_codegen_ssa/src/back/write.rs | 4 +-- compiler/rustc_codegen_ssa/src/common.rs | 4 +-- .../src/interpret/terminator.rs | 2 +- .../rustc_data_structures/src/fingerprint.rs | 4 +-- .../rustc_data_structures/src/profiling.rs | 2 +- .../rustc_data_structures/src/small_c_str.rs | 2 +- compiler/rustc_expand/src/mbe/macro_rules.rs | 10 +++--- compiler/rustc_expand/src/mbe/transcribe.rs | 4 +-- compiler/rustc_graphviz/src/lib.rs | 4 +-- compiler/rustc_hir_pretty/src/lib.rs | 12 +++---- .../rustc_incremental/src/persist/load.rs | 2 +- compiler/rustc_lint/src/non_fmt_panic.rs | 2 +- compiler/rustc_metadata/src/native_libs.rs | 2 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 2 +- compiler/rustc_middle/src/mir/mono.rs | 2 +- compiler/rustc_middle/src/mir/terminator.rs | 4 +-- compiler/rustc_middle/src/traits/mod.rs | 18 +++++----- .../rustc_parse/src/parser/diagnostics.rs | 6 ++-- .../rustc_query_impl/src/on_disk_cache.rs | 2 +- compiler/rustc_session/src/config.rs | 6 ++-- compiler/rustc_span/src/lib.rs | 4 +-- .../error_reporting/on_unimplemented.rs | 2 +- .../src/traits/error_reporting/suggestions.rs | 4 +-- compiler/rustc_typeck/src/astconv/mod.rs | 2 +- compiler/rustc_typeck/src/check/callee.rs | 2 +- .../rustc_typeck/src/check/fn_ctxt/_impl.rs | 2 +- .../rustc_typeck/src/check/fn_ctxt/checks.rs | 6 ++-- .../rustc_typeck/src/check/method/probe.rs | 2 +- .../rustc_typeck/src/check/method/suggest.rs | 2 +- compiler/rustc_typeck/src/collect.rs | 8 ++--- 45 files changed, 123 insertions(+), 127 deletions(-) diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs index 9c6ad47427d..8a41aec0819 100644 --- a/compiler/rustc_ast/src/util/literal.rs +++ b/compiler/rustc_ast/src/util/literal.rs @@ -57,7 +57,7 @@ impl LitKind { // string in the token. let s = symbol.as_str(); let symbol = - if s.contains(&['\\', '\r'][..]) { + if s.contains(&['\\', '\r']) { let mut buf = String::with_capacity(s.len()); let mut error = Ok(()); unescape_literal(&s, Mode::Str, &mut |_, unescaped_char| { diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index ad539f2564d..5eaec79c4ed 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -347,7 +347,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { if let Some(modifiers) = nested_meta.value_str() { for modifier in modifiers.as_str().split(',') { - if let Some(modifier) = modifier.strip_prefix(&['+', '-'][..]) { + if let Some(modifier) = modifier.strip_prefix(&['+', '-']) { macro_rules! gate_modifier { ($($name:literal => $feature:ident)*) => { $(if modifier == $name { let msg = concat!("`#[link(modifiers=\"", $name, "\")]` is unstable"); @@ -383,7 +383,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } ast::ItemKind::Fn(..) => { - if self.sess.contains_name(&i.attrs[..], sym::start) { + if self.sess.contains_name(&i.attrs, sym::start) { gate_feature_post!( &self, start, @@ -396,7 +396,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } ast::ItemKind::Struct(..) => { - for attr in self.sess.filter_by_name(&i.attrs[..], sym::repr) { + for attr in self.sess.filter_by_name(&i.attrs, sym::repr) { for item in attr.meta_item_list().unwrap_or_else(Vec::new) { if item.has_name(sym::simd) { gate_feature_post!( diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 74f2a2b2e09..5167e0a5292 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -499,7 +499,7 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere ast::MetaItemKind::List(ref items) => { self.print_path(&item.path, false, 0); self.popen(); - self.commasep(Consistent, &items[..], |s, i| s.print_meta_list_item(i)); + self.commasep(Consistent, &items, |s, i| s.print_meta_list_item(i)); self.pclose(); } } @@ -997,7 +997,7 @@ impl<'a> State<'a> { } ast::TyKind::Tup(ref elts) => { self.popen(); - self.commasep(Inconsistent, &elts[..], |s, ty| s.print_type(ty)); + self.commasep(Inconsistent, &elts, |s, ty| s.print_type(ty)); if elts.len() == 1 { self.word(","); } @@ -1017,10 +1017,10 @@ impl<'a> State<'a> { ast::TyKind::Path(Some(ref qself), ref path) => self.print_qpath(path, qself, false), ast::TyKind::TraitObject(ref bounds, syntax) => { let prefix = if syntax == ast::TraitObjectSyntax::Dyn { "dyn" } else { "" }; - self.print_type_bounds(prefix, &bounds[..]); + self.print_type_bounds(prefix, &bounds); } ast::TyKind::ImplTrait(_, ref bounds) => { - self.print_type_bounds("impl", &bounds[..]); + self.print_type_bounds("impl", &bounds); } ast::TyKind::Array(ref ty, ref length) => { self.word("["); @@ -1339,7 +1339,7 @@ impl<'a> State<'a> { real_bounds.push(b.clone()); } } - self.print_type_bounds(":", &real_bounds[..]); + self.print_type_bounds(":", &real_bounds); self.print_where_clause(&generics.where_clause); self.word(" "); self.bopen(); @@ -1368,7 +1368,7 @@ impl<'a> State<'a> { } } self.nbsp(); - self.print_type_bounds("=", &real_bounds[..]); + self.print_type_bounds("=", &real_bounds); self.print_where_clause(&generics.where_clause); self.word(";"); } @@ -1960,10 +1960,10 @@ impl<'a> State<'a> { self.print_expr_tup(exprs); } ast::ExprKind::Call(ref func, ref args) => { - self.print_expr_call(func, &args[..]); + self.print_expr_call(func, &args); } ast::ExprKind::MethodCall(ref segment, ref args, _) => { - self.print_expr_method_call(segment, &args[..]); + self.print_expr_method_call(segment, &args); } ast::ExprKind::Binary(op, ref lhs, ref rhs) => { self.print_expr_binary(op, lhs, rhs); @@ -2442,11 +2442,11 @@ impl<'a> State<'a> { self.print_path(path, true, 0); } self.popen(); - self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(p)); + self.commasep(Inconsistent, &elts, |s, p| s.print_pat(p)); self.pclose(); } PatKind::Or(ref pats) => { - self.strsep("|", true, Inconsistent, &pats[..], |s, p| s.print_pat(p)); + self.strsep("|", true, Inconsistent, &pats, |s, p| s.print_pat(p)); } PatKind::Path(None, ref path) => { self.print_path(path, true, 0); @@ -2464,7 +2464,7 @@ impl<'a> State<'a> { self.word_space("{"); self.commasep_cmnt( Consistent, - &fields[..], + &fields, |s, f| { s.cbox(INDENT_UNIT); if !f.is_shorthand { @@ -2487,7 +2487,7 @@ impl<'a> State<'a> { } PatKind::Tuple(ref elts) => { self.popen(); - self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(p)); + self.commasep(Inconsistent, &elts, |s, p| s.print_pat(p)); if elts.len() == 1 { self.word(","); } @@ -2529,7 +2529,7 @@ impl<'a> State<'a> { } PatKind::Slice(ref elts) => { self.word("["); - self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(p)); + self.commasep(Inconsistent, &elts, |s, p| s.print_pat(p)); self.word("]"); } PatKind::Rest => self.word(".."), @@ -2838,7 +2838,7 @@ impl<'a> State<'a> { self.print_path(&tree.prefix, false, 0); self.word("::{"); } - self.commasep(Inconsistent, &items[..], |this, &(ref tree, _)| { + self.commasep(Inconsistent, &items, |this, &(ref tree, _)| { this.print_use_tree(tree) }); self.word("}"); diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index b374769cbea..9ae1584fcbf 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -712,7 +712,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option Some(idx), None => { let msg = format!("there is no argument named `{}`", name); - ecx.struct_span_err(span, &msg[..]).emit(); + ecx.struct_span_err(span, &msg).emit(); None } }, diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 1427a2aada3..985c45e2253 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -766,8 +766,8 @@ impl<'a> TraitDef<'a> { self, struct_def, type_ident, - &self_args[..], - &nonself_args[..], + &self_args, + &nonself_args, ) } else { method_def.expand_struct_method_body( @@ -775,8 +775,8 @@ impl<'a> TraitDef<'a> { self, struct_def, type_ident, - &self_args[..], - &nonself_args[..], + &self_args, + &nonself_args, use_temporaries, ) }; @@ -815,8 +815,8 @@ impl<'a> TraitDef<'a> { self, enum_def, type_ident, - &self_args[..], - &nonself_args[..], + &self_args, + &nonself_args, ) } else { method_def.expand_enum_method_body( @@ -825,7 +825,7 @@ impl<'a> TraitDef<'a> { enum_def, type_ident, self_args, - &nonself_args[..], + &nonself_args, ) }; @@ -1217,7 +1217,7 @@ impl<'a> MethodDef<'a> { let vi_idents = self_arg_names .iter() .map(|name| { - let vi_suffix = format!("{}_vi", &name[..]); + let vi_suffix = format!("{}_vi", name); Ident::from_str_and_span(&vi_suffix, span) }) .collect::>(); @@ -1226,7 +1226,7 @@ impl<'a> MethodDef<'a> { // delegated expression that handles the catch-all case, // using `__variants_tuple` to drive logic if necessary. let catch_all_substructure = - EnumNonMatchingCollapsed(self_arg_idents, &variants[..], &vi_idents[..]); + EnumNonMatchingCollapsed(self_arg_idents, &variants, &vi_idents); let first_fieldless = variants.iter().find(|v| v.data.fields().is_empty()); @@ -1261,7 +1261,7 @@ impl<'a> MethodDef<'a> { idents }; for self_arg_name in &self_arg_names[1..] { - let (p, idents) = mk_self_pat(cx, &self_arg_name[..]); + let (p, idents) = mk_self_pat(cx, &self_arg_name); subpats.push(p); self_pats_idents.push(idents); } diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 62a55c0e49e..34cc4396816 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -549,7 +549,7 @@ impl<'a, 'b> Context<'a, 'b> { } else { self.fmtsp }; - let mut err = self.ecx.struct_span_err(sp, &msg[..]); + let mut err = self.ecx.struct_span_err(sp, &msg); err.note(&format!( "did you intend to capture a variable `{}` from \ diff --git a/compiler/rustc_codegen_gcc/src/back/write.rs b/compiler/rustc_codegen_gcc/src/back/write.rs index c3e3847823d..4962d016152 100644 --- a/compiler/rustc_codegen_gcc/src/back/write.rs +++ b/compiler/rustc_codegen_gcc/src/back/write.rs @@ -32,7 +32,7 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext, _diag_han if config.emit_asm { let _timer = cgcx .prof - .generic_activity_with_arg("LLVM_module_codegen_emit_asm", &module.name[..]); + .generic_activity_with_arg("LLVM_module_codegen_emit_asm", &*module.name); let path = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name); context.compile_to_file(OutputKind::Assembler, path.to_str().expect("path to str")); } @@ -41,7 +41,7 @@ pub(crate) unsafe fn codegen(cgcx: &CodegenContext, _diag_han EmitObj::ObjectCode(_) => { let _timer = cgcx .prof - .generic_activity_with_arg("LLVM_module_codegen_emit_obj", &module.name[..]); + .generic_activity_with_arg("LLVM_module_codegen_emit_obj", &*module.name); match &*module.name { "std_example.7rcbfp3g-cgu.15" => { println!("Dumping reproducer {}", module.name); diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index 90d3c0fb2f1..79bd76d96dc 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -477,7 +477,7 @@ pub(crate) fn inline_asm_call( .collect::>(); debug!("Asm Output Type: {:?}", output); - let fty = bx.cx.type_func(&argtys[..], output); + let fty = bx.cx.type_func(&argtys, output); unsafe { // Ask LLVM to verify that the constraints are well-formed. let constraints_ok = llvm::LLVMRustInlineAsmVerify(fty, cons.as_ptr().cast(), cons.len()); diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 97780de9ba4..f6c40f1689e 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -587,7 +587,7 @@ pub(crate) fn run_pass_manager( config: &ModuleConfig, thin: bool, ) -> Result<(), FatalError> { - let _timer = cgcx.prof.extra_verbose_generic_activity("LLVM_lto_optimize", &module.name[..]); + let _timer = cgcx.prof.extra_verbose_generic_activity("LLVM_lto_optimize", &*module.name); // Now we have one massive module inside of llmod. Time to run the // LTO-specific optimization passes that LLVM provides. diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 460a8cc6912..fa4fad30830 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -510,7 +510,7 @@ pub(crate) unsafe fn optimize( module: &ModuleCodegen, config: &ModuleConfig, ) -> Result<(), FatalError> { - let _timer = cgcx.prof.generic_activity_with_arg("LLVM_module_optimize", &module.name[..]); + let _timer = cgcx.prof.generic_activity_with_arg("LLVM_module_optimize", &*module.name); let llmod = module.module_llvm.llmod(); let llcx = &*module.module_llvm.llcx; @@ -663,14 +663,14 @@ pub(crate) unsafe fn optimize( { let _timer = cgcx.prof.extra_verbose_generic_activity( "LLVM_module_optimize_function_passes", - &module.name[..], + &*module.name, ); llvm::LLVMRustRunFunctionPassManager(fpm, llmod); } { let _timer = cgcx.prof.extra_verbose_generic_activity( "LLVM_module_optimize_module_passes", - &module.name[..], + &*module.name, ); llvm::LLVMRunPassManager(mpm, llmod); } @@ -733,7 +733,7 @@ pub(crate) unsafe fn codegen( module: ModuleCodegen, config: &ModuleConfig, ) -> Result { - let _timer = cgcx.prof.generic_activity_with_arg("LLVM_module_codegen", &module.name[..]); + let _timer = cgcx.prof.generic_activity_with_arg("LLVM_module_codegen", &*module.name); { let llmod = module.module_llvm.llmod(); let llcx = &*module.module_llvm.llcx; @@ -782,7 +782,7 @@ pub(crate) unsafe fn codegen( if config.bitcode_needed() { let _timer = cgcx .prof - .generic_activity_with_arg("LLVM_module_codegen_make_bitcode", &module.name[..]); + .generic_activity_with_arg("LLVM_module_codegen_make_bitcode", &*module.name); let thin = ThinBuffer::new(llmod); let data = thin.data(); @@ -795,10 +795,9 @@ pub(crate) unsafe fn codegen( } if config.emit_bc || config.emit_obj == EmitObj::Bitcode { - let _timer = cgcx.prof.generic_activity_with_arg( - "LLVM_module_codegen_emit_bitcode", - &module.name[..], - ); + let _timer = cgcx + .prof + .generic_activity_with_arg("LLVM_module_codegen_emit_bitcode", &*module.name); if let Err(e) = fs::write(&bc_out, data) { let msg = format!("failed to write bytecode to {}: {}", bc_out.display(), e); diag_handler.err(&msg); @@ -806,18 +805,16 @@ pub(crate) unsafe fn codegen( } if config.emit_obj == EmitObj::ObjectCode(BitcodeSection::Full) { - let _timer = cgcx.prof.generic_activity_with_arg( - "LLVM_module_codegen_embed_bitcode", - &module.name[..], - ); + let _timer = cgcx + .prof + .generic_activity_with_arg("LLVM_module_codegen_embed_bitcode", &*module.name); embed_bitcode(cgcx, llcx, llmod, &config.bc_cmdline, data); } } if config.emit_ir { - let _timer = cgcx - .prof - .generic_activity_with_arg("LLVM_module_codegen_emit_ir", &module.name[..]); + let _timer = + cgcx.prof.generic_activity_with_arg("LLVM_module_codegen_emit_ir", &*module.name); let out = cgcx.output_filenames.temp_path(OutputType::LlvmAssembly, module_name); let out_c = path_to_c_string(&out); @@ -866,9 +863,8 @@ pub(crate) unsafe fn codegen( } if config.emit_asm { - let _timer = cgcx - .prof - .generic_activity_with_arg("LLVM_module_codegen_emit_asm", &module.name[..]); + let _timer = + cgcx.prof.generic_activity_with_arg("LLVM_module_codegen_emit_asm", &*module.name); let path = cgcx.output_filenames.temp_path(OutputType::Assembly, module_name); // We can't use the same module for asm and object code output, @@ -898,7 +894,7 @@ pub(crate) unsafe fn codegen( EmitObj::ObjectCode(_) => { let _timer = cgcx .prof - .generic_activity_with_arg("LLVM_module_codegen_emit_obj", &module.name[..]); + .generic_activity_with_arg("LLVM_module_codegen_emit_obj", &*module.name); let dwo_out = cgcx.output_filenames.temp_path_dwo(module_name); let dwo_out = match cgcx.split_debuginfo { diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index 73a8d464431..d0ed9781243 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -120,7 +120,7 @@ impl CodegenCx<'ll, 'tcx> { !null_terminated as Bool, ); let sym = self.generate_local_symbol_name("str"); - let g = self.define_global(&sym[..], self.val_ty(sc)).unwrap_or_else(|| { + let g = self.define_global(&sym, self.val_ty(sc)).unwrap_or_else(|| { bug!("symbol `{}` is already defined", sym); }); llvm::LLVMSetInitializer(g, sc); diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index b154ced42f0..50a68ae49d5 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -225,7 +225,7 @@ impl CodegenCx<'ll, 'tcx> { let gv = match kind { Some(kind) if !self.tcx.sess.fewer_names() => { let name = self.generate_local_symbol_name(kind); - let gv = self.define_global(&name[..], self.val_ty(cv)).unwrap_or_else(|| { + let gv = self.define_global(&name, self.val_ty(cv)).unwrap_or_else(|| { bug!("symbol `{}` is already defined", name); }); llvm::LLVMRustSetLinkage(gv, llvm::Linkage::PrivateLinkage); diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs index 0390caaec33..d2af1b247e8 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs @@ -89,7 +89,7 @@ pub fn finalize<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>) { }); let filenames_size = filenames_buffer.len(); - let filenames_val = cx.const_bytes(&filenames_buffer[..]); + let filenames_val = cx.const_bytes(&filenames_buffer); let filenames_ref = coverageinfo::hash_bytes(filenames_buffer); // Generate the LLVM IR representation of the coverage map and store it in a well-known global @@ -238,7 +238,7 @@ fn save_function_record( ) { // Concatenate the encoded coverage mappings let coverage_mapping_size = coverage_mapping_buffer.len(); - let coverage_mapping_val = cx.const_bytes(&coverage_mapping_buffer[..]); + let coverage_mapping_val = cx.const_bytes(&coverage_mapping_buffer); let func_name_hash = coverageinfo::hash_str(&mangled_function_name); let func_name_hash_val = cx.const_u64(func_name_hash); diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index 10c7bb2eaea..cc39332d198 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -456,7 +456,7 @@ fn vec_slice_metadata( let metadata = composite_type_metadata( cx, slice_ptr_type, - &slice_type_name[..], + &slice_type_name, unique_type_id, member_descriptions, NO_SCOPE_METADATA, @@ -579,7 +579,7 @@ fn trait_pointer_metadata( composite_type_metadata( cx, trait_object_type.unwrap_or(trait_type), - &trait_type_name[..], + &trait_type_name, unique_type_id, member_descriptions, containing_scope, @@ -2398,7 +2398,7 @@ fn set_members_of_composite_type( let type_params = compute_type_parameters(cx, composite_type); unsafe { - let type_array = create_DIArray(DIB(cx), &member_metadata[..]); + let type_array = create_DIArray(DIB(cx), &member_metadata); llvm::LLVMRustDICompositeTypeReplaceArrays( DIB(cx), composite_type_metadata, @@ -2437,7 +2437,7 @@ fn compute_type_parameters(cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>) -> &'ll DIAr }) .collect(); - return create_DIArray(DIB(cx), &template_params[..]); + return create_DIArray(DIB(cx), &template_params); } } return create_DIArray(DIB(cx), &[]); diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs index 2a6bf7d9b1a..b801a7c1314 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs @@ -474,7 +474,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> { vec![] }; - create_DIArray(DIB(cx), &template_params[..]) + create_DIArray(DIB(cx), &template_params) } fn get_parameter_names(cx: &CodegenCx<'_, '_>, generics: &ty::Generics) -> Vec { diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 2d6904af207..d6af6104155 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -677,11 +677,11 @@ impl WorkItem { fn start_profiling<'a>(&self, cgcx: &'a CodegenContext) -> TimingGuard<'a> { match *self { WorkItem::Optimize(ref m) => { - cgcx.prof.generic_activity_with_arg("codegen_module_optimize", &m.name[..]) + cgcx.prof.generic_activity_with_arg("codegen_module_optimize", &*m.name) } WorkItem::CopyPostLtoArtifacts(ref m) => cgcx .prof - .generic_activity_with_arg("codegen_copy_artifacts_from_incr_cache", &m.name[..]), + .generic_activity_with_arg("codegen_copy_artifacts_from_incr_cache", &*m.name), WorkItem::LTO(ref m) => { cgcx.prof.generic_activity_with_arg("codegen_module_perform_lto", m.name()) } diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs index 1fa60612d26..2df58ecc9f6 100644 --- a/compiler/rustc_codegen_ssa/src/common.rs +++ b/compiler/rustc_codegen_ssa/src/common.rs @@ -122,8 +122,8 @@ pub fn langcall(tcx: TyCtxt<'_>, span: Option, msg: &str, li: LangItem) -> tcx.lang_items().require(li).unwrap_or_else(|s| { let msg = format!("{} {}", msg, s); match span { - Some(span) => tcx.sess.span_fatal(span, &msg[..]), - None => tcx.sess.fatal(&msg[..]), + Some(span) => tcx.sess.span_fatal(span, &msg), + None => tcx.sess.fatal(&msg), } }) } diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index 00208574c55..df177fd9679 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -103,7 +103,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.eval_fn_call( fn_val, abi, - &args[..], + &args, ret, match (cleanup, caller_can_unwind) { (Some(cleanup), true) => StackPopUnwind::Cleanup(*cleanup), diff --git a/compiler/rustc_data_structures/src/fingerprint.rs b/compiler/rustc_data_structures/src/fingerprint.rs index c0c0e7be3ca..c9af35da4bc 100644 --- a/compiler/rustc_data_structures/src/fingerprint.rs +++ b/compiler/rustc_data_structures/src/fingerprint.rs @@ -142,7 +142,7 @@ impl_stable_hash_via_hash!(Fingerprint); impl Encodable for Fingerprint { #[inline] fn encode(&self, s: &mut E) -> Result<(), E::Error> { - s.emit_raw_bytes(&self.to_le_bytes()[..])?; + s.emit_raw_bytes(&self.to_le_bytes())?; Ok(()) } } @@ -151,7 +151,7 @@ impl Decodable for Fingerprint { #[inline] fn decode(d: &mut D) -> Result { let mut bytes = [0u8; 16]; - d.read_raw_bytes_into(&mut bytes[..])?; + d.read_raw_bytes_into(&mut bytes)?; Ok(Fingerprint::from_le_bytes(bytes)) } } diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs index c21939209fc..fd6ff086b08 100644 --- a/compiler/rustc_data_structures/src/profiling.rs +++ b/compiler/rustc_data_structures/src/profiling.rs @@ -649,7 +649,7 @@ impl Drop for VerboseTimingGuard<'_> { fn drop(&mut self) { if let Some((start_time, start_rss, ref message)) = self.start_and_message { let end_rss = get_resident_set_size(); - print_time_passes_entry(&message[..], start_time.elapsed(), start_rss, end_rss); + print_time_passes_entry(&message, start_time.elapsed(), start_rss, end_rss); } } } diff --git a/compiler/rustc_data_structures/src/small_c_str.rs b/compiler/rustc_data_structures/src/small_c_str.rs index 4a089398ce6..33e72914e19 100644 --- a/compiler/rustc_data_structures/src/small_c_str.rs +++ b/compiler/rustc_data_structures/src/small_c_str.rs @@ -46,7 +46,7 @@ impl SmallCStr { #[inline] pub fn as_c_str(&self) -> &ffi::CStr { - unsafe { ffi::CStr::from_bytes_with_nul_unchecked(&self.data[..]) } + unsafe { ffi::CStr::from_bytes_with_nul_unchecked(&self.data) } } #[inline] diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 537a10e98e5..8065911afb9 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -253,7 +253,7 @@ fn generic_extension<'cx>( for (i, lhs) in lhses.iter().enumerate() { // try each arm's matchers let lhs_tt = match *lhs { - mbe::TokenTree::Delimited(_, ref delim) => &delim.tts[..], + mbe::TokenTree::Delimited(_, ref delim) => &delim.tts, _ => cx.span_bug(sp, "malformed macro lhs"), }; @@ -353,7 +353,7 @@ fn generic_extension<'cx>( for lhs in lhses { // try each arm's matchers let lhs_tt = match *lhs { - mbe::TokenTree::Delimited(_, ref delim) => &delim.tts[..], + mbe::TokenTree::Delimited(_, ref delim) => &delim.tts, _ => continue, }; if let Success(_) = @@ -677,11 +677,11 @@ impl FirstSets { first.replace_with(tt.clone()); } TokenTree::Delimited(span, ref delimited) => { - build_recur(sets, &delimited.tts[..]); + build_recur(sets, &delimited.tts); first.replace_with(delimited.open_tt(span)); } TokenTree::Sequence(sp, ref seq_rep) => { - let subfirst = build_recur(sets, &seq_rep.tts[..]); + let subfirst = build_recur(sets, &seq_rep.tts); match sets.first.entry(sp.entire()) { Entry::Vacant(vac) => { @@ -748,7 +748,7 @@ impl FirstSets { let subfirst = match self.first.get(&sp.entire()) { Some(&Some(ref subfirst)) => subfirst, Some(&None) => { - subfirst_owned = self.first(&seq_rep.tts[..]); + subfirst_owned = self.first(&seq_rep.tts); &subfirst_owned } None => { diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs index 88e1623012b..01a7f726617 100644 --- a/compiler/rustc_expand/src/mbe/transcribe.rs +++ b/compiler/rustc_expand/src/mbe/transcribe.rs @@ -175,12 +175,12 @@ pub(super) fn transcribe<'a>( )); } - LockstepIterSize::Contradiction(ref msg) => { + LockstepIterSize::Contradiction(msg) => { // FIXME: this really ought to be caught at macro definition time... It // happens when two meta-variables are used in the same repetition in a // sequence, but they come from different sequence matchers and repeat // different amounts. - return Err(cx.struct_span_err(seq.span(), &msg[..])); + return Err(cx.struct_span_err(seq.span(), &msg)); } LockstepIterSize::Constraint(len, _) => { diff --git a/compiler/rustc_graphviz/src/lib.rs b/compiler/rustc_graphviz/src/lib.rs index 27390fd2e4d..edb8bd503e1 100644 --- a/compiler/rustc_graphviz/src/lib.rs +++ b/compiler/rustc_graphviz/src/lib.rs @@ -659,7 +659,7 @@ where } writeln!(text, ";").unwrap(); - w.write_all(&text[..])?; + w.write_all(&text)?; text.clear(); } @@ -684,7 +684,7 @@ where } writeln!(text, ";").unwrap(); - w.write_all(&text[..])?; + w.write_all(&text)?; text.clear(); } diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 4240a4045a1..50a511510ee 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -316,7 +316,7 @@ impl<'a> State<'a> { } hir::TyKind::Tup(ref elts) => { self.popen(); - self.commasep(Inconsistent, &elts[..], |s, ty| s.print_type(&ty)); + self.commasep(Inconsistent, &elts, |s, ty| s.print_type(&ty)); if elts.len() == 1 { self.word(","); } @@ -1862,7 +1862,7 @@ impl<'a> State<'a> { self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(&p)); } } else { - self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(&p)); + self.commasep(Inconsistent, &elts, |s, p| s.print_pat(&p)); } self.pclose(); } @@ -1875,7 +1875,7 @@ impl<'a> State<'a> { self.word_space("{"); self.commasep_cmnt( Consistent, - &fields[..], + &fields, |s, f| { s.cbox(INDENT_UNIT); if !f.is_shorthand { @@ -1897,7 +1897,7 @@ impl<'a> State<'a> { self.word("}"); } PatKind::Or(ref pats) => { - self.strsep("|", true, Inconsistent, &pats[..], |s, p| s.print_pat(&p)); + self.strsep("|", true, Inconsistent, &pats, |s, p| s.print_pat(&p)); } PatKind::Tuple(ref elts, ddpos) => { self.popen(); @@ -1958,7 +1958,7 @@ impl<'a> State<'a> { } PatKind::Slice(ref before, ref slice, ref after) => { self.word("["); - self.commasep(Inconsistent, &before[..], |s, p| s.print_pat(&p)); + self.commasep(Inconsistent, &before, |s, p| s.print_pat(&p)); if let Some(ref p) = *slice { if !before.is_empty() { self.word_space(","); @@ -1973,7 +1973,7 @@ impl<'a> State<'a> { self.word_space(","); } } - self.commasep(Inconsistent, &after[..], |s, p| s.print_pat(&p)); + self.commasep(Inconsistent, &after, |s, p| s.print_pat(&p)); self.word("]"); } } diff --git a/compiler/rustc_incremental/src/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs index 9c6e2aeb50a..b36bf89c9d3 100644 --- a/compiler/rustc_incremental/src/persist/load.rs +++ b/compiler/rustc_incremental/src/persist/load.rs @@ -151,7 +151,7 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture { compilation session directory: {}", e ); - sess.fatal(&msg[..]) + sess.fatal(&msg) }); for swp in work_products { diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs index 4a9b27e89b1..30506445ebb 100644 --- a/compiler/rustc_lint/src/non_fmt_panic.rs +++ b/compiler/rustc_lint/src/non_fmt_panic.rs @@ -207,7 +207,7 @@ fn check_panic_str<'tcx>( arg: &'tcx hir::Expr<'tcx>, fmt: &str, ) { - if !fmt.contains(&['{', '}'][..]) { + if !fmt.contains(&['{', '}']) { // No brace, no problem. return; } diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index bd5cda15b91..9adf9406f09 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -132,7 +132,7 @@ impl ItemLikeVisitor<'tcx> for Collector<'tcx> { if let Some(modifiers) = item.value_str() { let span = item.name_value_literal_span().unwrap(); for modifier in modifiers.as_str().split(',') { - let (modifier, value) = match modifier.strip_prefix(&['+', '-'][..]) { + let (modifier, value) = match modifier.strip_prefix(&['+', '-']) { Some(m) => (m, modifier.starts_with('+')), None => { sess.span_err( diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 514a49d7e2c..94e7376ddb2 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -2119,7 +2119,7 @@ impl EncodedMetadata { #[inline] pub fn raw_data(&self) -> &[u8] { - &self.raw_data[..] + &self.raw_data } } diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs index 06b42320049..f48e27e02cd 100644 --- a/compiler/rustc_middle/src/mir/mono.rs +++ b/compiler/rustc_middle/src/mir/mono.rs @@ -530,6 +530,6 @@ impl CodegenUnitNameBuilder<'tcx> { write!(cgu_name, ".{}", special_suffix).unwrap(); } - Symbol::intern(&cgu_name[..]) + Symbol::intern(&cgu_name) } } diff --git a/compiler/rustc_middle/src/mir/terminator.rs b/compiler/rustc_middle/src/mir/terminator.rs index d52b6a8bc75..51e4afaf220 100644 --- a/compiler/rustc_middle/src/mir/terminator.rs +++ b/compiler/rustc_middle/src/mir/terminator.rs @@ -342,7 +342,7 @@ impl<'tcx> TerminatorKind<'tcx> { | InlineAsm { destination: Some(ref t), cleanup: Some(ref u), .. } => { Some(t).into_iter().chain(slice::from_ref(u)) } - SwitchInt { ref targets, .. } => None.into_iter().chain(&targets.targets[..]), + SwitchInt { ref targets, .. } => None.into_iter().chain(&targets.targets), FalseEdge { ref real_target, ref imaginary_target } => { Some(real_target).into_iter().chain(slice::from_ref(imaginary_target)) } @@ -380,7 +380,7 @@ impl<'tcx> TerminatorKind<'tcx> { | InlineAsm { destination: Some(ref mut t), cleanup: Some(ref mut u), .. } => { Some(t).into_iter().chain(slice::from_mut(u)) } - SwitchInt { ref mut targets, .. } => None.into_iter().chain(&mut targets.targets[..]), + SwitchInt { ref mut targets, .. } => None.into_iter().chain(&mut targets.targets), FalseEdge { ref mut real_target, ref mut imaginary_target } => { Some(real_target).into_iter().chain(slice::from_mut(imaginary_target)) } diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 49a64cb246a..33ddc4f954a 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -587,18 +587,18 @@ impl<'tcx, N> ImplSource<'tcx, N> { pub fn borrow_nested_obligations(&self) -> &[N] { match &self { ImplSource::UserDefined(i) => &i.nested[..], - ImplSource::Param(n, _) => &n[..], - ImplSource::Builtin(i) => &i.nested[..], - ImplSource::AutoImpl(d) => &d.nested[..], - ImplSource::Closure(c) => &c.nested[..], - ImplSource::Generator(c) => &c.nested[..], - ImplSource::Object(d) => &d.nested[..], - ImplSource::FnPointer(d) => &d.nested[..], + ImplSource::Param(n, _) => &n, + ImplSource::Builtin(i) => &i.nested, + ImplSource::AutoImpl(d) => &d.nested, + ImplSource::Closure(c) => &c.nested, + ImplSource::Generator(c) => &c.nested, + ImplSource::Object(d) => &d.nested, + ImplSource::FnPointer(d) => &d.nested, ImplSource::DiscriminantKind(ImplSourceDiscriminantKindData) | ImplSource::Pointee(ImplSourcePointeeData) | ImplSource::ConstDrop(ImplSourceConstDropData) => &[], - ImplSource::TraitAlias(d) => &d.nested[..], - ImplSource::TraitUpcasting(d) => &d.nested[..], + ImplSource::TraitAlias(d) => &d.nested, + ImplSource::TraitUpcasting(d) => &d.nested, } } diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 8e2e6eaee58..25beed1ecf9 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -306,7 +306,7 @@ impl<'a> Parser<'a> { } } - let expect = tokens_to_string(&expected[..]); + let expect = tokens_to_string(&expected); let actual = super::token_descr(&self.token); let (msg_exp, (label_sp, label_exp)) = if expected.len() > 1 { let short_expect = if expected.len() > 6 { @@ -909,7 +909,7 @@ impl<'a> Parser<'a> { // So far we have parsed `foo Parser<'a> { // Consume the fn call arguments. let modifiers = [(token::OpenDelim(token::Paren), 1), (token::CloseDelim(token::Paren), -1)]; - self.consume_tts(1, &modifiers[..]); + self.consume_tts(1, &modifiers); if self.token.kind == token::Eof { // Not entirely sure that what we consumed were fn arguments, rollback. diff --git a/compiler/rustc_query_impl/src/on_disk_cache.rs b/compiler/rustc_query_impl/src/on_disk_cache.rs index 552906aac31..c42decdccff 100644 --- a/compiler/rustc_query_impl/src/on_disk_cache.rs +++ b/compiler/rustc_query_impl/src/on_disk_cache.rs @@ -158,7 +158,7 @@ impl<'sess> rustc_middle::ty::OnDiskCache<'sess> for OnDiskCache<'sess> { // Wrap in a scope so we can borrow `data`. let footer: Footer = { - let mut decoder = opaque::Decoder::new(&data[..], start_pos); + let mut decoder = opaque::Decoder::new(&data, start_pos); // Decode the *position* of the footer, which can be found in the // last 8 bytes of the file. diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 87e8e576117..5df8a4103b7 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1735,7 +1735,7 @@ fn parse_native_lib_modifiers( ) -> (NativeLibKind, Option) { let mut verbatim = None; for modifier in modifiers.split(',') { - let (modifier, value) = match modifier.strip_prefix(&['+', '-'][..]) { + let (modifier, value) = match modifier.strip_prefix(&['+', '-']) { Some(m) => (m, modifier.starts_with('+')), None => early_error( error_format, @@ -2027,7 +2027,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { let unparsed_crate_types = matches.opt_strs("crate-type"); let crate_types = parse_crate_types_from_list(unparsed_crate_types) - .unwrap_or_else(|e| early_error(error_format, &e[..])); + .unwrap_or_else(|e| early_error(error_format, &e)); let mut debugging_opts = DebuggingOptions::build(matches, error_format); let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format); @@ -2151,7 +2151,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { let mut search_paths = vec![]; for s in &matches.opt_strs("L") { - search_paths.push(SearchPath::from_cli_opt(&s[..], error_format)); + search_paths.push(SearchPath::from_cli_opt(&s, error_format)); } let libs = parse_libs(matches, error_format); diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index ea3d3363b80..2934368dfeb 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -1383,7 +1383,7 @@ impl Encodable for SourceFile { // Encode the first element. lines[0].encode(s)?; - let diff_iter = lines[..].array_windows().map(|&[fst, snd]| snd - fst); + let diff_iter = lines.array_windows().map(|&[fst, snd]| snd - fst); match bytes_per_diff { 1 => { @@ -1506,7 +1506,7 @@ impl SourceFile { assert!(end_pos <= u32::MAX as usize); let (lines, multibyte_chars, non_narrow_chars) = - analyze_source_file::analyze_source_file(&src[..], start_pos); + analyze_source_file::analyze_source_file(&src, start_pos); SourceFile { name, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs index 6128c119b6b..d9a5aea4d95 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs @@ -231,7 +231,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { if let Ok(Some(command)) = OnUnimplementedDirective::of_item(self.tcx, trait_ref.def_id, def_id) { - command.evaluate(self.tcx, trait_ref, &flags[..]) + command.evaluate(self.tcx, trait_ref, &flags) } else { OnUnimplementedNote::default() } 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 2e87d6fdd3d..d0b61b24308 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -804,7 +804,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } else if let ObligationCauseCode::BindingObligation(_, _) | ObligationCauseCode::ItemObligation(_) = &*code { - try_borrowing(*poly_trait_ref, &never_suggest_borrow[..]) + try_borrowing(*poly_trait_ref, &never_suggest_borrow) } else { false } @@ -1132,7 +1132,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { "; let has_dyn = snippet.split_whitespace().next().map_or(false, |s| s == "dyn"); - let trait_obj = if has_dyn { &snippet[4..] } else { &snippet[..] }; + let trait_obj = if has_dyn { &snippet[4..] } else { &snippet }; if only_never_return { // No return paths, probably using `panic!()` or similar. // Suggest `-> T`, `-> impl Trait`, and if `Trait` is object safe, `-> Box`. diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index 08261fedd4a..427268d6d63 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -1350,7 +1350,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { tcx, span, item.trait_ref().def_id(), - &object_safety_violations[..], + &object_safety_violations, ) .emit(); return tcx.ty_error(); diff --git a/compiler/rustc_typeck/src/check/callee.rs b/compiler/rustc_typeck/src/check/callee.rs index 635ed938193..e67ee1cab3d 100644 --- a/compiler/rustc_typeck/src/check/callee.rs +++ b/compiler/rustc_typeck/src/check/callee.rs @@ -496,7 +496,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { call_expr.span, call_expr, fn_sig.inputs(), - &expected_arg_tys[..], + &expected_arg_tys, arg_exprs, fn_sig.c_variadic, TupleArgumentsFlag::DontTupleArguments, diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index a02a7d7cbfe..e82ff9cf2dd 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -1436,7 +1436,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { >::create_substs_for_generic_args( tcx, def_id, - &[][..], + &[], has_self, self_ty, &arg_count, diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 74d7f0a80b6..4cb597cb6d6 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -54,13 +54,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let err_inputs = match tuple_arguments { DontTupleArguments => err_inputs, - TupleArguments => vec![self.tcx.intern_tup(&err_inputs[..])], + TupleArguments => vec![self.tcx.intern_tup(&err_inputs)], }; self.check_argument_types( sp, expr, - &err_inputs[..], + &err_inputs, &[], args_no_rcvr, false, @@ -324,7 +324,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.point_at_type_arg_instead_of_call_if_possible(errors, expr); self.point_at_arg_instead_of_call_if_possible( errors, - &final_arg_types[..], + &final_arg_types, expr, sp, &args, diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index 9fd7e8c4daa..9ccf354db73 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -1372,7 +1372,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { if applicable_candidates.len() > 1 { if let Some(pick) = - self.collapse_candidates_to_trait_pick(self_ty, &applicable_candidates[..]) + self.collapse_candidates_to_trait_pick(self_ty, &applicable_candidates) { return Some(Ok(pick)); } diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index ad38885dbd8..e9ec0674cb7 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -1344,7 +1344,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if candidates.len() > limit { msg.push_str(&format!("\nand {} others", candidates.len() - limit)); } - err.note(&msg[..]); + err.note(&msg); } } diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 67a3053c607..fda96e49eb9 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -2998,9 +2998,9 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs { ) .emit(); InlineAttr::None - } else if list_contains_name(&items[..], sym::always) { + } else if list_contains_name(&items, sym::always) { InlineAttr::Always - } else if list_contains_name(&items[..], sym::never) { + } else if list_contains_name(&items, sym::never) { InlineAttr::Never } else { struct_span_err!( @@ -3034,9 +3034,9 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs { if items.len() != 1 { err(attr.span, "expected one argument"); OptimizeAttr::None - } else if list_contains_name(&items[..], sym::size) { + } else if list_contains_name(&items, sym::size) { OptimizeAttr::Size - } else if list_contains_name(&items[..], sym::speed) { + } else if list_contains_name(&items, sym::speed) { OptimizeAttr::Speed } else { err(items[0].span(), "invalid argument"); From 99bd24e9a3a812fcbaa82c3465f28dbe7a60667c Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 5 Dec 2021 15:55:41 -0800 Subject: [PATCH 13/13] Fix span calculation on secondary_label as well --- compiler/rustc_builtin_macros/src/format.rs | 5 +++-- src/test/ui/fmt/issue-91556.rs | 8 ++++++++ src/test/ui/fmt/issue-91556.stderr | 11 +++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/fmt/issue-91556.rs create mode 100644 src/test/ui/fmt/issue-91556.stderr diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index 62a55c0e49e..8c343b6ea08 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -995,8 +995,9 @@ pub fn expand_preparsed_format_args( e.note(¬e); } if let Some((label, span)) = err.secondary_label { - let sp = fmt_span.from_inner(span); - e.span_label(sp, label); + if efmt_kind_is_lit { + e.span_label(fmt_span.from_inner(span), label); + } } e.emit(); return DummyResult::raw_expr(sp, true); diff --git a/src/test/ui/fmt/issue-91556.rs b/src/test/ui/fmt/issue-91556.rs new file mode 100644 index 00000000000..e782e6f9076 --- /dev/null +++ b/src/test/ui/fmt/issue-91556.rs @@ -0,0 +1,8 @@ +fn main() { + let _ = format!(concat!("{0}๐–ณ๐–พ๐—Œ๐—{"), i); + //~^ ERROR: invalid format string: expected `'}'` but string was terminated + //~| NOTE: if you intended to print `{`, you can escape it using `{{` + //~| NOTE: in this expansion of concat! + //~| NOTE: in this expansion of concat! + //~| NOTE: expected `'}'` in format string +} diff --git a/src/test/ui/fmt/issue-91556.stderr b/src/test/ui/fmt/issue-91556.stderr new file mode 100644 index 00000000000..dbd5aef458b --- /dev/null +++ b/src/test/ui/fmt/issue-91556.stderr @@ -0,0 +1,11 @@ +error: invalid format string: expected `'}'` but string was terminated + --> $DIR/issue-91556.rs:2:19 + | +LL | let _ = format!(concat!("{0}๐–ณ๐–พ๐—Œ๐—{"), i); + | ^^^^^^^^^^^^^^^^^^^ expected `'}'` in format string + | + = note: if you intended to print `{`, you can escape it using `{{` + = note: this error originates in the macro `concat` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error +